From op
Run the Obsidian Projects workflow — scaffold new projects, create/work/resolve issues, and maintain schema-conformant notes in an Obsidian vault that follows the Projects schema. Use whenever the user invokes /op:* commands, references an Obsidian project by slug or ID prefix (e.g. JB-3, TMB-9, OP-11), or edits files under `Projects/<slug>/ISSUES|TASKS|DOCS|RESOLVED ISSUES/`.
How this skill is triggered — by the user, by Claude, or both
Slash command
/op:opThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are operating on an Obsidian vault that uses the **Projects schema** — a Jira-lite issue tracker where each project is a folder under `Projects/` and each issue/task/doc is a markdown note with structured frontmatter. Schema details live in [`reference/schema.md`](reference/schema.md); read it on first use or when frontmatter shape comes up.
You are operating on an Obsidian vault that uses the Projects schema — a Jira-lite issue tracker where each project is a folder under Projects/ and each issue/task/doc is a markdown note with structured frontmatter. Schema details live in reference/schema.md; read it on first use or when frontmatter shape comes up.
All vault mutations go through the op-obsidian plugin. Probe once per session and cache the result:
obsidian eval code='({enabled: app.plugins.enabledPlugins.has("op-obsidian"), version: app.plugins.plugins["op-obsidian"]?.manifest?.version})'
If the plugin is missing or disabled, stop and ask the user to install/enable it rather than improvising with raw obsidian CLI primitives — the plugin owns filename sanitization, ID numbering, frontmatter shape, atomic move-and-trash on resolve, and the JSON response payload.
Run obsidian vault once to learn the active vault path; cache it.
All op-* commands take key=value arguments (not --flag). Each prints a one-line summary to stdout and writes a full JSON payload to Projects/_scratch/op-last-response.md — read that note for structured fields (paths, trashed-task list, etc.).
| Command | Required | Optional | Effect |
|---|---|---|---|
op-scaffold | slug, prefix | title, priority, scope | creates Projects/<slug>/<slug>.base + STATUS.md; seeds <PREFIX>-1 if title given |
op-new | project, title | priority, scope | creates next-N issue with sanitized filename and schema-conformant frontmatter |
op-work | issue | — | sets status: in-progress; creates the initial TASKS note |
op-append-commit | issue, sha, subject | — | idempotent append to issue's commits: list |
op-set-pr | issue, url | — | sets scalar pr: |
op-resolve (or op-close-current-issue) | issue (or path) | status=wontfix | sets status: resolved, writes resolved: <today>, moves into RESOLVED ISSUES/, trashes linked TASKS — atomically |
scope is a single value containing newline-separated bullets.
Prefix → slug is not a plugin command — scan Projects/*/STATUS.md directly and read the prefix: frontmatter to disambiguate. Do not use obsidian search for this (it misreads prefix: as a query operator).
/op:scaffold <slug> <PREFIX> [<title>]
slug (lowercase + hyphens, Projects/<slug>/ doesn't already exist).obsidian op-scaffold slug=<slug> prefix=<PREFIX> [title="…"] [priority=med] [scope="bullet 1\nbullet 2"].projectFolder, basePath, statusPath, and seedPath (if any) from the JSON response. Suggest /op:new <slug> next./op:new <project-or-prefix> [description]
project-or-prefix to a slug (folder match, else prefix scan over STATUS.md).med), optional scope bullets.obsidian op-new project=<slug> title="<title>" priority=<low|med|high> [scope="bullet 1\nbullet 2"]./op:issue <PREFIX>-<N>./op:issue <project-or-prefix> [<N-or-ID>]
Accepts slug N, slug PREFIX-N, PREFIX N, PREFIX-N, or just slug/PREFIX (auto-pick). Without N, prefer the lowest-numbered in-progress, else the lowest-numbered open. Multiple matches → stop and ask.
obsidian op-work issue=<PREFIX>-<N>.obsidian create is fine for these auxiliary notes — they're trashed at resolve).After each commit on this issue:
sha=$(git rev-parse --short=7 HEAD)
sub=$(git log -1 --pretty=%s)
obsidian op-append-commit issue=<PREFIX>-<N> sha="$sha" subject="$sub"
When a PR opens: obsidian op-set-pr issue=<PREFIX>-<N> url=<pr-url>.
Skip both for meta-only projects with no git repo.
Every issue that ships code bumps the project's version file — one bump per issue, recorded as version: on the issue.
Files (bump in lockstep if multiple ship):
<repo>/plugins/<name>/.claude-plugin/plugin.json (Claude Code plugins)<repo>/manifest.json (Obsidian community plugins)<repo>/package.json (node packages)Classify:
Pre-1.0.0 projects MAY treat breakage as minor; prefer explicit major once the schema stabilizes. Skip entirely for meta-only projects with no version file.
/op:resolve (or run at the tail of work).
Projects/<slug>/ISSUES/<filename> → …/RESOLVED ISSUES/<filename>status → resolved (or wontfix), resolved → <today>commits: status: "set" / "empty — will back-fill from git log" / "empty — skipping (no repo)"<file>: <old> → <new> (patch/minor/major)" — or "skipping (no version file)"commits: if empty. Scan git log for commits referencing the issue id since the last resolved-issue date; append each via obsidian op-append-commit.op-append-commit, then obsidian property:set name=version value=<new> path="<issue-path>". Skip for meta-only projects.obsidian op-resolve issue=<PREFIX>-<N> (or status=wontfix). The plugin moves the file, sets status and resolved:, and trashes linked TASKS atomically. DOCS are never touched.Projects/all-projects.base and Projects/All Projects.md aggregate every project — leave them alone when scaffolding/cleaning. New projects land in them automatically via the project frontmatter key.
Projects with a code repo keep DOCS/superpowers/ as a symlink into <repo>/docs/superpowers/. Vault-only docs (logs, prompt libraries) live directly in DOCS/ alongside the symlink. One-time setup:
mkdir -p <vault>/Projects/<slug>/DOCS
ln -s <repo>/docs/superpowers <vault>/Projects/<slug>/DOCS/superpowers
obsidian eval code='(async()=>{const a=app.vault.adapter;const base="Projects/<slug>/DOCS/superpowers";for(const sub of ["plans","specs","research","testing"]){await a.reconcileFolderCreation(base+"/"+sub, base+"/"+sub);}})()'
Repo-tracked docs (doc_type: plan|spec|adr|runbook) → DOCS/superpowers/{plans,specs,…}/. Vault-only docs → DOCS/ directly. Meta-only projects keep a plain DOCS/ folder, no symlink.
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub earchibald/obsidian-projects --plugin op