projectstore-claude 0.29.4 → 0.30.1
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/README.md +13 -12
- package/bin/projectstore-claude.mjs +2 -2
- package/node_modules/projectstore/.claude-plugin/marketplace.json +1 -1
- package/node_modules/projectstore/.claude-plugin/plugin.json +1 -1
- package/node_modules/projectstore/README.md +229 -78
- package/node_modules/projectstore/commands/bind.md +5 -5
- package/node_modules/projectstore/commands/statusline.md +8 -8
- package/node_modules/projectstore/docs/extending.md +11 -6
- package/node_modules/projectstore/docs/getting-started.md +52 -10
- package/node_modules/projectstore/docs/harnesses.md +19 -10
- package/node_modules/projectstore/docs/how-it-works.md +1 -1
- package/node_modules/projectstore/harnesses/claude-code.json +35 -13
- package/node_modules/projectstore/harnesses/codex.json +8 -8
- package/node_modules/projectstore/package.json +1 -1
- package/node_modules/projectstore/scripts/agents-change.mjs +84 -0
- package/node_modules/projectstore/scripts/binding.mjs +40 -0
- package/node_modules/projectstore/scripts/cli.mjs +86 -85
- package/node_modules/projectstore/scripts/configure.mjs +908 -0
- package/node_modules/projectstore/scripts/fetch-shell.mjs +97 -34
- package/node_modules/projectstore/scripts/harness.mjs +8 -0
- package/node_modules/projectstore/scripts/install-harness.mjs +56 -19
- package/node_modules/projectstore/scripts/lib.mjs +41 -5
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
# projectstore-claude
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **To install ProjectStore, run `npx projectstore setup` from a terminal in your project.** This package is a release artifact; you do not need it.
|
|
4
|
+
|
|
5
|
+
The Claude Code distribution shell of [projectstore](https://www.npmjs.com/package/projectstore): the core, pinned at exactly this version and bundled inside this tarball, with the harness fixed to Claude Code.
|
|
6
|
+
|
|
7
|
+
From a terminal in your project:
|
|
4
8
|
|
|
5
9
|
```sh
|
|
6
|
-
npx projectstore
|
|
10
|
+
npx projectstore setup
|
|
7
11
|
```
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- See before you write: `npx projectstore-claude plan --project "$PWD"` prints the same plan and writes nothing; `--verbose` adds every row's reasoning; `npx projectstore-claude <verb> --help` lists a verb's options with examples.
|
|
13
|
+
Setup finds the coding agents the project uses, Claude Code among them, and installs ProjectStore for each, with a vault for the project's notes. It asks a few questions, prints one plan — every write and every host command, verbatim — and asks once before anything runs. For Claude Code it registers the plugin for that checkout at the host's local scope, through a small local marketplace under your Claude home. Restart Claude Code afterwards.
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- Behind a registry mirror: if `npx` answers `could not determine executable to run`, the mirror's index knows only the reserved `0.0.1` placeholder — name the version, and if needed the public registry: `npx --registry https://registry.npmjs.org projectstore-claude@<version> install --project "$PWD"`.
|
|
15
|
-
- Uninstall: `npx projectstore-claude uninstall --project "$PWD"` — forgets the registration for that checkout and nothing else; your vault is plain markdown and stays yours.
|
|
16
|
-
- `doctor`, `status`, `search` and the other read verbs pass through unchanged: `npx projectstore-claude doctor --json`.
|
|
15
|
+
Upgrade, or pin, from the same place; the version you name is the version you run:
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
```sh
|
|
18
|
+
npx projectstore@<version> upgrade
|
|
19
|
+
```
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
This shell's bin is `projectstore <verb> --harness claude-code` and nothing more. `bin/projectstore-claude.mjs` locates the bundled core under `node_modules/projectstore/` and execs it; a different `--harness` is refused (exit 2). The shell carries no plugin of its own: the plugin Claude Code loads is the bundled core.
|
|
21
22
|
|
|
22
|
-
- Docs: https://github.com/SmartAndPoint/ProjectStore#install
|
|
23
|
+
- Docs: https://github.com/SmartAndPoint/ProjectStore#install
|
|
23
24
|
- Source: https://github.com/SmartAndPoint/ProjectStore
|
|
24
25
|
- Issues: https://github.com/SmartAndPoint/ProjectStore/issues
|
|
25
26
|
|
|
@@ -24,7 +24,7 @@ const HARNESS = "claude-code";
|
|
|
24
24
|
// scripts/cli.mjs; the packaging test pins it). Any other verb — doctor,
|
|
25
25
|
// status, search, --version — passes through untouched: the core refuses an
|
|
26
26
|
// option a verb does not declare, so a blanket insert would break `doctor`.
|
|
27
|
-
const HARNESS_VERBS = new Set(["setup","plan","install","uninstall","upgrade","agents"]);
|
|
27
|
+
const HARNESS_VERBS = new Set(["setup","configure","plan","install","uninstall","upgrade","agents"]);
|
|
28
28
|
|
|
29
29
|
// The bundled core, by path — never by package resolution: a hoisted or global
|
|
30
30
|
// copy at another version is exactly the pairing the pin exists to prevent,
|
|
@@ -57,7 +57,7 @@ function fixHarness(argv) {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
const other = given.find((g) => g !== HARNESS);
|
|
60
|
-
if (other !== undefined) return { error: `installs for ${HARNESS} only — \`--harness ${other}\` names another harness. Run
|
|
60
|
+
if (other !== undefined) return { error: `installs for ${HARNESS} only — \`--harness ${other}\` names another harness. Run the core: npx projectstore <verb> --harness ${other} …` };
|
|
61
61
|
if (given.length) return { argv }; // named already: pass through, never twice (the core's option repeats)
|
|
62
62
|
const at = scan.findIndex((a) => !a.startsWith("-"));
|
|
63
63
|
if (at === -1 || !HARNESS_VERBS.has(scan[at])) return { argv };
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"name": "projectstore",
|
|
13
13
|
"displayName": "projectstore",
|
|
14
14
|
"description": "📚 Your agent runs the project through a verified loop: task → artifact (ADR · spec · epic · story) → adversarial critic → backlog → planner → reviewer → done. Plain markdown in an Obsidian-friendly vault, every write approved by you — and any model can pick the project up tomorrow.",
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.30.1",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "Evgenii Konev",
|
|
18
18
|
"email": "ekonev@smartandpoint.com",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projectstore",
|
|
3
3
|
"displayName": "projectstore",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.30.1",
|
|
5
5
|
"description": "Your agent runs the project through a verified loop: task → artifact (ADR / spec / epic / story) → adversarial critic → backlog → planner → reviewer → done. Plain markdown in git — any model can pick the project up tomorrow.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Evgenii Konev @ SmartAndPoint",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/SmartAndPoint/ProjectStore/releases) [](./LICENSE) [](https://github.com/SmartAndPoint/ProjectStore/stargazers)
|
|
6
6
|
|
|
7
|
-
A project workflow plugin for [Claude Code](https://claude.com/claude-code) and [OpenAI Codex](https://developers.openai.com/codex/) (experimental). Both are released together at one version, and
|
|
7
|
+
A project workflow plugin for [Claude Code](https://claude.com/claude-code) and [OpenAI Codex](https://developers.openai.com/codex/) (experimental). Both are released together at one version, and one command sets a project up for either or both: see [Install](#install).
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -75,24 +75,64 @@ In Claude Code a band above the prompt goes further (experimental): the session'
|
|
|
75
75
|
|
|
76
76
|
Open the vault in [Obsidian](https://obsidian.md) and you get the graph view and the board for free. Don't use Obsidian? Everything renders on GitHub and in any editor.
|
|
77
77
|
|
|
78
|
-
## Install
|
|
78
|
+
## Install
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
From a terminal in your project:
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
```
|
|
83
|
+
npx projectstore setup
|
|
84
|
+
```
|
|
83
85
|
|
|
84
|
-
|
|
86
|
+
Setup finds the coding agents the project uses — Claude Code, Codex or both — and installs ProjectStore for each, with a vault for the project's notes. At a terminal it asks a few questions: which folder is the project, which agents to install for, where the vault lives (an existing folder is bound; a missing or empty one becomes a new vault, with its own git repository and the layout's folders) and whether to show ProjectStore in the status line. Then it prints one plan — every file it writes and every host command, verbatim — and asks once before it writes anything. Restart the agent afterwards; Codex asks you to approve the ProjectStore hooks once.
|
|
85
87
|
|
|
86
|
-
**
|
|
88
|
+
**What it needs:**
|
|
89
|
+
|
|
90
|
+
- Node.js 20 or later, always. The plugin's hooks, its MCP server and the status line run as `node` inside the agent session.
|
|
91
|
+
- npm, for Codex only: setup fetches the Codex plugin through npm. Claude Code alone needs no npm.
|
|
92
|
+
- The agent's own CLI on PATH (`claude`, `codex`), and git for a new vault.
|
|
93
|
+
- A terminal outside every Claude Code and Codex session: inside one, the registration waits and the plan says so.
|
|
94
|
+
- macOS or Linux. Windows is not verified yet.
|
|
95
|
+
|
|
96
|
+
Other package runners start setup the same way. Each was observed running it with Claude Code and Codex:
|
|
87
97
|
|
|
88
98
|
```
|
|
89
|
-
|
|
99
|
+
bunx projectstore@latest setup
|
|
90
100
|
```
|
|
91
101
|
|
|
92
|
-
|
|
102
|
+
```
|
|
103
|
+
pnpm dlx projectstore@latest setup
|
|
104
|
+
```
|
|
93
105
|
|
|
94
|
-
|
|
95
|
-
|
|
106
|
+
```
|
|
107
|
+
deno run -A npm:projectstore@latest setup
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`pnpm dlx` needs pnpm 6.13 or later. Without npm on PATH, a runner sets up Claude Code and refuses Codex, naming npm. The runner only fetches the package: setup copies the plugin into the agents' own directories, so clearing the runner's cache later breaks nothing.
|
|
111
|
+
|
|
112
|
+
`npx projectstore setup --dry-run` shows the questions and the plan and writes nothing. Without a terminal (a script, CI, an agent's tool) nothing is asked: `--harness <id>` names an agent and is the confirmation, and `--vault <path>` names the vault. `npx projectstore setup --help` lists the rest.
|
|
113
|
+
|
|
114
|
+
If you prefer a global command:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
npm install -g projectstore
|
|
118
|
+
projectstore setup
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Behind a registry mirror (often a company's), `npx` runs the newest `projectstore` the mirror knows. That can be a release older than setup, which answers that `setup` is an unknown verb, or no release at all. Name the version, and if that is not enough, the public registry:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
npm_config_registry=https://registry.npmjs.org npx projectstore@<version> setup
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
npm reads that variable wherever it runs, so the Codex plugin setup fetches comes from the same registry.
|
|
128
|
+
|
|
129
|
+
### In a Claude Code session
|
|
130
|
+
|
|
131
|
+
Open Claude Code in your project and say:
|
|
132
|
+
|
|
133
|
+
> Install the projectstore plugin from https://github.com/SmartAndPoint/ProjectStore and set it up for this project.
|
|
134
|
+
|
|
135
|
+
Claude adds the git marketplace, installs the plugin, and walks you through binding a vault, scaffolding it and wiring the status line — every step previewed, nothing written without your Yes. Or type it yourself:
|
|
96
136
|
|
|
97
137
|
```
|
|
98
138
|
/plugin marketplace add SmartAndPoint/ProjectStore
|
|
@@ -103,49 +143,31 @@ Then restart Codex, approve the ProjectStore hooks when it asks, and run `$proje
|
|
|
103
143
|
|
|
104
144
|
One switch worth flipping: Claude Code does **not** auto-update third-party plugins by default — `/plugin` → **Marketplaces** → **SmartAndPoint** → toggle **auto-update** on. If you skip it, `/projectstore:doctor` will remind you later with the exact setting.
|
|
105
145
|
|
|
106
|
-
Contributors: `git clone` this repo, then
|
|
107
|
-
|
|
108
|
-
**Or from npm, in one command** — from a terminal, not inside a Claude Code session:
|
|
146
|
+
Contributors: `git clone` this repo, then run Claude Code from the clone's parent folder:
|
|
109
147
|
|
|
110
148
|
```
|
|
111
|
-
|
|
149
|
+
claude --plugin-dir ./ProjectStore
|
|
112
150
|
```
|
|
113
151
|
|
|
114
|
-
|
|
152
|
+
<details>
|
|
153
|
+
<summary>What setup does for each agent, the low-level verbs, the CLI and MCP</summary>
|
|
115
154
|
|
|
116
|
-
**
|
|
117
|
-
|
|
118
|
-
plugin
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
installation back and verifies its version and payload digest. Before it
|
|
122
|
-
changes anything it asks Codex for that read-back (`codex plugin list --json`),
|
|
123
|
-
so a Codex too old to answer stops the registration before it changes anything
|
|
124
|
-
and tells you to upgrade Codex. Restart Codex,
|
|
125
|
-
approve the hooks, and run `$projectstore-bind <vault-path>`. For later
|
|
126
|
-
releases, `npx projectstore-codex@<version> upgrade --project "$PWD"`. Because
|
|
127
|
-
Codex's plugin registry is user-global, ordinary uninstall removes only the
|
|
128
|
-
project's agents block; `uninstall --global` is the explicit machine-wide
|
|
129
|
-
removal. If `npx` answers `could not determine executable to run`, your
|
|
130
|
-
registry (often a company mirror) serves a stale index that knows only the
|
|
131
|
-
reserved `0.0.1` placeholder: name the version, and if that is not enough, the
|
|
132
|
-
public registry: `npx --registry https://registry.npmjs.org
|
|
133
|
-
projectstore-codex@<version> install --project "$PWD"` (the same holds for
|
|
134
|
-
`projectstore-claude`). Codex is **experimental** until a live session has exercised every
|
|
135
|
-
surface it installs; [`docs/harnesses.md`](./docs/harnesses.md) says what has
|
|
136
|
-
been measured and what has not. From a checkout, the same npx path runs against
|
|
137
|
-
a built tarball:
|
|
155
|
+
**Claude Code.** Setup registers the plugin from the npm package [`projectstore`](https://www.npmjs.com/package/projectstore) — one source package carrying every harness's manifest. It writes a small local marketplace of its own under your Claude home, then drives `claude plugin marketplace add` / `plugin install` **at local scope**, so the registration lands in this checkout's `.claude/settings.local.json` and nowhere else. The host CLI and a live session both rewrite the same settings files, so inside a Claude Code session the registration is deferred, and the plan says so: run setup from a terminal outside the session. When the checkout already loads ProjectStore from the git marketplace, setup asks whether to switch this project to the npm install or keep the git marketplace. A switch silences the git-marketplace copy for this checkout only (not globally), so the plugin does not load twice; `uninstall` turns it back on.
|
|
156
|
+
|
|
157
|
+
**Codex.** The Codex plugin ships in a package of its own; setup fetches it at setup's own version and plans Codex in the same plan as everything else. It stages a stable marketplace under `CODEX_HOME`, drives `codex plugin marketplace add` and `codex plugin add`, then reads the installation back and verifies its version and payload digest. Before it changes anything it asks Codex for that read-back (`codex plugin list --json`), so a Codex too old to answer stops the registration before it changes anything and tells you to upgrade Codex. Codex's plugin registry is user-global; the agents block in `AGENTS.md` stays project-local. Codex is **experimental** until a live session has exercised every surface it installs: [`docs/harnesses.md`](./docs/harnesses.md#codex) says what has been verified and what has not. A project can be worked from both agents: they share the binding in `.projectstore/`, and each keeps its own overlay and session state beside it ([running both over one project](./docs/harnesses.md#running-both-over-one-project)).
|
|
158
|
+
|
|
159
|
+
**The low-level verbs.** Setup composes verbs that also run on their own. One agent's install, with no questions about the project or the vault:
|
|
138
160
|
|
|
139
|
-
```sh
|
|
140
|
-
npm run shells:build -- --only projectstore-codex --dev --out dist
|
|
141
|
-
npx --package "./dist/projectstore-codex-$(node -p 'require("./package.json").version').tgz" projectstore-codex install --project "$PWD"
|
|
142
161
|
```
|
|
162
|
+
npx projectstore install --harness claude-code # shows the plan, asks at a terminal, then writes; without a terminal naming the harness is the confirmation — there is no --yes
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`plan` prints the same plan and writes nothing; `--verbose` adds every row's reasoning; `npx projectstore <verb> --help` lists a verb's options with examples. bun works the same on the packed bin.
|
|
143
166
|
|
|
144
|
-
|
|
167
|
+
Without a session — in CI, or in a shell — the same core answers token-free, with a `--json` envelope on every verb:
|
|
145
168
|
|
|
146
169
|
```
|
|
147
170
|
npx projectstore doctor --json
|
|
148
|
-
npx projectstore install --harness claude-code # the low-level form the shell runs: shows the plan, asks at a terminal, then writes; without a terminal naming the harness is the confirmation — there is no --yes
|
|
149
171
|
npx projectstore reconcile --write --only kanban
|
|
150
172
|
```
|
|
151
173
|
|
|
@@ -175,43 +197,107 @@ npx projectstore init ~/vaults/new-project --language ru
|
|
|
175
197
|
npx projectstore scaffold --write
|
|
176
198
|
```
|
|
177
199
|
|
|
178
|
-
`projectstore-claude`, `projectstore-codex` and `projectstore-opencode` are
|
|
200
|
+
`projectstore-claude`, `projectstore-codex` and `projectstore-opencode` are release artifacts: per-harness packages that carry the core, pinned at the same version and bundled, with the harness fixed. Nobody needs to type their names. Setup fetches the Codex one, which carries the Codex plugin; the Claude Code one is published at the core's version too; the opencode one publishes after its plugin root is rendered. The other `projectstore-*` names are reserved placeholders pointing back here. One source package, one version, N tarballs. How a release builds and publishes them, and how to run a checkout's own build: [`packaging/README.md`](./packaging/README.md).
|
|
179
201
|
</details>
|
|
180
202
|
|
|
203
|
+
## Configure
|
|
204
|
+
|
|
205
|
+
Setup asks only what a first install needs. Everything after it is one command, from a terminal in your project:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
npx projectstore configure
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
At a terminal it shows every setting with its current value and where it lives:
|
|
212
|
+
|
|
213
|
+
- each agent's model, per harness;
|
|
214
|
+
- the status line and the band above the prompt (Claude Code);
|
|
215
|
+
- the vault's template language, the default author and tags;
|
|
216
|
+
- the vault's spec policy and lifecycle gates.
|
|
217
|
+
|
|
218
|
+
It asks which to change, then shows one plan and asks once. Without a terminal it prints the same view and writes nothing. To change a setting there, name it with `--set`; naming it is the confirmation:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
npx projectstore configure --set agents.critic=fable --set statusline=on
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`--dry-run` shows the plan and writes nothing, and `--json` returns the settings as one envelope. In a project that uses two harnesses, an agent's model names its overlay with `--harness <id>`.
|
|
225
|
+
|
|
226
|
+
Each setting has exactly one writer, and the plan says which file it changes:
|
|
227
|
+
|
|
228
|
+
- **The agents' models** live in `.projectstore/harness/<harness>.json`. That file is committed, so a change there is a team change.
|
|
229
|
+
- **The status line, the band, the language and the other binding keys** live in `.projectstore/projectstore.json`, which stays on this machine.
|
|
230
|
+
- **The spec policy and the lifecycle gates** live in the vault's `.projectstore.json`, which commits with the vault. Setting `spec_policy=required` records when it took effect; stories closed before then are exempt.
|
|
231
|
+
|
|
232
|
+
The vault itself is changed by `bind --rebind`, which configure names when asked. In a Claude Code session, `/projectstore:statusline` and `/projectstore:agents configure` run the same writers.
|
|
233
|
+
|
|
181
234
|
## Upgrading
|
|
182
235
|
|
|
183
|
-
|
|
184
|
-
|
|
236
|
+
Installed with setup or from npm: from a terminal in your project, name the version you want to run (`latest` is the newest):
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
npx projectstore@<version> upgrade
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
It upgrades every agent the project uses — each one whose own directory (`.claude/`, `.codex/`) or `.projectstore/state/<id>/` is there — in one plan, and fetches the Codex plugin at the same version. `npx projectstore setup` converges a project the same way and asks its questions again. Installed from the git marketplace in a Claude Code session: `/plugin update` (or auto-update) and a restart.
|
|
243
|
+
|
|
244
|
+
A bare upgrade selects agents by those directories, so on Codex name it, which upgrades Codex even in a project where no Codex session has run yet:
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
npx projectstore@<version> upgrade --harness codex
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
With the global command, update it first, then run it in the project:
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
npm install -g projectstore@latest
|
|
254
|
+
projectstore upgrade
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
A project bound before 0.28 needs one more command. What an existing project sees afterwards, and why:
|
|
185
258
|
|
|
186
259
|
- **The project's files move to `.projectstore/`.** `.claude/projectstore.json`
|
|
187
260
|
and `.claude/.projectstore/` become `.projectstore/projectstore.json`,
|
|
188
261
|
`.projectstore/harness/claude-code.json` and `.projectstore/state/`. Nothing
|
|
189
262
|
breaks before you move them: every reader falls back to the old paths through
|
|
190
|
-
0.
|
|
191
|
-
every Claude Code session in the project, run that command from a terminal
|
|
192
|
-
then restart. The command depends on how you installed
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
263
|
+
0.30, and the startup line names the command until the move is done. Close
|
|
264
|
+
every Claude Code session in the project, run that command from a terminal in
|
|
265
|
+
the project, then restart. The command depends on how you installed. From the
|
|
266
|
+
git marketplace (every 0.27.x install), it is the installed copy's own
|
|
267
|
+
`bin/projectstore.mjs`, with its path spelled out in the startup line:
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
node "<plugin cache>/bin/projectstore.mjs" upgrade --harness claude-code --no-register
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
From npm:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
npx projectstore@<version> upgrade --harness claude-code --no-register
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
`--no-register` leaves your plugin registration as it is: both forms move
|
|
280
|
+
only the project's files. The same run re-stamps the status-line launcher at
|
|
281
|
+
its new path and re-registers the agents block, whose template is now v4. An
|
|
282
|
+
upgrade without `--no-register` on a git-marketplace install does more: it
|
|
203
283
|
also registers the plugin from npm for this checkout and turns the
|
|
204
284
|
git-marketplace copy off here, so `/plugin update` stops reaching the
|
|
205
|
-
checkout. The 0.28.0-rc.1 and rc.2 startup lines named that
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
285
|
+
checkout. The 0.28.0-rc.1 and rc.2 startup lines named that form, without
|
|
286
|
+
`--no-register`, so on those, update first and run what the new startup line
|
|
287
|
+
names. If it already happened, this turns the git-marketplace copy back on
|
|
288
|
+
(0.28.0 or later), from a terminal in the project:
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
npx projectstore@<version> uninstall --harness claude-code --surface plugin
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
That copy must be 0.28 or later — an older one reads a moved project as
|
|
295
|
+
unbound — so update it first if it is not. Restart, then in the new session,
|
|
296
|
+
to re-stamp the status line against that copy:
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
/projectstore:doctor --fix
|
|
300
|
+
```
|
|
215
301
|
- **The status line keeps rendering.** A launcher written by an earlier version
|
|
216
302
|
still works, but it carries no file stamp and its embedded fallback root is
|
|
217
303
|
frozen at the old version; the move above re-stamps it. Nothing rewrites that
|
|
@@ -242,9 +328,9 @@ bound before 0.28. What an existing project sees afterwards, and why:
|
|
|
242
328
|
move once more, and the move re-stamps the launcher. If a session already
|
|
243
329
|
re-stamped the status line or re-registered the agents block before the move
|
|
244
330
|
(rc.2's `/projectstore:doctor --fix` did both), 0.27.x reports a foreign
|
|
245
|
-
status line and a v4 block and leaves both alone — unless you run
|
|
246
|
-
`/projectstore:agents register
|
|
247
|
-
still renders, and the move settles both.
|
|
331
|
+
status line and a v4 block and leaves both alone — unless you run
|
|
332
|
+
`/projectstore:agents register` in it, which rewrites the block; the status
|
|
333
|
+
line still renders, and the move settles both.
|
|
248
334
|
- **Rolling back** to 0.27.x after the move: 0.27.x looks for its binding under
|
|
249
335
|
`.claude/`, finds none and offers `bind`. Do not accept. A re-bind writes
|
|
250
336
|
`.claude/projectstore.json` again, and 0.28's `install` and `upgrade` refuse
|
|
@@ -252,11 +338,11 @@ bound before 0.28. What an existing project sees afterwards, and why:
|
|
|
252
338
|
`.claude/projectstore.json`, then run the command the startup line names
|
|
253
339
|
once more: a 0.27.x session writes its welcome marker back under `.claude/`.
|
|
254
340
|
- **Installed from npm?** Then `/plugin update` has nothing to fetch: the
|
|
255
|
-
|
|
256
|
-
the session,
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
341
|
+
package itself refreshes the registration. The upgrade at the top of this
|
|
342
|
+
section, run from a terminal outside the session, rewrites the local
|
|
343
|
+
marketplace and runs the host's `plugin update` for this checkout.
|
|
344
|
+
`/projectstore:doctor` says when the registration is behind the package, and
|
|
345
|
+
names the command.
|
|
260
346
|
|
|
261
347
|
## When an agent starts a task, it can find its way
|
|
262
348
|
|
|
@@ -297,7 +383,62 @@ The deep dive — real session files, measured payloads, how every mechanism wor
|
|
|
297
383
|
|
|
298
384
|
## Uninstalling
|
|
299
385
|
|
|
300
|
-
|
|
386
|
+
From a terminal in your project:
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
npx projectstore uninstall
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
With no `--harness` it covers every agent the project uses — each one whose own directory (`.claude/`, `.codex/`) or `.projectstore/state/<id>/` is there — and removes what install wrote, and only that. For Codex that is the project-owned wiring: its plugin and marketplace are user-global, and removing them for every project is explicit:
|
|
393
|
+
|
|
394
|
+
```
|
|
395
|
+
npx projectstore uninstall --harness codex --global
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
A Claude Code install from the git marketplace is removed in the session:
|
|
399
|
+
|
|
400
|
+
```
|
|
401
|
+
/plugin uninstall projectstore@SmartAndPoint
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**What a removal keeps:**
|
|
405
|
+
|
|
406
|
+
- the vault;
|
|
407
|
+
- the binding `.projectstore/projectstore.json`, with the status-line choice, so a later setup wires the line again;
|
|
408
|
+
- the agents' models in `.projectstore/harness/`, which is committed team configuration;
|
|
409
|
+
- Codex's user-wide registration, until `--global` removes it.
|
|
410
|
+
|
|
411
|
+
`--global` removes the Codex plugin for every other project on this machine too. Their `AGENTS.md` blocks stay and name agents that no longer load: uninstall Codex in each of them as well, or set them up again.
|
|
412
|
+
|
|
413
|
+
Your vault is yours — plain markdown, untouched. One leftover of a host-managed plugin path can be the agents block in `CLAUDE.md`/`AGENTS.md`; remove it with the harness's agents unregister skill, or delete everything between `<!-- projectstore:agents … -->` and `<!-- /projectstore:agents -->` by hand. A one-harness `uninstall`, with `--harness <id>`, leaves a block that lives in `AGENTS.md`, because that file is read by other coding agents too. Claude Code's then removes the `CLAUDE.md` import when that file holds nothing else; Codex's keeps it, so Claude Code still sees the block. `uninstall --surface agents_block` removes the block as well. Once every harness that can read the block's file is among those uninstalled (for `AGENTS.md`, Claude Code and Codex), the block goes too, and the `CLAUDE.md` import with it unless your own text keeps both files.
|
|
414
|
+
|
|
415
|
+
### Reinstalling clean
|
|
416
|
+
|
|
417
|
+
Keeping the vault and the binding, uninstall and set up again. The second setup finds both:
|
|
418
|
+
|
|
419
|
+
```
|
|
420
|
+
npx projectstore uninstall
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
```
|
|
424
|
+
npx projectstore setup
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
To start as if the project was never bound, remove only the machine-local half after the uninstall. `.projectstore/harness/` and `.projectstore/.gitignore` are committed; keep them. The binding also carries the template language, the default author and tags, the skills switch, the band and the status-line choice, and removing it drops them. Setup then asks for the vault again.
|
|
428
|
+
|
|
429
|
+
```
|
|
430
|
+
rm -f .projectstore/projectstore.json
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
```
|
|
434
|
+
rm -rf .projectstore/state
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
To point the project at another vault, no reinstall is needed. From a terminal in your project:
|
|
438
|
+
|
|
439
|
+
```
|
|
440
|
+
npx projectstore bind ~/vaults/other --rebind
|
|
441
|
+
```
|
|
301
442
|
|
|
302
443
|
## Extending
|
|
303
444
|
|
|
@@ -322,7 +463,17 @@ One formatting-only commit is listed in `.git-blame-ignore-revs`. GitHub skips i
|
|
|
322
463
|
git config blame.ignoreRevsFile .git-blame-ignore-revs
|
|
323
464
|
```
|
|
324
465
|
|
|
325
|
-
A branch opened before that commit rebases in two steps, so that the lint fixes before it are kept
|
|
466
|
+
A branch opened before that commit rebases in two steps, so that the lint fixes before it are kept. First onto the commit before it, resolving real conflicts as usual:
|
|
467
|
+
|
|
468
|
+
```sh
|
|
469
|
+
git rebase <the commit before it>
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Then onto the formatting commit itself, where every conflict is formatting only: take your side, format the file with `npx prettier --write <file>` and `git add` it, then continue.
|
|
473
|
+
|
|
474
|
+
```sh
|
|
475
|
+
git rebase --onto <it> <the commit before it>
|
|
476
|
+
```
|
|
326
477
|
|
|
327
478
|
## License
|
|
328
479
|
|
|
@@ -3,7 +3,7 @@ description: Bind this project to an Obsidian vault (or any markdown directory)
|
|
|
3
3
|
argument-hint: <vault-path> | --inherit [--layout engineering] [--lang en|ru|es|de|fr|zh]
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are binding the current project to a markdown vault for projectstore. The config is written by the core's `bind` / `init` verbs (roadmap A8); this interview decides the values, previews them, and asks — it never writes `projectstore.json` itself, except on the inherit path (step 0a), which copies the parent's file verbatim
|
|
6
|
+
You are binding the current project to a markdown vault for projectstore. The config is written by the core's `bind` / `init` verbs (roadmap A8); this interview decides the values, previews them, and asks — it never writes `projectstore.json` itself, except on the inherit path (step 0a), which copies the parent's file verbatim. The settings later steps change — the vault policy (step 7.5) and the status line (step 11) — go through `configure --set`, each key's one writer. The interview's `--lang` is the verb's `--language`.
|
|
7
7
|
|
|
8
8
|
Parse `$ARGUMENTS`:
|
|
9
9
|
- First positional arg: vault path. Expand `~` if present.
|
|
@@ -81,7 +81,7 @@ Steps:
|
|
|
81
81
|
node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" bind "<vault-path>" [--layout <name>] [--language <code>] [--rebind]
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
`init "<vault-path>" …` instead when step 1 chose to create the vault — it creates the whole vault, so step 7 has nothing to offer after it; `--rebind` only when step 0 ended on **Replace bind**. Naming the vault is the verb's confirmation (there is no `--yes`); the interview's AskUserQuestion in step 4 is the in-session gate. Print the verb's output. A non-zero exit is a refusal or a usage error — relay it and stop — except an `init` whose output reports `git init failed` or `Scaffold failed`: the binding is written, so relay the remedy line it prints and continue.
|
|
84
|
+
`init "<vault-path>" …` instead when step 1 chose to create the vault — it creates the whole vault, so step 7 has nothing to offer after it; `--rebind` only when step 0 ended on **Replace bind**. Naming the vault is the verb's confirmation (there is no `--yes`); the interview's AskUserQuestion in step 4 is the in-session gate. Print the verb's output. A non-zero exit is a refusal or a usage error — relay it and stop — except an `init` whose output reports `git init failed` or `Scaffold failed`: the binding is written, so relay the remedy line it prints and continue.
|
|
85
85
|
|
|
86
86
|
6. **Check `.gitignore`**: read `<project>/.gitignore` if it exists. Our own files are self-ignored inside `.projectstore/` — the verb writes that `.gitignore` itself, carrying `projectstore.json` and `state/`, with `harness/` committed on purpose (the layout ADR); on the inherit path of step 0a, which bypasses the verb, you wrote both by hand. Unless `.claude/` is ignored wholesale, the one machine-specific entry left is the host's `.claude/settings.local.json`. If it is missing, offer (AskUserQuestion) to append it. If the user declines, skip silently.
|
|
87
87
|
|
|
@@ -97,7 +97,7 @@ Steps:
|
|
|
97
97
|
- If it already exists with a `spec_policy` key — respect it, print the current policy, do not re-ask.
|
|
98
98
|
- **New bind into a vault with no artifacts** (a vault `init` just made counts: its folders and README indexes are not artifacts): ask via AskUserQuestion — "Enable spec-first policy for this vault (every story must be covered by a spec; doctor enforces it)?" with options **Yes, `spec_policy: required` (Recommended)** / **Not yet, `optional`**. Second question: "Enable lifecycle gates (plan/close sections + evidence checks on stories)?" — **Yes, `lifecycle_gates: on` (Recommended)** / **Off for now**.
|
|
99
99
|
- **Bind to an existing vault with artifacts**: default to `spec_policy: optional`, `lifecycle_gates: off` and say doctor will suggest enabling once specs appear. Do not impose the gate on an existing backlog.
|
|
100
|
-
- On any choice,
|
|
100
|
+
- On any choice, run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" configure --set spec_policy=<required|optional> --set lifecycle_gates=<on|off> --dry-run --project "${CLAUDE_PROJECT_DIR}"` and show its PLAN, then ask via AskUserQuestion: "Record this policy in the vault? [Yes / No]". On **Yes**, run the same command without `--dry-run`; a non-zero exit is a refusal — relay it and go on to step 8 (the binding is already written). It writes `<vault>/.projectstore.json` — vault ROOT, deliberately not inside `<vault>/.projectstore/`, whose .gitignore would keep the policy out of git — and keeps any other key in it:
|
|
101
101
|
|
|
102
102
|
```json
|
|
103
103
|
{
|
|
@@ -107,7 +107,7 @@ Steps:
|
|
|
107
107
|
}
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
`spec_policy_since`
|
|
110
|
+
configure stamps `spec_policy_since` whenever spec_policy becomes `required` — it anchors the legacy exemption (stories done before it stay exempt; stories in progress/review at enable time are in scope).
|
|
111
111
|
|
|
112
112
|
8. **Agent registration** (v0.13, ADR-002): ask via AskUserQuestion — "Register projectstore's agents in CLAUDE.md/AGENTS.md so every session routes to them (critic after authoring artifacts, planner before implementing, reviewer before commit)? [Yes (Recommended) / No]". On Yes, run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" install --harness claude-code --surface agents_block --project "${CLAUDE_PROJECT_DIR}"` and print its output (it renders from the layout's roster, migrates rather than duplicates, previews every write, and applies because the harness is named). On a rebind where a block already exists the verb reports it current or replaces it in place — do not re-ask blindly.
|
|
113
113
|
|
|
@@ -121,4 +121,4 @@ Steps:
|
|
|
121
121
|
|
|
122
122
|
(for `ru`: `[PS#<version>] 📚 Супер-фича в супер-продукте › Ручка для туалетной бумаги (in-progress)`; every bundled language ships its own example pair)
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
First run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" configure --set statusline=on --dry-run --project "${CLAUDE_PROJECT_DIR}"` and show its PLAN; a non-zero exit is a refusal (a foreign status line, an unparseable settings file) — relay it and skip this step. Then ask via AskUserQuestion: "Show your current epic/story in the status line, composed above any existing HUD? [Yes / No]". On Yes, run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" configure --set statusline=on --project "${CLAUDE_PROJECT_DIR}"` and print its output — a non-zero exit is a refusal to relay (it records `statusline.enabled: true` and writes the `settings.local.json` entry and the launcher, in one plan), and report: "Enabled — restart Claude Code in this project to apply. A fresh session shows: `[PS#<version>] 📚 <statusline_no_work>`."
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Enable/disable the projectstore status line (current epic & story in the HUD).
|
|
2
|
+
description: Enable/disable the projectstore status line (current epic & story in the HUD). Runs `configure --set statusline=on|off`, which records the flag and wires or removes the entry behind a preview; the SessionStart hook keeps an existing entry current across plugin updates.
|
|
3
3
|
argument-hint: "on | off | status"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@ You are toggling the projectstore status line for THIS project. When enabled, `i
|
|
|
7
7
|
|
|
8
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 tool hooks — a write's patch after the write — by `story close`, and at session start; a done, closed or parked story leaves the segment); 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
9
|
|
|
10
|
-
This command
|
|
10
|
+
This command runs `configure --set statusline=on|off` (the configure spec, contracts 6 and 9): install's own items record `statusline.enabled` and write or remove the `settings.local.json` entry and the launcher, in one plan. The command never writes `projectstore.json` itself. The SessionStart hook only refreshes an entry that is already ours and removes it when the flag is off — it never creates one.
|
|
11
11
|
|
|
12
12
|
## 1. Require a bound project
|
|
13
13
|
|
|
@@ -21,15 +21,15 @@ Read `.projectstore/projectstore.json`. If missing → "No vault bound. Run `/pr
|
|
|
21
21
|
|
|
22
22
|
## 3. `on`
|
|
23
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 —
|
|
25
|
-
2. **
|
|
26
|
-
3. On
|
|
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 — configure refuses to enable over a foreign local status line (and `statusline.mjs` composes only over a base in `.claude/settings.json` or `~/.claude/settings.json`, never one in `settings.local.json`). AskUserQuestion: **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. **Preview**: run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" configure --set statusline=on --dry-run --project "${CLAUDE_PROJECT_DIR}"` and print its PLAN. A non-zero exit is a refusal — relay it and stop; nothing is asked or written.
|
|
26
|
+
3. **AskUserQuestion** (Yes / No): "Wire the status line for this project?" On Yes, run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" configure --set statusline=on --project "${CLAUDE_PROJECT_DIR}"` and print its output verbatim — it records `statusline.enabled: true` (keeping `statusline.position` and every other key) and writes the `statusLine` entry and the launcher (`.projectstore/state/claude-code/statusline.mjs`, provenance-stamped), in one plan. A non-zero exit is a refusal (a foreign status line, an unparseable settings file, a layout still to move) — relay it and stop; nothing was written.
|
|
27
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
28
|
|
|
29
29
|
## 4. `off`
|
|
30
30
|
|
|
31
|
-
1. **
|
|
32
|
-
2.
|
|
31
|
+
1. **Preview**: run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" configure --set statusline=off --dry-run --project "${CLAUDE_PROJECT_DIR}"` and print its PLAN. A non-zero exit is a refusal — relay it and stop.
|
|
32
|
+
2. **AskUserQuestion** (Yes / No): "Remove the projectstore status line from this project?" On Yes, run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" configure --set statusline=off --project "${CLAUDE_PROJECT_DIR}"` and print its output — it records `statusline.enabled: false` (even if the flag was absent, so the hook keeps it off) and removes our `statusLine` entry and the launcher, and leaves a foreign entry alone.
|
|
33
33
|
3. Report: "Disabled; restart to apply."
|
|
34
34
|
|
|
35
35
|
## 5. `status`
|
|
@@ -42,5 +42,5 @@ Report, read-only:
|
|
|
42
42
|
## Notes
|
|
43
43
|
|
|
44
44
|
- Every write goes through AskUserQuestion. Never write without approval.
|
|
45
|
-
- The command
|
|
45
|
+
- The command runs `configure --set statusline=on|off`, whose install items are the flag's one writer; 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
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.
|