obsidian-workspace-skill
Development conventions and architecture guide for the Obsidian plugin monorepo.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Development conventions and architecture guide for the Obsidian plugin monorepo.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
Guide for submitting an Obsidian plugin to the community marketplace for the first time. Use this skill when the user asks to "publish", "submit", "release to community", "add to obsidian community plugins", "PR to obsidian-releases", or wants to know what to do before their first community release. Also trigger when the user asks for a publish checklist, wants to verify plugin submission readiness, needs to fix bot validation errors ("Validation failed" label), or wants to re-trigger the bot after fixing issues. This is distinct from ongoing `pnpm release:*` version bumps — it covers the one-time community-plugins.json PR flow and all post-submission bot feedback loops.
Propagate boiler-template changes to downstream plugins. Use this skill when the user asks to "sync", "propagate", "push template changes", check drift/sync status, or after modifying files under tooling/shared/ or tooling/sync/.
Debug, profile, and verify Obsidian community plugins in a live vault with the Obsidian CLI. Use when a plugin throws runtime errors, needs a DB or plugin-state reset, must be reinstalled into a test vault, requires DevTools/CDP profiling, or needs screenshot and DOM verification before shipping.
استنادا إلى تصنيف SOC المهني
| name | obsidian-workspace-skill |
| description | Development conventions and architecture guide for the Obsidian plugin monorepo. |
A monorepo of Obsidian community plugins sharing a common architecture enforced by a boiler-template sync engine. All plugins follow a strict 4-layer architecture with ESLint-enforced layer boundaries.
Codebase: 7 plugin submodules + 1 boiler-template, TypeScript under src/.
| Component | Technology |
|---|---|
| Language | TypeScript (strict mode, ES modules) |
| Runtime | Node.js via Obsidian's Electron |
| UI Framework | Obsidian API (Views, Modals, Settings) |
| Build | esbuild (esbuild.config.mjs) |
| Package Manager | pnpm (workspace) |
| Linter | ESLint flat config (eslint.config.mts) |
| Commit Lint | commitlint + Husky hooks |
| Release | Automated via scripts/release.mjs |
| CI/CD | GitHub Actions (generated by boiler-template) |
| Template Sync | Custom sync engine (tooling/sync/index.mjs) |
src/)| Directory | Purpose | obsidian import? |
|---|---|---|
main.ts | Composition root — wires everything | Yes |
domain/ | Business logic, pure functions | No |
ui/ | Views, modals, settings, commands, adapters with I/O | Yes |
types/ | Pure type definitions | No |
utils/ | Pure functions, zero state | No |
shared/ | Boiler-template synced modules | Yes |
utils/ ──┐
types/ ──┼── domain/ ── ui/ ── main.ts
shared/ ─┘ │
└── shared/
| Submodule | Purpose | Default Branch |
|---|---|---|
obsidian-eagle-plugin | Image upload to Eagle app | main |
open-connections | Semantic note connections via embeddings | main |
Metadata-Auto-Classifier | AI-powered metadata classification | master |
obsidian-boiler-template | Source-of-truth seed template | master |
obsidian-bible-search | Bible verse search (private) | main |
obsidian-qmd | QMD semantic search integration | main |
youtube-note-playlist | YouTube music player via yt-dlp | main |
| File | Role |
|---|---|
src/main.ts | Plugin entry point, onload() / onunload() |
src/ui/settings*.ts | Plugin settings tab |
src/shared/plugin-logger.ts | Structured logger (synced) |
src/shared/plugin-notices.ts | Catalog-driven notice system (synced) |
src/shared/settings-migration.ts | Settings version migration (synced) |
boiler.config.mjs | Per-plugin sync overrides |
eslint.config.mts | ESLint config (synced from boiler-template) |
| File | Role |
|---|---|
tooling/sync/index.mjs | Sync engine core |
tooling/sync/targets.json | Managed plugin list |
scripts/release.mjs | Release pipeline (CI -> version bump -> tag) |
scripts/sync-to-plugins.mjs | CLI for sync operations |
tooling/shared/ | Shared source modules, scripts, infra |
Every plugin extends Plugin and uses onload() as the composition root:
// src/main.ts
import { Plugin } from 'obsidian';
export default class MyPlugin extends Plugin {
async onload() {
// Register commands, views, settings, event handlers
this.addCommand({ ... });
this.registerView(VIEW_TYPE, (leaf) => new MyView(leaf));
this.addSettingTab(new MySettingTab(this.app, this));
this.registerEvent(this.app.vault.on('modify', handler));
}
onunload() { /* cleanup */ }
}
ESLint no-restricted-imports prevents domain/, types/, and utils/ from importing obsidian. Verified with:
rg "import.*from 'obsidian'" */src/domain/ # should return zero
Define shim interfaces in types/ instead of importing from obsidian:
// types/index.ts
export interface FileRef { path: string; }
export interface NoteMetadata { frontmatter?: Record<string, unknown>; }
main.ts passes real Obsidian objects which satisfy these via structural typing.
Modules in src/shared/ are synced from boiler-template. Never edit directly in downstream plugins — change in boiler-template, then propagate.
| Element | Convention | Example |
|---|---|---|
| Files | kebab-case | qmd-process-adapter.ts, query-builder.ts |
| Classes | PascalCase | QmdProcessAdapter, EmbedStore |
| Types/Interfaces | PascalCase | FileRef, EmbedState, PluginSettings |
| Constants | SCREAMING_SNAKE_CASE | CACHE_MAX_SIZE, DEFAULT_DELAY_MS |
| Functions | camelCase | parseCollectionList, sanitizeForVec |
| Directories | kebab-case | domain/, ui/, shared/ |
| Skill | Trigger | Purpose |
|---|---|---|
obsidian-propagate | "sync", "propagate", "push template changes" | Sync boiler-template to downstream plugins |
obsidian-runtime-debug | Runtime errors, plugin state reset, profiling | Debug plugins in live vault with obsidian-cli |
frontend-design | Build web components, UI design | Production-grade frontend interfaces |
| Agent | Role | Owns |
|---|---|---|
obsidian-developer | Implementation — domain logic, infrastructure | main.ts, domain/, types/, utils/, shared/, test/ |
obsidian-ui | UX design + visual implementation | ui/settings*, ui/connections/, ui/views/, styles.css |
obsidian-qa | Runtime verification + static code review | All files (read), fixes where needed |
utils.ts, helpers.ts, service.ts are bannedpnpm run ci # build + lint + test (must pass)
pnpm release:patch|minor|major # CI -> version bump -> auto-push tag
# GitHub Actions handles the rest
git tag, git push --tags, gh release, npm publish are DENIED by settings.json.
| Setting | Location |
|---|---|
| Plugin settings | <vault>/.obsidian/plugins/<id>/data.json |
| Claude Code permissions | .claude/settings.json |
| Agent definitions | .claude/agents/*.md |
| Skill definitions | .claude/skills/*/SKILL.md |
| ESLint config | eslint.config.mts (synced) |
| Per-plugin sync | boiler.config.mjs |
| Sync targets | obsidian-boiler-template/tooling/sync/targets.json |
Detailed guides in docs/:
| Guide | Purpose |
|---|---|
| Architecture | Layer structure, dependency rules, data flow |
| Exploration Guide | Study paths, grep patterns, feature-to-file mapping |
| Rules | Mandatory code rules with enforcement grep commands |
| Patterns | 8 proven patterns with code examples |
| Gotchas | 7 known pitfalls with fixes |
| Obsidian API | API quirks and workarounds |
| Collaboration | Agent roles, handoff protocol, Definition of Done |
obsidian, it belongs in ui/.src/shared/ in downstream plugins — change in boiler-template, then propagate.node scripts/sync-to-plugins.mjs --dry-run.pnpm run ci before declaring work complete.docs/ as project conventions evolve.