obsidian-workspace/skills/pm/SKILL.md
Project management via Obsidian vault — tasks, documents, ADRs, and dashboards scoped to a `.obsidian.yaml`-bound project. Owns folder layout and property schema; delegates all vault I/O to the Obsidian CLI.
npx skillsauth add musingfox/cc-plugins pmInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill owns: folder layout, template names, property schema, ADR numbering, dashboard generation strategy, and the direct-read rule. For CLI syntax, consult the preloaded obsidian:obsidian-cli skill in the obsidian-operator sub-agent; fall back to obsidian <subcommand> --help only if the skill doesn't cover it. For Bases (.base) syntax used by dashboards, read the bundled templates/dashboard-cross.base / dashboard-project.base directly — do not guess.
.obsidian.yaml)vault: <VAULT_NAME>
pm:
project: <PROJECT_NAME>
Missing config or pm.project → tell the user to run /obw:init and stop.
pm/
├── {project}/
│ ├── tasks/ # active tasks
│ ├── archive/ # completed tasks
│ └── docs/ # docs + ADRs
└── dashboard.base # cross-project dashboard (optional)
Folders are created on demand — obsidian create path="pm/{project}/tasks/foo.md" auto-creates any missing parent folders. No mkdir needed.
Fixed: task, doc, adr. Installed into the vault's Obsidian Templates folder by /obw:init. Use via CLI create template=<name>.
If obsidian vault=<v> templates doesn't list one of these, /obw:init hasn't run (or the user removed them). Tell the user to re-run init rather than inlining template content here.
All vault I/O goes through the obsidian CLI — see preloaded obsidian:obsidian-cli skill. Use one call per known-name read — never chain search → read. The pm-specific bits:
create path="pm/{project}/tasks/{name}.md" template=task, then property:set for project / priority / due / tags.create path="pm/{project}/docs/{name}.md" template=doc, then property:set name=project.create path="pm/{project}/docs/adr-{NNNN}-{title}.md" template=adr, then property:set for project / status. See ADR numbering below.search query="[type:task] [project:{project}] [status:<s>]" format=json.status=done and completed, then move file="{name}" to="pm/{project}/archive" (target folder is auto-created if missing).move if the build lacks delete.Before creating an ADR, search existing ADRs in the project and take max(number)+1, zero-padded to 4 digits:
obsidian vault={vault} search query="[type:adr] [project:{project}]" format=json
Task: type: task, status (todo/in-progress/blocked/done), priority (high/medium/low), project, due (date), tags (list), created, completed.
Doc: type: doc, project, created, updated.
ADR: type: adr, project, status (proposed/accepted/deprecated/superseded), created, deciders.
Property names are lowercase. Do not invent fields — dashboards depend on this schema.
Dashboards are Obsidian Bases (.base files — core in 1.9+). For Bases schema / filter / formula syntax, defer to the obsidian:obsidian-bases skill.
Generated from plugin templates via shell (template contents never enter context):
pm/dashboard.base:
obsidian vault={vault} create path="pm/dashboard.base" \
content="$(cat "${CLAUDE_PLUGIN_ROOT}/templates/dashboard-cross.base")" overwrite
pm/{project}/dashboard.base:
obsidian vault={vault} create path="pm/{project}/dashboard.base" \
content="$(sed "s/__PROJECT__/{project}/g" "${CLAUDE_PLUGIN_ROOT}/templates/dashboard-project.base")" overwrite
Conversation-mode status (user asks in chat, not Obsidian): run the equivalent search and format a summary table in the reply. Don't write a .base file unless asked to.
.obsidian.yaml before any operation.file= uses wikilink resolution — just the base name, no path/extension.search to locate a note whose name is known — go straight to read.$VAULT_PATH/.... Only exception: reading .obsidian/templates.json / obsidian.json during /obw:init. Dashboard creation uses the CLI via shell-piped content; folder creation is implicit in create / move.data-ai
Unified entry point for Obsidian daily-note captures and long-form notes. Triggers on "記一下 / log / 紀錄 / capture this / 寫到 journal" (→ cap mode) and "建立筆記 / new note / 寫一份筆記 / create a note on" (→ note mode). Also via `/obw:cap` and `/obw:note`. Requires `.obsidian.yaml`.
tools
Use the `gog` CLI to operate Google Workspace — Gmail (read/search/send/labels/drafts), Calendar (events/RSVP/freebusy/focus-time/out-of-office), and Drive (list/search/upload/ download/share/move). Triggers on any Gmail, inbox, email, calendar, agenda, meeting, schedule, RSVP, Drive, Google Doc/Sheet/Slides, file share, or upload/download request.
documentation
Interactively create .obsidian.yaml for a project and install starter templates (task / doc / adr) into the vault's Templates folder. Skips templates that already exist; never overwrites.
tools
Manage project hook-guard installation — set up, diagnose, or update Claude Code hooks, git pre-commit, and commit-msg scripts with security checks, code-quality gates, and CLAUDECODE skip logic. Triggers on "set up hooks", "configure pre-commit", "add linting hooks", "initialize hook-guard", "check hooks", "hook doctor", "verify hook setup", "troubleshoot hooks", "update hooks", "regenerate hooks", "sync hooks with current tools", or similar requests.