projectstore-codex 0.0.1 → 0.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +48 -0
- package/README.md +15 -7
- package/bin/projectstore-codex.mjs +88 -0
- package/hooks/hooks.json +59 -0
- package/node_modules/projectstore/.claude-plugin/marketplace.json +40 -0
- package/node_modules/projectstore/.claude-plugin/plugin.json +23 -0
- package/node_modules/projectstore/.mcp.json +14 -0
- package/node_modules/projectstore/AGENTS.md +26 -0
- package/node_modules/projectstore/LICENSE +21 -0
- package/node_modules/projectstore/README.md +284 -0
- package/node_modules/projectstore/agents/archaeologist.md +76 -0
- package/node_modules/projectstore/agents/clerk.md +93 -0
- package/node_modules/projectstore/agents/critic.md +94 -0
- package/node_modules/projectstore/agents/librarian.md +81 -0
- package/node_modules/projectstore/agents/planner.md +80 -0
- package/node_modules/projectstore/agents/reviewer.md +98 -0
- package/node_modules/projectstore/bin/projectstore.mjs +7 -0
- package/node_modules/projectstore/commands/adr.md +57 -0
- package/node_modules/projectstore/commands/agents.md +180 -0
- package/node_modules/projectstore/commands/bind.md +128 -0
- package/node_modules/projectstore/commands/codemap.md +50 -0
- package/node_modules/projectstore/commands/concept.md +17 -0
- package/node_modules/projectstore/commands/doctor.md +166 -0
- package/node_modules/projectstore/commands/epic.md +40 -0
- package/node_modules/projectstore/commands/graph.md +56 -0
- package/node_modules/projectstore/commands/kanban.md +40 -0
- package/node_modules/projectstore/commands/meeting.md +17 -0
- package/node_modules/projectstore/commands/reconcile.md +73 -0
- package/node_modules/projectstore/commands/research.md +17 -0
- package/node_modules/projectstore/commands/review.md +89 -0
- package/node_modules/projectstore/commands/runbook.md +17 -0
- package/node_modules/projectstore/commands/scaffold.md +23 -0
- package/node_modules/projectstore/commands/search.md +22 -0
- package/node_modules/projectstore/commands/spec.md +91 -0
- package/node_modules/projectstore/commands/status.md +27 -0
- package/node_modules/projectstore/commands/statusline.md +46 -0
- package/node_modules/projectstore/commands/story.md +113 -0
- package/node_modules/projectstore/docs/extending.md +172 -0
- package/node_modules/projectstore/docs/getting-started.md +133 -0
- package/node_modules/projectstore/docs/harnesses.md +176 -0
- package/node_modules/projectstore/docs/how-it-works.md +263 -0
- package/node_modules/projectstore/docs/images/loop-light.svg +94 -0
- package/node_modules/projectstore/docs/images/loop.svg +93 -0
- package/node_modules/projectstore/docs/images/statusline-hud.png +0 -0
- package/node_modules/projectstore/docs/images/team-light.svg +79 -0
- package/node_modules/projectstore/docs/images/team.svg +79 -0
- package/node_modules/projectstore/harnesses/claude-code.json +483 -0
- package/node_modules/projectstore/harnesses/codex.json +332 -0
- package/node_modules/projectstore/hooks/hooks.json +59 -0
- package/node_modules/projectstore/hooks/pre-compact.mjs +121 -0
- package/node_modules/projectstore/hooks/session-rules.mjs +63 -0
- package/node_modules/projectstore/hooks/session-start.mjs +301 -0
- package/node_modules/projectstore/hooks/session-stop.mjs +84 -0
- package/node_modules/projectstore/package.json +70 -0
- package/node_modules/projectstore/scaffold/checklists.json +88 -0
- package/node_modules/projectstore/scaffold/headings.json +171 -0
- package/node_modules/projectstore/scaffold/layouts/engineering.json +85 -0
- package/node_modules/projectstore/scripts/binding.mjs +165 -0
- package/node_modules/projectstore/scripts/build-adapters.mjs +264 -0
- package/node_modules/projectstore/scripts/cli.mjs +595 -0
- package/node_modules/projectstore/scripts/codemap.mjs +99 -0
- package/node_modules/projectstore/scripts/diff-refs.mjs +127 -0
- package/node_modules/projectstore/scripts/doctor.mjs +2127 -0
- package/node_modules/projectstore/scripts/draft.mjs +261 -0
- package/node_modules/projectstore/scripts/graph.mjs +219 -0
- package/node_modules/projectstore/scripts/harness.mjs +608 -0
- package/node_modules/projectstore/scripts/install-harness.mjs +1387 -0
- package/node_modules/projectstore/scripts/kanban.mjs +174 -0
- package/node_modules/projectstore/scripts/lib.mjs +3085 -0
- package/node_modules/projectstore/scripts/mcp.mjs +391 -0
- package/node_modules/projectstore/scripts/portable-registration.mjs +198 -0
- package/node_modules/projectstore/scripts/provenance.mjs +375 -0
- package/node_modules/projectstore/scripts/query.mjs +490 -0
- package/node_modules/projectstore/scripts/reconcile.mjs +422 -0
- package/node_modules/projectstore/scripts/statusline-launcher.mjs +141 -0
- package/node_modules/projectstore/scripts/statusline.mjs +253 -0
- package/node_modules/projectstore/scripts/story-section.mjs +209 -0
- package/node_modules/projectstore/scripts/surfaces.mjs +421 -0
- package/node_modules/projectstore/scripts/tokens.mjs +449 -0
- package/node_modules/projectstore/scripts/touch-session.mjs +336 -0
- package/node_modules/projectstore/scripts/version-guard.mjs +261 -0
- package/node_modules/projectstore/scripts/worktree.mjs +109 -0
- package/node_modules/projectstore/skills/projectstore-decision-detector/SKILL.md +40 -0
- package/node_modules/projectstore/skills/projectstore-peer-reviewer/SKILL.md +38 -0
- package/node_modules/projectstore/skills/projectstore-story-completion/SKILL.md +50 -0
- package/node_modules/projectstore/skills/projectstore-vault-communication/SKILL.md +96 -0
- package/node_modules/projectstore/templates/claude-md-block.md.tmpl +26 -0
- package/node_modules/projectstore/templates/de/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/de/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/de/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/de/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/de/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/de/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/de/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/de/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/de/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/de/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/de/strings.json +6 -0
- package/node_modules/projectstore/templates/en/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/en/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/en/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/en/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/en/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/en/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/en/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/en/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/en/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/en/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/en/strings.json +6 -0
- package/node_modules/projectstore/templates/es/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/es/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/es/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/es/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/es/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/es/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/es/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/es/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/es/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/es/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/es/strings.json +6 -0
- package/node_modules/projectstore/templates/fr/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/fr/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/fr/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/fr/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/fr/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/fr/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/fr/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/fr/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/fr/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/fr/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/fr/strings.json +6 -0
- package/node_modules/projectstore/templates/ru/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/ru/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/ru/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/ru/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/ru/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/ru/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/ru/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/ru/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/ru/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/ru/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/ru/strings.json +6 -0
- package/node_modules/projectstore/templates/zh/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/zh/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/zh/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/zh/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/zh/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/zh/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/zh/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/zh/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/zh/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/zh/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/zh/strings.json +6 -0
- package/package.json +35 -14
- package/skills/projectstore-adr/SKILL.md +76 -0
- package/skills/projectstore-agents/SKILL.md +50 -0
- package/skills/projectstore-archaeologist/SKILL.md +109 -0
- package/skills/projectstore-bind/SKILL.md +44 -0
- package/skills/projectstore-clerk/SKILL.md +126 -0
- package/skills/projectstore-codemap/SKILL.md +69 -0
- package/skills/projectstore-concept/SKILL.md +36 -0
- package/skills/projectstore-critic/SKILL.md +127 -0
- package/skills/projectstore-decision-detector/SKILL.md +59 -0
- package/skills/projectstore-doctor/SKILL.md +33 -0
- package/skills/projectstore-epic/SKILL.md +59 -0
- package/skills/projectstore-graph/SKILL.md +75 -0
- package/skills/projectstore-kanban/SKILL.md +60 -0
- package/skills/projectstore-librarian/SKILL.md +114 -0
- package/skills/projectstore-meeting/SKILL.md +36 -0
- package/skills/projectstore-peer-reviewer/SKILL.md +57 -0
- package/skills/projectstore-planner/SKILL.md +113 -0
- package/skills/projectstore-reconcile/SKILL.md +92 -0
- package/skills/projectstore-research/SKILL.md +36 -0
- package/skills/projectstore-review/SKILL.md +108 -0
- package/skills/projectstore-reviewer/SKILL.md +131 -0
- package/skills/projectstore-runbook/SKILL.md +36 -0
- package/skills/projectstore-scaffold/SKILL.md +42 -0
- package/skills/projectstore-search/SKILL.md +41 -0
- package/skills/projectstore-spec/SKILL.md +110 -0
- package/skills/projectstore-status/SKILL.md +47 -0
- package/skills/projectstore-statusline/SKILL.md +29 -0
- package/skills/projectstore-story/SKILL.md +132 -0
- package/skills/projectstore-story-completion/SKILL.md +69 -0
- package/skills/projectstore-vault-communication/SKILL.md +115 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Regenerate graph.md — the vault link graph (nodes + typed edges) derived from body links and frontmatter relations. Compute → preview → approval → apply through the core.
|
|
3
|
+
argument-hint: ""
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are managing the vault link graph — the third root-level derived view
|
|
7
|
+
beside kanban.md and code-map.md (spec:
|
|
8
|
+
vault-link-graph-derived-view-and-shared-link-resolver).
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
|
|
12
|
+
1. **Check config**; stop if missing.
|
|
13
|
+
|
|
14
|
+
2. **Compute** (read-only, the unified reconcile path):
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --only graph
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The `graph` entry carries `{ path, changed, content?, stats }` — stats:
|
|
21
|
+
node count, edge count, edges by kind.
|
|
22
|
+
|
|
23
|
+
3. **Nothing changed** (`changed: false`) → report "graph.md already matches
|
|
24
|
+
the vault — nothing to regenerate." and stop.
|
|
25
|
+
|
|
26
|
+
4. **Preview**: show `stats` and the first ~15 lines of `content`. Surface
|
|
27
|
+
`dead` and `ambiguous` edge counts FIRST — they are the actionable part
|
|
28
|
+
(the same facts doctor reports as wikilink findings, from the same
|
|
29
|
+
resolver).
|
|
30
|
+
|
|
31
|
+
5. **Approval** via AskUserQuestion: Yes / No. Disclose that content is
|
|
32
|
+
recomputed from vault state at write time — the preview is advisory, the
|
|
33
|
+
approval covers the regeneration action. On Yes → apply through the core,
|
|
34
|
+
never the Write tool:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --write --only graph
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Explicit selection creates graph.md when absent — bare reconcile
|
|
41
|
+
deliberately never mints it (first creation and re-minting after deletion
|
|
42
|
+
are this command's job). Render the report's `graph` entry; nonzero exit —
|
|
43
|
+
surface the `error`.
|
|
44
|
+
|
|
45
|
+
6. **Verify**: run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" doctor --vault` (exit 1 = findings, not failure)
|
|
46
|
+
and show the summary line.
|
|
47
|
+
|
|
48
|
+
## Notes
|
|
49
|
+
|
|
50
|
+
- The grep contract: `grep '<vault-relative-path>' graph.md` returns an
|
|
51
|
+
artifact's full typed neighborhood — outgoing AND incoming edges — in one
|
|
52
|
+
call. Node keys are full vault-relative paths, never short names.
|
|
53
|
+
- Edge kinds: wikilink, mdlink, supersedes, spec-covers, spec-implements-adr,
|
|
54
|
+
epic-contains, dead, ambiguous, out-of-scope. Nothing resolves silently.
|
|
55
|
+
- Hand-edits to graph.md never stick: doctor flags staleness, reconcile
|
|
56
|
+
repairs. Fix the source artifact, then regenerate.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Regenerate the kanban board from story frontmatter (status, priority, title).
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are regenerating the kanban board.
|
|
6
|
+
|
|
7
|
+
Steps:
|
|
8
|
+
|
|
9
|
+
1. **Check config**. Stop if missing.
|
|
10
|
+
|
|
11
|
+
2. **Compute** (read-only, the unified reconcile path):
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --only kanban
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The `kanban` entry carries `{ path, changed, content?, stats }`.
|
|
18
|
+
|
|
19
|
+
3. **Show stats**: print `stats.total` (total stories) and `stats.by_column`
|
|
20
|
+
(how many in each column). If `changed` is false, report "board already
|
|
21
|
+
matches frontmatter" and stop.
|
|
22
|
+
|
|
23
|
+
4. **Diff preview**: if `<vault>/kanban.md` already exists, read it and show a brief textual diff vs the generated content (count of added/removed lines per column is enough). If it doesn't exist, just preview the first column.
|
|
24
|
+
|
|
25
|
+
5. **Approval** via AskUserQuestion:
|
|
26
|
+
- **Yes** — regenerate the board (content is recomputed from story
|
|
27
|
+
frontmatter at write time; the preview is advisory)
|
|
28
|
+
- **No** — abort, keep current file
|
|
29
|
+
|
|
30
|
+
6. **On Yes**: apply through the core — never the Write tool:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --write --only kanban
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The write is atomic (temp + rename) and recomputed at write time. Render
|
|
37
|
+
the report's `kanban` entry; its `stats` mirror step 3. Nonzero exit —
|
|
38
|
+
surface the `error`.
|
|
39
|
+
|
|
40
|
+
7. **Final**: confirm and suggest opening the file in Obsidian (the `kanban-plugin: board` frontmatter triggers the Kanban view automatically).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a new meeting note (date-prefixed filename).
|
|
3
|
+
argument-hint: <title>
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are creating a meeting note. Today's date is auto-prefixed.
|
|
7
|
+
|
|
8
|
+
Steps:
|
|
9
|
+
|
|
10
|
+
1. Check config; stop if missing.
|
|
11
|
+
2. Run `node "${CLAUDE_PLUGIN_ROOT}/scripts/draft.mjs" meeting "$ARGUMENTS"`.
|
|
12
|
+
3. Preview path + first ~15 lines. When `index` is non-null, print `index.line` too — the exact row that will appear in the folder index, unless the index step reports a failure and no row lands at all. (In the step-5 **Append to existing** branch no new row appears: the existing note already has one, rendered from its own frontmatter.)
|
|
13
|
+
4. AskUserQuestion: Yes / Edit / No. When proposing "Edit", offer to seed `Attendees` and `Agenda` from the conversation context if relevant. This is the only gate: **Yes** covers the artifact and its index row. Disclose in the question that the folder's whole managed index table is regenerated from vault state at write time, so the update may also repair a stale row for another artifact.
|
|
14
|
+
5. Pre-write race check (Layer 1): `test -e "<path>"`. If a meeting note with this date+slug already exists, ask: **Append to existing** (open it and add a section), **Use new slug** (`-2`), or **Cancel**.
|
|
15
|
+
6. On Yes (path free): Write file.
|
|
16
|
+
7. Index row, if `index` is non-null — apply through the core, never Write/Edit, no second gate (step 4 covers it): `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --write --only indexes=<index.folder>`. The row is derived state: canonical order, atomic write, manual prose preserved. The file is already on disk, so a nonzero exit is a warning naming the folder (stderr with no JSON = rejected before any write, fix the header or restore the README; `error` in JSON = I/O failure, suggest `/projectstore:reconcile`), never a failed creation.
|
|
17
|
+
8. Suggest: "Add attendees and agenda before the meeting; record decisions and action items during/after."
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Re-derive every derived view (kanban, folder-index READMEs, code-map, graph) from the vault's source of truth — the repair half of doctor's vault checks. Hand-edits can never permanently desync the board.
|
|
3
|
+
argument-hint: ""
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are reconciling the vault's derived views with their source of truth (frontmatter).
|
|
7
|
+
|
|
8
|
+
## Steps
|
|
9
|
+
|
|
10
|
+
1. **Check config**; stop if missing.
|
|
11
|
+
|
|
12
|
+
2. **Compute** (read-only):
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Output JSON: `kanban` / `codemap` / `graph` / `indexes[]`, each
|
|
19
|
+
`{path, changed, content?}`, plus `summary.changed`. A graph.md that does
|
|
20
|
+
not exist yet reports `skipped` — bare reconcile never mints the file;
|
|
21
|
+
first creation goes through `/projectstore:graph` (or `--only graph`).
|
|
22
|
+
|
|
23
|
+
3. **Nothing changed** (`summary.changed == 0` and `summary.failed == 0`) →
|
|
24
|
+
report "Derived views already match frontmatter — nothing to reconcile."
|
|
25
|
+
and stop.
|
|
26
|
+
|
|
27
|
+
4. **Preview**: list each changed target (path + a one-line what: "kanban board",
|
|
28
|
+
"adr/ index", "code map", "link graph"). Show a short diff excerpt for indexes.
|
|
29
|
+
**Surface any target carrying `error` first** — an errored target has no
|
|
30
|
+
`changed` flag, so it never appears in the changed list; a broken board
|
|
31
|
+
must not hide behind a clean-looking preview.
|
|
32
|
+
|
|
33
|
+
5. **Approval** via AskUserQuestion: **Apply all** / **Select targets** / **Cancel**.
|
|
34
|
+
Disclose in the question that content is recomputed from the vault at write
|
|
35
|
+
time — the preview is advisory, the approval covers the regeneration action.
|
|
36
|
+
|
|
37
|
+
5a. **Delegate the apply — enumerated case: two or more targets** (ADR "Artifact
|
|
38
|
+
content is authored by the context-holder, the write ceremony by a clerk").
|
|
39
|
+
When the approved set contains two or more targets, hand steps 6-7 to
|
|
40
|
+
`projectstore:clerk`: pass the exact selector list from step 4's preview and
|
|
41
|
+
the expectation that doctor ends clean. **Model (ADR-008)**: resolve
|
|
42
|
+
the model with `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" agents model clerk --json --project "${CLAUDE_PROJECT_DIR}"` and pass `result.model` as the spawn's model parameter (`null` → pass nothing);
|
|
43
|
+
missing key, `inherit`, or unreadable config → pass nothing and let the
|
|
44
|
+
agent's own frontmatter decide; never guess a model. The clerk applies
|
|
45
|
+
through the core exactly as step 6 specifies and reports per target. A single
|
|
46
|
+
approved target stays in the main thread — the spawn costs more than it
|
|
47
|
+
saves. No clerk available → steps 6-7 yourself; never a general-purpose
|
|
48
|
+
substitute.
|
|
49
|
+
|
|
50
|
+
6. **On approval**: apply through the core — never the Write/Edit tools:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --write --only <approved,targets>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Selectors: `kanban`, `codemap`, `graph`, `indexes` (all), `indexes=<folder>` (one).
|
|
57
|
+
"Apply all" means the targets previewed in step 4, passed explicitly — not a
|
|
58
|
+
bare `--write`. The script recomputes each target immediately before its own
|
|
59
|
+
atomic replace; manual prose outside the managed Index tables is preserved by
|
|
60
|
+
construction (check-and-retry re-reads the README before writing). Render the
|
|
61
|
+
report: per target `{path, changed, written, error?}` + `summary`. A nonzero
|
|
62
|
+
exit means at least one target failed — surface its `error`.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
7. **Verify**: run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" doctor --vault` (exit 1 = findings, not failure) and show
|
|
66
|
+
the summary line — reconcile's whole point is a clean doctor afterwards.
|
|
67
|
+
|
|
68
|
+
## Notes
|
|
69
|
+
|
|
70
|
+
- Reconcile owns **vault-side** repair (ADR-005 boundary); install-side repair
|
|
71
|
+
lives in `/projectstore:doctor --fix`.
|
|
72
|
+
- Frontmatter is never modified here — if the *frontmatter* is what's wrong, fix
|
|
73
|
+
the artifact, then reconcile.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a new research note.
|
|
3
|
+
argument-hint: <title>
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are creating a research note (deep investigation, comparison, benchmark).
|
|
7
|
+
|
|
8
|
+
Steps:
|
|
9
|
+
|
|
10
|
+
1. Check config; stop if missing.
|
|
11
|
+
2. Run `node "${CLAUDE_PLUGIN_ROOT}/scripts/draft.mjs" research "$ARGUMENTS"`.
|
|
12
|
+
3. Preview path + first ~20 lines. When `index` is non-null, print `index.line` too — the exact row that will appear in the folder index, unless the index step reports a failure and no row lands at all.
|
|
13
|
+
4. AskUserQuestion: Yes / Edit / No. This is the only gate: **Yes** covers the artifact and its index row. Disclose in the question that the folder's whole managed index table is regenerated from vault state at write time, so the update may also repair a stale row for another artifact.
|
|
14
|
+
5. Pre-write race check (Layer 1): `test -e "<path>"`. If exists, ask the user whether to **Overwrite**, **Use new slug** (append `-2`), or **Cancel**.
|
|
15
|
+
6. On Yes (path free or overwrite confirmed): Write file.
|
|
16
|
+
7. Index row, if `index` is non-null — apply through the core, never Write/Edit, no second gate (step 4 covers it): `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --write --only indexes=<index.folder>`. The row is derived state: canonical order, atomic write, manual prose preserved. The file is already on disk, so a nonzero exit is a warning naming the folder (stderr with no JSON = rejected before any write, fix the header or restore the README; `error` in JSON = I/O failure, suggest `/projectstore:reconcile`), never a failed creation.
|
|
17
|
+
8. Suggest: "Fill `Question`, then `Method`, then `Findings`. After the conclusion, consider raising an ADR if the research informs a decision."
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Peer-review an existing artifact (ADR / research / epic / etc.) using a fresh critic-mode agent with a structural checklist. Returns concrete improvements, no sycophancy.
|
|
3
|
+
argument-hint: <path-to-artifact>
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are running a peer review on a projectstore artifact.
|
|
7
|
+
|
|
8
|
+
## Steps
|
|
9
|
+
|
|
10
|
+
1. **Resolve path**: `$ARGUMENTS` is the target file. If it is relative, resolve against the bound vault (read `.projectstore/projectstore.json` → `vault_path`). If config missing, stop with: "Run `/projectstore:bind <path>` first."
|
|
11
|
+
|
|
12
|
+
2. **Read the artifact**: use the Read tool on the resolved path. Stop if file does not exist.
|
|
13
|
+
|
|
14
|
+
3. **Identify the kind**: parse the YAML frontmatter for `type:`. If missing, try to infer from the file path (`adr/` → adr, `epics/<id>/epic.md` → epic, `epics/<id>/stories/*` → story, `research/` → research, etc.). If still unknown, ask the user via AskUserQuestion which kind to apply.
|
|
15
|
+
|
|
16
|
+
4. **Load the checklist**:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cat "${CLAUDE_PLUGIN_ROOT}/scaffold/checklists.json"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Parse JSON, pick the entry by kind. If the kind has no entry, use the `adr` checklist as a generic fallback and note this to the user.
|
|
23
|
+
|
|
24
|
+
5. **Gather domain context**: read the vault's top-level `README.md` and the folder README of the artifact's parent (e.g. `adr/README.md`). Keep both short — they're context for the critic, not the focus.
|
|
25
|
+
|
|
26
|
+
6. **Spawn the critic agent**. Prefer this plugin's own `projectstore:critic` (purpose-built fresh-context critic, no sycophancy; named `projectstore:projectstore-critic` before v0.13). If unavailable, fall back to `oh-my-claudecode:critic`, then `general-purpose`. Use this exact prompt template:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
You are a critic-mode reviewer. You have ONLY the artifact and the
|
|
30
|
+
project context below. You did NOT participate in producing this
|
|
31
|
+
artifact. Your job is to find concrete, actionable problems — not
|
|
32
|
+
to praise.
|
|
33
|
+
|
|
34
|
+
## Artifact ({{kind}} at {{path}})
|
|
35
|
+
|
|
36
|
+
<full file content>
|
|
37
|
+
|
|
38
|
+
## Project context
|
|
39
|
+
|
|
40
|
+
<vault README excerpt>
|
|
41
|
+
<folder README excerpt>
|
|
42
|
+
|
|
43
|
+
## Structural checklist
|
|
44
|
+
|
|
45
|
+
<bullet list of checklist.items>
|
|
46
|
+
|
|
47
|
+
## Report format (strict)
|
|
48
|
+
|
|
49
|
+
Return a numbered list of findings, max 7 items. For each:
|
|
50
|
+
1. **What's wrong** — one sentence, specific (cite section / line).
|
|
51
|
+
2. **Why it matters** — one sentence.
|
|
52
|
+
3. **Suggested fix** — concrete edit, ideally a phrase to add or
|
|
53
|
+
replace.
|
|
54
|
+
|
|
55
|
+
Forbidden:
|
|
56
|
+
- Sycophancy ("Overall this is a strong ADR, but...").
|
|
57
|
+
- Generic advice without a citation.
|
|
58
|
+
- Restating what the artifact says.
|
|
59
|
+
- "Consider" without a concrete alternative.
|
|
60
|
+
|
|
61
|
+
If the artifact passes all checklist items with no concrete issues,
|
|
62
|
+
say so in one line — do not pad.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Set the agent description to: `Peer-review of {{kind}} artifact at {{path}}`. Pass it as a foreground task (you need the result to continue).
|
|
66
|
+
|
|
67
|
+
**Model (ADR-008)**: resolve it with `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" agents model critic --json --project "${CLAUDE_PROJECT_DIR}"` and pass `result.model` as the spawn's model parameter (`null` → pass nothing). Missing key, `inherit`, or unreadable config → pass nothing and let the agent's own frontmatter decide; never guess a model. This is the only way the configured model reaches the agent — there are no override copies (`/projectstore:agents configure`). When falling back to `oh-my-claudecode:critic` or `general-purpose`, pass the same model.
|
|
68
|
+
|
|
69
|
+
7. **Show findings**: print the agent's report verbatim. Number is its number.
|
|
70
|
+
|
|
71
|
+
8. **Ask the user via AskUserQuestion** what to do:
|
|
72
|
+
- **Apply all** — propose Edits for each suggested fix, one at a time with diff preview + approval.
|
|
73
|
+
- **Apply selected** — ask which finding numbers to apply, then walk through them.
|
|
74
|
+
- **Note for later** — leave artifact untouched, but append a `## Review notes` section at the bottom of the file (after user approval) summarizing findings.
|
|
75
|
+
- **Skip** — do nothing, just close.
|
|
76
|
+
|
|
77
|
+
9. **On any apply path**, after each Edit (approved by AskUserQuestion), update the frontmatter:
|
|
78
|
+
- `review_status: reviewed`
|
|
79
|
+
- `reviewed_at: <today's date YYYY-MM-DD>`
|
|
80
|
+
|
|
81
|
+
Do this with one final Edit after all content changes are applied.
|
|
82
|
+
|
|
83
|
+
10. **Final print**: file path, what was applied / noted / skipped, and a one-line hint to commit the review if the vault is git-tracked.
|
|
84
|
+
|
|
85
|
+
## Notes for the implementer (you, Claude)
|
|
86
|
+
|
|
87
|
+
- Critic agent MUST NOT see the conversation that produced the artifact. Only the artifact + minimal context. That fresh framing is the whole point.
|
|
88
|
+
- If the critic returns suspiciously sycophantic findings ("good overall, minor nit:"), retry once with an explicit `NO PRAISE, NO HEDGING.` injected into the prompt.
|
|
89
|
+
- Selective default: if user invoked `/projectstore:review` on a kind whose `default_review` is `false` in checklists.json (e.g. meeting), still run — they asked explicitly. Just don't auto-trigger via skill.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a new ops runbook (step-by-step how-to with verification & rollback).
|
|
3
|
+
argument-hint: <title>
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are creating an ops runbook.
|
|
7
|
+
|
|
8
|
+
Steps:
|
|
9
|
+
|
|
10
|
+
1. Check config; stop if missing.
|
|
11
|
+
2. Run `node "${CLAUDE_PLUGIN_ROOT}/scripts/draft.mjs" runbook "$ARGUMENTS"`.
|
|
12
|
+
3. Preview path + first ~20 lines. When `index` is non-null, print `index.line` too — the exact row that will appear in the folder index, unless the index step reports a failure and no row lands at all.
|
|
13
|
+
4. AskUserQuestion: Yes / Edit / No. This is the only gate: **Yes** covers the artifact and its index row. Disclose in the question that the folder's whole managed index table is regenerated from vault state at write time, so the update may also repair a stale row for another artifact.
|
|
14
|
+
5. Pre-write race check (Layer 1): `test -e "<path>"`. If exists, ask: **Overwrite**, **Use new slug** (`-2`), or **Cancel**.
|
|
15
|
+
6. On Yes (path free or overwrite confirmed): Write file.
|
|
16
|
+
7. Index row, if `index` is non-null — apply through the core, never Write/Edit, no second gate (step 4 covers it): `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --write --only indexes=<index.folder>` (runbooks live in `ops/` — always take the folder from the draft JSON, never from the kind name). The row is derived state: canonical order, atomic write, manual prose preserved. The file is already on disk, so a nonzero exit is a warning naming the folder (stderr with no JSON = rejected before any write, fix the header or restore the README; `error` in JSON = I/O failure, suggest `/projectstore:reconcile`), never a failed creation.
|
|
17
|
+
8. Suggest: "Fill `Purpose`, `Prerequisites`, numbered `Steps` with shell snippets, and always include `Verification` and `Rollback`."
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scaffold the bound vault with the layout's folder structure and README index files.
|
|
3
|
+
argument-hint: [layout-name]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are creating the folder structure of the projectstore layout inside the bound vault.
|
|
7
|
+
|
|
8
|
+
Steps:
|
|
9
|
+
|
|
10
|
+
1. **Read config**: `cat .projectstore/projectstore.json`. If missing, tell user to run `/projectstore:bind <path>` and stop.
|
|
11
|
+
2. **Determine layout**: use `$ARGUMENTS` if provided, else `config.layout`.
|
|
12
|
+
3. **Load layout spec**: `cat "${CLAUDE_PLUGIN_ROOT}/scaffold/layouts/<layout>.json"`. Parse it.
|
|
13
|
+
4. **Show plan**: list every folder that will be created and which folders already exist. Mark new ones with `(create)`, existing with `(exists)`.
|
|
14
|
+
5. **Ask approval** via AskUserQuestion: "Create the missing folders and READMEs? [Yes / Skip READMEs / No]".
|
|
15
|
+
6. **Execute**:
|
|
16
|
+
- For each folder in `layout.folders`:
|
|
17
|
+
- Create directory via `mkdir -p <vault>/<folder.path>`.
|
|
18
|
+
- If `folder.readme === true` and `<vault>/<folder.path>/README.md` does not exist:
|
|
19
|
+
- Read template: `cat "${CLAUDE_PLUGIN_ROOT}/templates/<lang>/folder-readme.md.tmpl"`.
|
|
20
|
+
- Substitute `{{folder_name}}` and `{{folder_description}}` based on the folder kind.
|
|
21
|
+
- Write the README via Write tool.
|
|
22
|
+
- Also create a top-level `<vault>/README.md` if missing — a simple index pointing to each folder.
|
|
23
|
+
7. **Print result**: tree of newly created files and a one-line "next step" suggestion.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Search the bound vault for a phrase — literal, bounded, grouped by folder.
|
|
3
|
+
argument-hint: <query> [--kind <type>] [--status <status>] [--limit <n>] [--case-sensitive] [--include-derived]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are searching the vault for the user's query through the core's `search` verb (roadmap A8: the command is a thin front-end; the deterministic search lives in `scripts/query.mjs` and answers identically over MCP).
|
|
7
|
+
|
|
8
|
+
Steps:
|
|
9
|
+
|
|
10
|
+
1. Run the verb. The query is a positional and travels **behind `--`**, so a phrase that starts with `-` (a flag name, say) is searched for rather than parsed; the options, if the user gave any, go before it:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" search [--kind <type>] [--status <status>] [--limit <n>] [--case-sensitive] [--include-derived] -- "<query>"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The project resolves from the session's project directory; do not pass `--project`. Exit 3 means the project is unbound — say so and point at `/projectstore:bind <vault-path>`; exit 2 is a usage error — relay its message.
|
|
17
|
+
|
|
18
|
+
2. Print the output verbatim. It is already grouped by the vault's top-level folder with a count per group and `path:line snippet` lines; the header says how many matches there are, whether the list was cut (`--limit`, default 20, cap 100) and whether a file hit the per-file cap (`[N in file]`). The search is literal substring, case-insensitive unless `--case-sensitive`, over artifact bodies and `title:` lines; the derived views (the board, `code-map.md`, `graph.md`) are excluded unless `--include-derived`.
|
|
19
|
+
|
|
20
|
+
3. Zero matches is exit 0 and the output already suggests a shorter or case-insensitive phrase. Do not fall back to a shell `grep`: the verb is the search.
|
|
21
|
+
|
|
22
|
+
4. At the end, print a hint: "Open a file with the Read tool: `Read <vault_path>/<path>`" — `vault_path` is in `.projectstore/projectstore.json` (or `status --json` → `result.vault_path`); the search output prints vault-relative paths.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a spec (normative "how" covering one or more stories), or transition its status (draft → active → superseded).
|
|
3
|
+
argument-hint: <title> | activate <SPEC-ID> | supersede <SPEC-ID>
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are managing a **spec** — the durable, normative "how" of a subsystem
|
|
7
|
+
(ADR-007): it references the ADR(s) that decided the approach, carries numbered
|
|
8
|
+
behavioral contracts, and its Acceptance is **additive** to the covered
|
|
9
|
+
stories' own criteria. One spec covers one or more stories and outlives them.
|
|
10
|
+
|
|
11
|
+
Dispatch on the first argument:
|
|
12
|
+
|
|
13
|
+
- `activate <SPEC-ID>` / `supersede <SPEC-ID>` → **Status transition flow**.
|
|
14
|
+
- Anything else → **Creation flow** (the whole argument string is the title).
|
|
15
|
+
|
|
16
|
+
## Creation flow
|
|
17
|
+
|
|
18
|
+
1. **Check config**: stop if `.projectstore/projectstore.json` missing.
|
|
19
|
+
|
|
20
|
+
2. **Render draft**:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
node "${CLAUDE_PLUGIN_ROOT}/scripts/draft.mjs" spec "$ARGUMENTS"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Capture the JSON `{ kind, path, content, index, vars }`.
|
|
27
|
+
|
|
28
|
+
3. **Fill before preview**: populate `adr: []` and `stories: []` (path form:
|
|
29
|
+
`"EPIC-ID/story-002"`, inline flow) from the conversation context when
|
|
30
|
+
known; write the mandatory sections (How we solve with ADR wiki-links,
|
|
31
|
+
numbered Behavioral contracts, Acceptance checkboxes with `— stories:`
|
|
32
|
+
attribution where items are story-specific). Optional sections (Modules &
|
|
33
|
+
files on disk, Testing) may be omitted for research spikes.
|
|
34
|
+
|
|
35
|
+
4. **Preview**: path + full content, plus every `warnings` entry as a `⚠️`
|
|
36
|
+
line. If the draft's `collision` field is non-null, surface it as a
|
|
37
|
+
**topic collision** (`"<identity>" already exists as <with>`) and ask:
|
|
38
|
+
extend the existing spec, pick a different slug (`-2` is a deliberate
|
|
39
|
+
distinct identity), or cancel. When `index` is non-null, print `index.line`
|
|
40
|
+
too — the exact row that will appear in `specs/README.md`, unless the index
|
|
41
|
+
step reports a failure and no row lands at all. **Approval** via
|
|
42
|
+
AskUserQuestion: Yes / Edit / No. This is the only gate: **Yes** covers the
|
|
43
|
+
artifact and its index row. Disclose in the question that the folder's whole
|
|
44
|
+
managed index table is regenerated from vault state at write time, so the
|
|
45
|
+
update may also repair a stale row for another artifact.
|
|
46
|
+
|
|
47
|
+
5. **Post-approval race re-check**: re-run draft.mjs and re-read `collision`
|
|
48
|
+
— an exact-name `test -e` cannot see normalized cross-era collisions. If
|
|
49
|
+
it is now non-null, re-preview and re-ask.
|
|
50
|
+
|
|
51
|
+
6. **On Yes**: Write the file. Then, if `index` is non-null, apply its index
|
|
52
|
+
row through the core — never the Write/Edit tools, no second gate (the
|
|
53
|
+
step-4 approval covers it):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" reconcile --write --only indexes=<index.folder>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The row is derived state — regenerated in canonical order, written
|
|
60
|
+
atomically, manual prose preserved. The artifact is already on disk, so a
|
|
61
|
+
nonzero exit is a warning naming the folder (stderr with no JSON = rejected
|
|
62
|
+
before any write, fix the header or restore the README; per-target `error`
|
|
63
|
+
in JSON = I/O failure, suggest `/projectstore:reconcile`), never a failed
|
|
64
|
+
creation.
|
|
65
|
+
|
|
66
|
+
7. **Reciprocal links**: for every entry in `stories:`, propose an Edit to that
|
|
67
|
+
story's frontmatter adding the spec id to its `specs:` list (inline flow —
|
|
68
|
+
`specs: ["SPEC-001"]`). One AskUserQuestion per file.
|
|
69
|
+
|
|
70
|
+
8. **Remind**: "The spec is `draft`. Run `/projectstore:spec activate <ID>`
|
|
71
|
+
after review — a covered story must not enter implementation while its spec
|
|
72
|
+
is draft (doctor enforces this under `spec_policy: required`)."
|
|
73
|
+
|
|
74
|
+
## Status transition flow
|
|
75
|
+
|
|
76
|
+
1. **Resolve** the spec file in `<vault>/specs/` by id (case-insensitive
|
|
77
|
+
prefix match on the filename). If not found, list existing specs and stop.
|
|
78
|
+
|
|
79
|
+
2. **Validate the transition**: `draft → active` (activate), `active →
|
|
80
|
+
superseded` (supersede). Reject anything else with the current status
|
|
81
|
+
shown. `superseded` requires the user to name what supersedes it — record
|
|
82
|
+
it in the body under References.
|
|
83
|
+
|
|
84
|
+
3. **Preview the change**: current vs proposed frontmatter `status:` (+
|
|
85
|
+
`updated:` bump to today). For `activate`, remind that review is expected
|
|
86
|
+
first (`/projectstore:review <path>`) if `review_status` is still pending —
|
|
87
|
+
ask whether to proceed anyway.
|
|
88
|
+
|
|
89
|
+
4. **Approval** via AskUserQuestion, then apply the Edit (frontmatter lines
|
|
90
|
+
only). Suggest `/projectstore:reconcile` if the specs index shows a stale
|
|
91
|
+
status.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Show what's bound, the active layout, what is in progress, and whether the derived views are fresh.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are summarizing the projectstore binding and the vault's state through the core's `status` verb (roadmap A8: the command renders the verb's facts; nothing here counts, lists or greps the vault by hand).
|
|
6
|
+
|
|
7
|
+
Steps:
|
|
8
|
+
|
|
9
|
+
1. Run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" status --json
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The project resolves from the session's project directory; do not pass `--project`. `status` runs unbound: if `result.bound` is `false`, output "No vault bound. Run `/projectstore:bind <vault-path>` first." and stop.
|
|
16
|
+
|
|
17
|
+
2. Print from `result`: `vault_path` (mark `vault_exists: false` as **missing**), `layout`, `language`, `auto_inject`, `approval_mode`, `spec_policy`, `lifecycle_gates`. If `vault_exists` is `false`, the remaining fields are `null` — stop here with "The bound vault directory is missing — restore it, or rebind with `/projectstore:bind <vault-path>`."
|
|
18
|
+
|
|
19
|
+
3. **Stories** from `result.stories`: `total` on the board with the `by_status` breakdown on one line ("Stories: 72 — done 44, in_progress 3, planned 25"); if `off_board_total` is non-zero, add how many stories the board leaves off and why (`off_board`, e.g. `not_actionable 2`). Then the in-progress list — `in_progress[]` carries `epic`, `title`, `path`, `started_at`; `in_progress_total` says whether the list (capped at 5) is complete. If `stories.status` is `"error"`, print its `error` instead.
|
|
20
|
+
|
|
21
|
+
4. **Views** from `result.views`: one line, `kanban`, `code_map`, `graph` each as fresh / stale / missing / unknown (`stale` is `true`, `false`, or `null` when the view's mtime could not be read; it compares the view's mtime with the newest artifact's). A stale or missing view is the cue for step 6.
|
|
22
|
+
|
|
23
|
+
5. **Active sessions** from `result.sessions`: `active` is the count within the last 30 minutes; `entries[]` (capped at 5) carry `id`, `project_root`, `started_at`, `last_active` — print them as a compact table. From inside a slash command you cannot tell which entry is the current session (Claude's `session_id` reaches hooks, not commands); the user can match by `project_root` and timestamps. If `active` is greater than 1: warn "⚠️ Coordinate via /projectstore:search before creating new artifacts to avoid topic collisions (identity is the slug — ADR-010; the draft's `collision` field catches clashes at creation time)."
|
|
24
|
+
|
|
25
|
+
6. Suggest the next command from what you saw: `stories.total` is 0 → "Vault looks empty — try `/projectstore:scaffold`"; any view stale or missing → "Stale views — try `/projectstore:reconcile`"; something in progress → name it and suggest `/projectstore:story` to continue.
|
|
26
|
+
|
|
27
|
+
What this command no longer does, and why: the former `ls`/`find -mtime -7` walk of recently touched files is gone — its failure mode is a false "nothing changed" (an iCloud download or a git checkout resets mtimes), the opposite of the views' `stale` flag, whose false positive only costs a reconcile. The in-progress list and the views' freshness answer the same question from artifact facts. The former layout-folder check (`ls` the vault, mark missing folders) is `doctor --vault`'s job and `orientation`'s skeleton shows the folders that exist; it is not repeated here.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Enable/disable the projectstore status line (current epic & story in the HUD). Flips a flag and runs the install verb, which wires it behind a preview; the SessionStart hook keeps an existing entry current across plugin updates.
|
|
3
|
+
argument-hint: "on | off | status"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are toggling the projectstore status line for THIS project. When enabled, `install-harness.mjs` points the project's `.claude/settings.local.json` at a launcher it writes at `.projectstore/state/claude-code/statusline.mjs`. That path carries no version, so it never goes stale: the launcher resolves the *currently installed* plugin on every render, and an update is reflected on the spot instead of one restart later. (A dev checkout or `--plugin-dir` root is wired straight to its `scripts/statusline.mjs` — those paths have no version to drift.) The line renders `[PS#<version>] 📚 <epic> › <story> (<status>)` **composed above** any existing HUD (e.g. oh-my-claudecode), never replacing it.
|
|
7
|
+
|
|
8
|
+
Resolution is **per-session with zero cross-session and zero vault reads** (ADR-006): the 📚 segment comes from this session's pointer (`.projectstore/state/sessions/<session_id>.json`, maintained by the PreToolUse hook); a fresh session shows an explicit localized cold-start line ("No epic or story in this session yet" / «Эпик и стори ещё не в работе в этой сессии») — never a silent blank; a corrupt pointer shows an error-marked string. Strings localize via `templates/<lang>/strings.json` (en fallback). The version badge is controlled by `statusline.show_version` (default true).
|
|
9
|
+
|
|
10
|
+
This command flips the flag in `.projectstore/projectstore.json` and then runs the install verb, which writes `settings.local.json` and the launcher behind a preview. The SessionStart hook only refreshes an entry that is already ours and removes it when the flag is off — it never creates one.
|
|
11
|
+
|
|
12
|
+
## 1. Require a bound project
|
|
13
|
+
|
|
14
|
+
Read `.projectstore/projectstore.json`. If missing → "No vault bound. Run `/projectstore:bind <vault-path>` first." and stop. (The epic/story segment needs a vault.)
|
|
15
|
+
|
|
16
|
+
## 2. Parse `$ARGUMENTS`
|
|
17
|
+
|
|
18
|
+
- `on` (or empty) — enable.
|
|
19
|
+
- `off` — disable.
|
|
20
|
+
- `status` — report only; modify nothing.
|
|
21
|
+
|
|
22
|
+
## 3. `on`
|
|
23
|
+
|
|
24
|
+
1. **Foreign status line check** (read-only): read `.claude/settings.local.json` if present. If it has a `statusLine` whose `command` is **not** ours (ours contains either `.projectstore/state/<harness>/statusline.mjs` — the launcher; a not-yet-migrated project's legacy launcher is `.claude/.projectstore/statusline.mjs`, also ours — or `scripts/statusline.mjs` — an older or dev wiring), warn — the hook will **not** clobber a foreign local status line, so enabling would silently do nothing (and `statusline.mjs` composes only over a base in `.claude/settings.json` or `~/.claude/settings.json`, never one in `settings.local.json`). AskUserQuestion: **Proceed anyway / Help me clear it / Cancel**. If a base HUD lives in `~/.claude/settings.json` (e.g. oh-my-claudecode), that's fine — we compose over it; no warning needed.
|
|
25
|
+
2. **AskUserQuestion** (Yes / No): "Wire the status line for this project?" On Yes, run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" install --harness claude-code --surface statusline --project "${CLAUDE_PROJECT_DIR}"` and print its output verbatim — it previews and writes the `statusLine` entry and the launcher (`.projectstore/state/claude-code/statusline.mjs`, provenance-stamped). A non-zero exit is a refusal (a foreign status line, an unparseable settings file) — relay it and stop, leaving the flag as it was.
|
|
26
|
+
3. On success, read `.projectstore/projectstore.json`, set `statusline.enabled = true`. **Preserve `statusline.position`** if present (don't drop it); keep all other keys. Preview the change, then Write.
|
|
27
|
+
4. Report: "Enabled. `📚 <epic> › <story>` renders above your existing HUD. **Restart Claude Code in this project** to apply now (statusLine loads at session start). If `.claude/settings.local.json` is tracked in git, add it to `.gitignore` — the entry carries a machine-specific absolute path."
|
|
28
|
+
|
|
29
|
+
## 4. `off`
|
|
30
|
+
|
|
31
|
+
1. **AskUserQuestion** (Yes / No): "Remove the projectstore status line from this project?" On Yes, read `.projectstore/projectstore.json` and set `statusline.enabled = false` (keep `statusline.position` + other keys) — write it **even if the flag was absent**, so the hook removes any managed `statusLine` entry it previously wrote. Preview, then Write.
|
|
32
|
+
2. Run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" uninstall --harness claude-code --surface statusline --project "${CLAUDE_PROJECT_DIR}"` and print its output — it removes our `statusLine` entry and the launcher, previewed, and leaves a foreign entry alone.
|
|
33
|
+
3. Report: "Disabled; restart to apply."
|
|
34
|
+
|
|
35
|
+
## 5. `status`
|
|
36
|
+
|
|
37
|
+
Report, read-only:
|
|
38
|
+
- `.projectstore/projectstore.json` → `statusline.enabled` and `statusline.position` (default `above`).
|
|
39
|
+
- `.claude/settings.local.json` → whether `statusLine` is present and ours (`command` contains `.projectstore/state/<harness>/statusline.mjs`, the legacy `.claude/.projectstore/statusline.mjs` of a not-yet-migrated project, or `scripts/statusline.mjs`), foreign, or absent. A `scripts/…` command inside the plugin cache is the pre-v0.16 pinned wiring — the hook replaces it with the launcher on the next session start.
|
|
40
|
+
- `.claude/settings.json`, else `~/.claude/settings.json` → `statusLine.command` = the base HUD we compose over (or "none — standalone line").
|
|
41
|
+
|
|
42
|
+
## Notes
|
|
43
|
+
|
|
44
|
+
- Every write goes through AskUserQuestion. Never write without approval.
|
|
45
|
+
- The command writes `.projectstore/projectstore.json` and runs the install verb for the `statusline` surface; the SessionStart hook only refreshes an entry that is already ours (and removes it when the flag is off) — it never creates one, and never touches a foreign status line.
|
|
46
|
+
- Config shape: `.projectstore/projectstore.json` → `"statusline": { "enabled": true, "position": "above", "show_version": true }`. `position` is `above` (default) or `below` — the side our 📚 line sits relative to the base HUD; `show_version` toggles the `[PS#…]` badge.
|