planning-with-files 3.20.7 → 3.23.0

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  <div align="center">
2
- <img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.20.7/media/pwf-banner-v5.webp" alt="PWF: Every task. Every step. Three planning files on a brass-inlaid base beneath an engraved arch" width="100%">
2
+ <img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.23.0/media/pwf-banner-v5.webp" alt="PWF: Every task. Every step. Three planning files on a brass-inlaid base beneath an engraved arch" width="100%">
3
3
  </div>
4
4
 
5
5
  <h1 align="center">
@@ -30,9 +30,9 @@ Persistent file-based planning for AI coding agents and long-running agent tasks
30
30
  </p>
31
31
 
32
32
  <p align="center">
33
- <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/evals.md"><img src="https://img.shields.io/badge/benchmark-96.7%25_pass_(29%2F30)-2da44e?style=flat" alt="Benchmark: 96.7 percent assertion pass rate with skill"></a>
34
- <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/evals.md"><img src="https://img.shields.io/badge/blind_A%2FB-3%2F3_wins-2da44e?style=flat" alt="Blind A/B: 3 of 3 wins"></a>
35
- <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/LICENSE"><img src="https://img.shields.io/github/license/OthmanAdi/planning-with-files?style=flat" alt="MIT license"></a>
33
+ <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/evals.md"><img src="https://img.shields.io/badge/benchmark-96.7%25_pass_(29%2F30)-2da44e?style=flat" alt="Benchmark: 96.7 percent assertion pass rate with skill"></a>
34
+ <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/evals.md"><img src="https://img.shields.io/badge/blind_A%2FB-3%2F3_wins-2da44e?style=flat" alt="Blind A/B: 3 of 3 wins"></a>
35
+ <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/LICENSE"><img src="https://img.shields.io/github/license/OthmanAdi/planning-with-files?style=flat" alt="MIT license"></a>
36
36
  </p>
37
37
 
38
38
  <p align="center">
@@ -45,7 +45,7 @@ Persistent file-based planning for AI coding agents and long-running agent tasks
45
45
  </p>
46
46
 
47
47
  <p align="center">
48
- <sub>Proof, comparisons and the repository reference are <a href="#reference">further down</a> · <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/installation.md">Full install guide</a></sub>
48
+ <sub>Proof, comparisons and the repository reference are <a href="#reference">further down</a> · <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/installation.md">Full install guide</a></sub>
49
49
  </p>
50
50
 
51
51
 
@@ -55,7 +55,7 @@ Persistent file-based planning for AI coding agents and long-running agent tasks
55
55
  npx skills add OthmanAdi/planning-with-files --skill planning-with-files -g
56
56
  ```
57
57
 
58
- All install methods: [docs/installation.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/installation.md).
58
+ All install methods: [docs/installation.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/installation.md).
59
59
 
60
60
  ---
61
61
 
@@ -64,7 +64,7 @@ All install methods: [docs/installation.md](https://github.com/OthmanAdi/plannin
64
64
  Every coding agent loses its working memory when the context window resets. The plan does not have to die with it.
65
65
 
66
66
  <p align="center">
67
- <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/media/pwf-context-story-v1.mp4"><img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.20.7/media/pwf-context-story-v1.gif" alt="Illustrated workflow: planning files preserve the task state through a context reset" width="760"></a>
67
+ <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/media/pwf-context-story-v1.mp4"><img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.23.0/media/pwf-context-story-v1.gif" alt="Illustrated workflow: planning files preserve the task state through a context reset" width="760"></a>
68
68
  </p>
69
69
 
70
70
  ## Built for long-running agent tasks
@@ -141,7 +141,7 @@ npx skills add OthmanAdi/planning-with-files --skill planning-with-files-zht -g
141
141
 
142
142
  These are real translations, not an English body with a translated description: the SKILL.md prose, the templates, and the user-facing output of `check-complete`, `init-session` and `session-catchup` are all localized. The status tokens stay literal English (`**Status:** complete`) on purpose, because `check-complete.sh` matches them with `grep -F`, so translating them would disable the completion gate.
143
143
 
144
- Since v3.10.0 the variants also ship the full script surface: attestation, the Stop gate, the ledger, phase status and plan-doctor used to be canonical-only, which quietly made every non-English install a subset install. Full details, including what changed on the plugin route in v3.11.0, are in [docs/languages.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/languages.md).
144
+ Since v3.10.0 the variants also ship the full script surface: attestation, the Stop gate, the ledger, phase status and plan-doctor used to be canonical-only, which quietly made every non-English install a subset install. Full details, including what changed on the plugin route in v3.11.0, are in [docs/languages.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/languages.md).
145
145
 
146
146
  They live under `skills/i18n/`, one directory deeper than the canonical skill. The install commands above are unchanged, because `npx skills add` resolves `--skill` by skill name across the whole repository. The Claude Code plugin scan reads `skills/*/SKILL.md` without recursing, so the plugin route registers the canonical skill alone and no longer carries five extra descriptions in every session's system prompt. On that route the `/plan-ar`, `/plan-de`, `/plan-es`, `/plan-zh` and `/plan-zht` commands read the translated skill from disk instead of invoking it by name.
147
147
 
@@ -152,18 +152,18 @@ They live under `skills/i18n/`, one directory deeper than the canonical skill. T
152
152
 
153
153
  | IDE | Installation Guide | Integration |
154
154
  |-----|-------------------|-------------|
155
- | Claude Code | [Installation](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/installation.md) | Plugin + SKILL.md + Hooks |
156
- | Cursor | [Cursor Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/cursor.md) | Skills + [hooks.json](https://cursor.com/docs/hooks) |
157
- | GitHub Copilot | [Copilot Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/copilot.md) | [Hooks](https://docs.github.com/en/copilot/reference/hooks-configuration) (incl. errorOccurred) |
158
- | Mastra Code | [Mastra Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/mastra.md) | Skills + [Hooks](https://mastra.ai/docs/mastra-code/configuration) |
159
- | Gemini CLI | [Gemini Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/gemini.md) | Skills + [Hooks](https://geminicli.com/docs/hooks/) |
160
- | Kiro | [Kiro Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/kiro.md) | [Agent Skills](https://kiro.dev/docs/skills/) |
161
- | Codex | [Codex Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/codex.md) | [Skills + Hooks](https://developers.openai.com/codex/skills) |
162
- | Hermes Agent | [Hermes Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/hermes.md) | Skill + native plugin (tools, `/pwf`, `pre_llm_call`, `post_tool_call`, `pre_verify` gate), CLI and Desktop |
163
- | CodeBuddy | [CodeBuddy Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/codebuddy.md) | [Skills + Hooks](https://www.codebuddy.ai/docs/cli/skills) |
164
- | FactoryAI Droid | [Factory Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/factory.md) | [Skills + Hooks](https://docs.factory.ai/cli/configuration/skills) |
165
- | OpenCode | [OpenCode Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/opencode.md) | Native plugin `opencode-planning-with-files` (`chat.message` injection, write reminders, compaction flush, `session.idle` gate, `pwf_*` tools, `/pwf` commands) + skill |
166
- | DeepSeek Harness | [DeepSeek Harness Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/deepseek-harness.md) | Native plugin `dsh-planning-with-files` (`agent/pre-step` injection, write reminders, post-compaction restore, `agent/turn-stopping` gate, `pwf_*` tools, `/pwf` commands) + skill |
155
+ | Claude Code | [Installation](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/installation.md) | Plugin + SKILL.md + Hooks |
156
+ | Cursor | [Cursor Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/cursor.md) | Skills + [hooks.json](https://cursor.com/docs/hooks) |
157
+ | GitHub Copilot | [Copilot Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/copilot.md) | [Hooks](https://docs.github.com/en/copilot/reference/hooks-configuration) (incl. errorOccurred) |
158
+ | Mastra Code | [Mastra Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/mastra.md) | Skills + [Hooks](https://mastra.ai/docs/mastra-code/configuration) |
159
+ | Gemini CLI | [Gemini Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/gemini.md) | Skills + [Hooks](https://geminicli.com/docs/hooks/) |
160
+ | Kiro | [Kiro Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/kiro.md) | [Agent Skills](https://kiro.dev/docs/skills/) |
161
+ | Codex | [Codex Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/codex.md) | [Skills + Hooks](https://developers.openai.com/codex/skills) |
162
+ | Hermes Agent | [Hermes Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/hermes.md) | Skill + native plugin (tools, `/pwf`, `pre_llm_call`, `post_tool_call`, `pre_verify` gate), CLI and Desktop |
163
+ | CodeBuddy | [CodeBuddy Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/codebuddy.md) | [Skills + Hooks](https://www.codebuddy.ai/docs/cli/skills) |
164
+ | FactoryAI Droid | [Factory Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/factory.md) | [Skills + Hooks](https://docs.factory.ai/cli/configuration/skills) |
165
+ | OpenCode | [OpenCode Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/opencode.md) | Native plugin `opencode-planning-with-files` (`chat.message` injection, write reminders, compaction flush, `session.idle` gate, `pwf_*` tools, `/pwf` commands) + skill |
166
+ | DeepSeek Harness | [DeepSeek Harness Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/deepseek-harness.md) | Native plugin `dsh-planning-with-files` (`agent/pre-step` injection, write reminders, post-compaction restore, `agent/turn-stopping` gate, `pwf_*` tools, `/pwf` commands) + skill |
167
167
 
168
168
  </details>
169
169
 
@@ -172,13 +172,13 @@ They live under `skills/i18n/`, one directory deeper than the canonical skill. T
172
172
 
173
173
  | IDE | Installation Guide | Skill Discovery Path |
174
174
  |-----|-------------------|---------------------|
175
- | Continue | [Continue Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/continue.md) | `.continue/skills/` + [.prompt files](https://docs.continue.dev/customize/deep-dives/prompts) |
176
- | Pi Agent | [Pi Agent Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/pi-agent.md) | `.pi/skills/` ([npm package](https://www.npmjs.com/package/@mariozechner/pi-coding-agent)) |
177
- | OpenClaw | [OpenClaw Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/openclaw.md) | `.openclaw/skills/` ([docs](https://docs.openclaw.ai/tools/skills)) |
178
- | Autohand Code | [Autohand Code Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/autohand.md) | `~/.autohand/skills/` or `.autohand/skills/` |
179
- | Antigravity | [Antigravity Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/antigravity.md) | `.agent/skills/` ([docs](https://codelabs.developers.google.com/getting-started-with-antigravity-skills)) |
180
- | Kilocode | [Kilocode Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/kilocode.md) | `.kilocode/skills/` ([docs](https://kilo.ai/docs/agent-behavior/skills)) |
181
- | AdaL CLI (Sylph AI) | [AdaL Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/adal.md) | `.adal/skills/` ([docs](https://docs.sylph.ai/features/plugins-and-skills)) |
175
+ | Continue | [Continue Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/continue.md) | `.continue/skills/` + [.prompt files](https://docs.continue.dev/customize/deep-dives/prompts) |
176
+ | Pi Agent | [Pi Agent Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/pi-agent.md) | `.pi/skills/` ([npm package](https://www.npmjs.com/package/@mariozechner/pi-coding-agent)) |
177
+ | OpenClaw | [OpenClaw Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/openclaw.md) | `.openclaw/skills/` ([docs](https://docs.openclaw.ai/tools/skills)) |
178
+ | Autohand Code | [Autohand Code Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/autohand.md) | `~/.autohand/skills/` or `.autohand/skills/` |
179
+ | Antigravity | [Antigravity Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/antigravity.md) | `.agent/skills/` ([docs](https://codelabs.developers.google.com/getting-started-with-antigravity-skills)) |
180
+ | Kilocode | [Kilocode Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/kilocode.md) | `.kilocode/skills/` ([docs](https://kilo.ai/docs/agent-behavior/skills)) |
181
+ | AdaL CLI (Sylph AI) | [AdaL Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/adal.md) | `.adal/skills/` ([docs](https://docs.sylph.ai/features/plugins-and-skills)) |
182
182
 
183
183
  > **Note:** If your IDE uses the legacy Rules system instead of Skills, see the [`legacy-rules-support`](https://github.com/OthmanAdi/planning-with-files/tree/legacy-rules-support) branch.
184
184
 
@@ -189,7 +189,7 @@ They live under `skills/i18n/`, one directory deeper than the canonical skill. T
189
189
 
190
190
  | Runtime | Status | Guide | Notes |
191
191
  |---------|--------|-------|-------|
192
- | BoxLite | ✅ Documented | [BoxLite Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/boxlite.md) | Run Claude Code + planning-with-files inside hardware-isolated micro-VMs |
192
+ | BoxLite | ✅ Documented | [BoxLite Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/boxlite.md) | Run Claude Code + planning-with-files inside hardware-isolated micro-VMs |
193
193
 
194
194
  > BoxLite is a sandbox runtime, not an IDE. Skills load via [ClaudeBox](https://github.com/boxlite-ai/claudebox), BoxLite's official Claude Code integration layer.
195
195
 
@@ -223,7 +223,7 @@ They are complementary stages, not alternatives. Plan mode is where you design a
223
223
 
224
224
  ### What happens to the plan files after a task is complete?
225
225
 
226
- They are working memory, not a tracked deliverable. `task_plan.md`, `findings.md`, `progress.md`, and the `.planning/` directory are gitignored by default and are not archived automatically: the next task overwrites the root plan, and a slug directory just stops being active. Anything worth keeping should be promoted into code, a commit, or a doc. See [After Completion: What Happens to the Plan Files](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/workflow.md#after-completion-what-happens-to-the-plan-files) for the full lifecycle and how to retain a completed plan. This is a deliberate default, not a missing feature; a completion-triggered archive step is a welcome opt-in extension.
226
+ They are working memory, not a tracked deliverable. `task_plan.md`, `findings.md`, `progress.md`, and the `.planning/` directory are gitignored by default and are not archived automatically: the next task overwrites the root plan, and a slug directory just stops being active. Anything worth keeping should be promoted into code, a commit, or a doc. See [After Completion: What Happens to the Plan Files](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/workflow.md#after-completion-what-happens-to-the-plan-files) for the full lifecycle and how to retain a completed plan. This is a deliberate default, not a missing feature; a completion-triggered archive step is a welcome opt-in extension.
227
227
 
228
228
  ### How fast are the hooks?
229
229
 
@@ -238,6 +238,10 @@ One hook fire measures 289ms wall-clock since the v3.6.0 optimization, down from
238
238
 
239
239
  | Version | Highlights |
240
240
  |---------|------------|
241
+ | **v3.23.0** | Public file-only recovery fixture with separate trial arms (#303). DSH V4 message-source compatibility (#306), resolver-based manual workflows (#300), and accurate Codex opt-out documentation (#302). |
242
+ | **v3.22.0** | OpenCode 2 support with native plugin registration, context injection, planning tools and the completion gate. OpenCode 1 remains supported; moved v2 sessions follow their current project (#298). |
243
+ | **v3.21.0** | Explicit root and named attestation targets preserve active selection and project containment (#296). PowerShell initialization retries the concurrent pointer pre-check race with bounded, validated attempts (#294). |
244
+ | **v3.20.8** | Claude Code sessions without a plan no longer end every reply with a Stop notice (#288). Cursor hooks move to the current schema with `sessionStart` injection (#262), Gemini CLI hooks inject through `BeforeAgent` and `AfterTool` `hookSpecificOutput` (#292), and both adapters' hook scripts are now executable on macOS and Linux; the Cursor stop hook stays silent once every phase is complete. PowerShell pointer replacement recovers or removes only its own `ReplaceFile` backup (#254). |
241
245
  | **v3.20.7** | Fixes npm capability disclosure metadata and three unavailable contributor portrait endpoints. The npm package continues to ship the canonical skill and full repository README. |
242
246
  | **v3.20.6** | Phase-status writers claim one lock owner even with Windows-native `mkdir` (#282). OpenCode, DSH and Hermes safely replace linked active pointers (#283, #284). PowerShell named plans reject read-only pointers before creation (#285), work under bracketed paths (#286), and retry transient concurrent pointer writes and inspection races (#287). The remaining `ReplaceFile` artifact case stays open in #254. |
243
247
  | **v3.20.5** | OpenCode replay tolerates malformed parts (#273). Initialization reports attestation failures accurately (#277), analytics plans include Next Step (#279), and PowerShell denied writes fail without activating an incomplete named plan (#280). |
@@ -326,7 +330,7 @@ One hook fire measures 289ms wall-clock since the v3.6.0 optimization, down from
326
330
  | **v2.7.0** | Gemini CLI support |
327
331
  | **v2.2.0** | Session recovery, Windows PowerShell, OS-aware hooks |
328
332
 
329
- [View all releases](https://github.com/OthmanAdi/planning-with-files/releases) · [CHANGELOG](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/CHANGELOG.md)
333
+ [View all releases](https://github.com/OthmanAdi/planning-with-files/releases) · [CHANGELOG](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/CHANGELOG.md)
330
334
 
331
335
  > Parallel plan isolation (`.planning/YYYY-MM-DD-slug/` directories) and Codex session isolation shipped in v2.36.0. The `experimental/isolated-planning` branch was the earlier prototype; master is now the canonical location.
332
336
 
@@ -364,7 +368,7 @@ One hook fire measures 289ms wall-clock since the v3.6.0 optimization, down from
364
368
 
365
369
  *Built something? [Open an issue](https://github.com/OthmanAdi/planning-with-files/issues) to get listed!*
366
370
 
367
- Full list of everyone who made this project better: [CONTRIBUTORS.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/CONTRIBUTORS.md).
371
+ Full list of everyone who made this project better: [CONTRIBUTORS.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/CONTRIBUTORS.md).
368
372
 
369
373
  </details>
370
374
 
@@ -384,7 +388,7 @@ Full list of everyone who made this project better: [CONTRIBUTORS.md](https://gi
384
388
  | Autonomous loops burn tokens on recitation | Autonomous mode drops the per-tool-call recitation and replaces the raw progress tail with a fixed-shape ledger summary; injection is KV-cache stable and one hook fire costs about 289 ms |
385
389
  | Hooks that quietly stop firing | `/plan-doctor` self-checks resolution, injection, attestation, install surfaces and per-fire latency |
386
390
 
387
- Everything in that table is opt-in per plan and byte-identical to the previous behavior when no mode marker is set. Details: [v3 Long-Running Agent Features](#v3-long-running-agent-features) and [docs/long-running-agent-tasks.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/long-running-agent-tasks.md).
391
+ Everything in that table is opt-in per plan and byte-identical to the previous behavior when no mode marker is set. Details: [v3 Long-Running Agent Features](#v3-long-running-agent-features) and [docs/long-running-agent-tasks.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/long-running-agent-tasks.md).
388
392
 
389
393
  ### Installation routes
390
394
 
@@ -455,7 +459,7 @@ What each route actually ships:
455
459
  | DeepSeek Harness `dsh plugin add` | yes, with the skill | **yes**, `/pwf`, `/pwf-status` | **yes**, plugin hooks incl. the gate |
456
460
  | ClawHub / manual copy | yes | no | frontmatter hooks, see note |
457
461
 
458
- Skill-route installs can end up silently hook-less (project trust not accepted, or frontmatter hooks not registering on project-level installs). The hooks are the differentiating mechanism, so if they matter to you, use the plugin route, then verify with `/plan-doctor`. Full matrix and the two silent killers: [docs/installation.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/installation.md#what-each-install-route-actually-ships).
462
+ Skill-route installs can end up silently hook-less (project trust not accepted, or frontmatter hooks not registering on project-level installs). The hooks are the differentiating mechanism, so if they matter to you, use the plugin route, then verify with `/plan-doctor`. Full matrix and the two silent killers: [docs/installation.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/installation.md#what-each-install-route-actually-ships).
459
463
 
460
464
  Install acting up? Open your agent and say: *"Read docs/installation.md and docs/troubleshooting.md from OthmanAdi/planning-with-files and fix my install."* Then run `/plan-doctor`.
461
465
 
@@ -472,7 +476,7 @@ One skill, three integration tiers. Know what your agent gets before you install
472
476
 
473
477
  | Tier | Platforms | What you get |
474
478
  |------|-----------|--------------|
475
- | **Enhanced** (hooks + lifecycle automation) | Claude Code, Cursor, GitHub Copilot, Mastra Code, Gemini CLI, Kiro, Codex, Hermes Agent, CodeBuddy, Factory Droid, OpenCode, DeepSeek Harness | Plan injection every turn, progress reminders, completion check |
479
+ | **Enhanced** (hooks + lifecycle automation) | Claude Code, Cursor, GitHub Copilot, Mastra Code, Gemini CLI, Kiro, Codex, Hermes Agent, CodeBuddy, Factory Droid, OpenCode, DeepSeek Harness | Plan injection every turn (Cursor: at session start), progress reminders, completion check |
476
480
  | **Standard Agent Skills** | Continue, Pi, OpenClaw, Autohand Code, Antigravity, Kilocode, AdaL CLI | SKILL.md discovery via `npx skills add`; the pattern without lifecycle hooks |
477
481
  | **Agent Skills standard path** (in-tree since v3.7.0) | Zed, Amp, Warp, Devin, Antigravity, Gemini CLI, Cursor | `.agents/skills/planning-with-files/` discovered from a plain `git clone`, no per-tool setup |
478
482
 
@@ -492,7 +496,7 @@ Per-platform setup guides, discovery paths and sandbox runtimes are in the colla
492
496
  - **Stall-aware gate.** The completion gate reads the ledger, not `progress.md` mtime, so a worker that stopped producing events releases the stop instead of looping.
493
497
  - **One plan, many hosts.** Claude Code, Codex, Pi, Hermes and OpenCode read the same files, the same `.attestation` and the same gate counters, so a plan can be handed from one agent to another mid-run.
494
498
 
495
- The contract and the `.mode` tokens are specified in the skill itself ([SKILL.md, Autonomous and Gated Modes](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/skills/planning-with-files/SKILL.md#autonomous-and-gated-modes-v3)) and in [docs/long-running-agent-tasks.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/long-running-agent-tasks.md).
499
+ The contract and the `.mode` tokens are specified in the skill itself ([SKILL.md, Autonomous and Gated Modes](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/skills/planning-with-files/SKILL.md#autonomous-and-gated-modes-v3)) and in [docs/long-running-agent-tasks.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/long-running-agent-tasks.md).
496
500
 
497
501
  To find a saved plan, run the installed `scripts/set-active-plan.sh --list` helper from your project directory, or `scripts/set-active-plan.ps1 -List` in PowerShell. It lists named plans under that project's `.planning/` directory, with phase counts for the shipped English and translated templates. `[active]` marks the shared default pointer. Listing does not select a plan or attach a session; use the displayed ID as `PLAN_ID` before starting a concurrent task. Kiro's separate `.kiro/plan` layout is not part of this inventory.
498
502
 
@@ -533,7 +537,7 @@ Optional gated mode can request continuation only on a host that supports the re
533
537
 
534
538
  Keep automatic compaction enabled. The `PreCompact` hook flushes the planning reminder before compaction, and the plugin `SessionStart` path restores the active plan for the continuation.
535
539
 
536
- Maintainer depth (hook architecture, dispatcher layout, parity tooling) lives in [AGENTS.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/AGENTS.md) and [docs/](https://github.com/OthmanAdi/planning-with-files/tree/v3.20.7/docs/).
540
+ Maintainer depth (hook architecture, dispatcher layout, parity tooling) lives in [AGENTS.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/AGENTS.md) and [docs/](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/).
537
541
 
538
542
  ## Commands
539
543
 
@@ -697,12 +701,12 @@ Everything below is the proof and the reference half: the benchmarks and their l
697
701
 
698
702
  ## Benchmark Results
699
703
 
700
- > **Methodology note:** the 96.7% figure comes from the v2.21.0 evaluation run on `claude-sonnet-4-6` (2026-03-06). It measures file-pattern fidelity (does the agent create and maintain the 3-file structure), not goal-drift over long autonomous runs. Newer models and the autonomous-mode work are not yet covered by this number. Full methodology, dataset, and assertion list: [docs/evals.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/evals.md).
704
+ > **Methodology note:** the 96.7% figure comes from the v2.21.0 evaluation run on `claude-sonnet-4-6` (2026-03-06). It measures file-pattern fidelity (does the agent create and maintain the 3-file structure), not goal-drift over long autonomous runs. Newer models and the autonomous-mode work are not yet covered by this number. Full methodology, dataset, and assertion list: [docs/evals.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/evals.md).
701
705
 
702
706
  Evaluated with Anthropic's [skill-creator](https://github.com/anthropics/skills/tree/main/skills/skill-creator) framework: skill v2.21.0, model `claude-sonnet-4-6`, 2026-03-06. 10 parallel subagents, 5 task types, 30 objectively verifiable assertions, 3 blind A/B comparisons.
703
707
 
704
708
  <p align="center">
705
- <img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.20.7/media/benchmark-skill-vs-baseline.svg" width="860" alt="Eval results, with skill vs without: assertions passed 29 of 30 vs 2 of 30, 3-file pattern followed 5 of 5 vs 0 of 5, blind A/B wins 3 of 3 vs 0 of 3, average rubric score 10.0 vs 6.8">
709
+ <img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.23.0/media/benchmark-skill-vs-baseline.svg" width="860" alt="Eval results, with skill vs without: assertions passed 29 of 30 vs 2 of 30, 3-file pattern followed 5 of 5 vs 0 of 5, blind A/B wins 3 of 3 vs 0 of 3, average rubric score 10.0 vs 6.8">
706
710
  </p>
707
711
 
708
712
  | Test | with_skill | without_skill |
@@ -714,17 +718,17 @@ Evaluated with Anthropic's [skill-creator](https://github.com/anthropics/skills/
714
718
 
715
719
  ### Recovery after a context wipe
716
720
 
717
- > **Internal benchmark, v1 (2026-07-06).** Author-run against v3.4.0, harness-authored tasks, deterministic grading, no LLM grades anything. Treat it as the project's own measurement, not an independent comparison. Full method, arms, disclosed limits, and grader validation: [docs/evals.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/evals.md#test-5-competitive-benchmark-v1-seven-planning-methods-head-to-head-2026-07-06-internal).
721
+ > **Internal benchmark, v1 (2026-07-06).** Author-run against v3.4.0, harness-authored tasks, deterministic grading, no LLM grades anything. Treat it as the project's own measurement, not an independent comparison. Full method, arms, disclosed limits, and grader validation: [docs/evals.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/evals.md#test-5-competitive-benchmark-v1-seven-planning-methods-head-to-head-2026-07-06-internal).
718
722
 
719
723
  Protocol: the session is hard-stopped at roughly half done, and a fresh session is told only "Continue the work in this directory." Every graded run across every arm ended pytest-green (77/77), so the difference is re-orientation cost, not correctness.
720
724
 
721
725
  <p align="center">
722
- <img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.20.7/media/recovery-turns.svg" width="860" alt="Turns to resume after a context wipe, internal benchmark v1: 5.0 with planning-with-files, 13.3 for a raw agent with no planning method">
726
+ <img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.23.0/media/recovery-turns.svg" width="860" alt="Turns to resume after a context wipe, internal benchmark v1: 5.0 with planning-with-files, 13.3 for a raw agent with no planning method">
723
727
  </p>
724
728
 
725
- **With the planning files on disk, a resume took 5.0 turns on average; a raw agent took 13.3.** Planning-file recovery plus hook injection put phase state in front of the model before its first tool call, and the same run found no correctness penalty anywhere. This internal v1 used the earlier default transcript catchup; current automatic recovery is file-only and has not been re-benchmarked under the same protocol. An animated summary lives at [docs/benchmark/index.html](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/benchmark/index.html) ([rendered view](https://htmlpreview.github.io/?https://github.com/OthmanAdi/planning-with-files/blob/master/docs/benchmark/index.html)).
729
+ **With the planning files on disk, a resume took 5.0 turns on average; a raw agent took 13.3.** Planning-file recovery plus hook injection put phase state in front of the model before its first tool call, and the same run found no correctness penalty anywhere. This internal v1 used the earlier default transcript catchup; current automatic recovery is file-only and has not been re-benchmarked under the same protocol. Contributors can run that current protocol from [examples/file-only-recovery/](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/examples/file-only-recovery/README.md). Running the fixture is not a new measurement of the 5.0 or 13.3 figures. An animated summary lives at [docs/benchmark/index.html](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/benchmark/index.html) ([rendered view](https://htmlpreview.github.io/?https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/benchmark/index.html)).
726
730
 
727
- [Full methodology and results](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/evals.md) · [Technical write-up](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/article.md)
731
+ [Full methodology and results](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/evals.md) · [Technical write-up](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/article.md)
728
732
 
729
733
  ## File Structure
730
734
 
@@ -762,25 +766,25 @@ Every release maintains 20 tracked parity targets plus the gitignored ClawHub up
762
766
 
763
767
  | Doc | What it covers |
764
768
  |-----|----------------|
765
- | [docs/installation.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/installation.md) | Every install route, the route matrix, the trust prerequisite |
766
- | [docs/quickstart.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/quickstart.md) | Your first planning session in 5 steps |
767
- | [docs/workflow.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/workflow.md) | Day-to-day usage, plan lifecycle, topic handoffs |
768
- | [docs/hermes.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/hermes.md) | Hermes Agent CLI and Desktop: install, `/pwf`, the `pre_verify` gate, Windows, migration from Claude Code |
769
- | [docs/opencode.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/opencode.md) | OpenCode: the native plugin, `/pwf`, the `session.idle` gate, `pwf_*` tools |
770
- | [docs/deepseek-harness.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/deepseek-harness.md) | DeepSeek Harness: the native plugin, profiles, `/pwf`, the turn-boundary gate, what DSH does not expose |
771
- | [docs/evals.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/evals.md) | Full benchmark methodology, raw numbers, disclosed limits |
772
- | [docs/troubleshooting.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/troubleshooting.md) | When hooks are quiet, plus `/plan-doctor` |
773
- | [docs/claude-code-lost-context-after-compaction.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/claude-code-lost-context-after-compaction.md) | Recovering and preventing context loss from compaction |
774
- | [docs/agent-forgets-plan-after-clear.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/agent-forgets-plan-after-clear.md) | The file-based fix when an agent forgets its plan after `/clear` |
775
- | [docs/long-running-agent-tasks.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/docs/long-running-agent-tasks.md) | Keeping a coding agent on track for hours: modes, gate, ledger |
776
- | [MIGRATION.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/MIGRATION.md) | v2 to v3 migration and host capability tiers |
777
- | [SECURITY.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/SECURITY.md) | Vulnerability reporting and hardening history |
778
- | [CONTRIBUTING.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/CONTRIBUTING.md) | How to contribute; authorship is preserved on merge |
779
- | Per-platform guides | 19+ setup docs in [docs/](https://github.com/OthmanAdi/planning-with-files/tree/v3.20.7/docs/), linked from the [platform tables](#works-across-19-platforms) |
769
+ | [docs/installation.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/installation.md) | Every install route, the route matrix, the trust prerequisite |
770
+ | [docs/quickstart.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/quickstart.md) | Your first planning session in 5 steps |
771
+ | [docs/workflow.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/workflow.md) | Day-to-day usage, plan lifecycle, topic handoffs |
772
+ | [docs/hermes.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/hermes.md) | Hermes Agent CLI and Desktop: install, `/pwf`, the `pre_verify` gate, Windows, migration from Claude Code |
773
+ | [docs/opencode.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/opencode.md) | OpenCode: the native plugin, `/pwf`, the `session.idle` gate, `pwf_*` tools |
774
+ | [docs/deepseek-harness.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/deepseek-harness.md) | DeepSeek Harness: the native plugin, profiles, `/pwf`, the turn-boundary gate, what DSH does not expose |
775
+ | [docs/evals.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/evals.md) | Full benchmark methodology, raw numbers, disclosed limits |
776
+ | [docs/troubleshooting.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/troubleshooting.md) | When hooks are quiet, plus `/plan-doctor` |
777
+ | [docs/claude-code-lost-context-after-compaction.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/claude-code-lost-context-after-compaction.md) | Recovering and preventing context loss from compaction |
778
+ | [docs/agent-forgets-plan-after-clear.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/agent-forgets-plan-after-clear.md) | The file-based fix when an agent forgets its plan after `/clear` |
779
+ | [docs/long-running-agent-tasks.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/long-running-agent-tasks.md) | Keeping a coding agent on track for hours: modes, gate, ledger |
780
+ | [MIGRATION.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/MIGRATION.md) | v2 to v3 migration and host capability tiers |
781
+ | [SECURITY.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/SECURITY.md) | Vulnerability reporting and hardening history |
782
+ | [CONTRIBUTING.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/CONTRIBUTING.md) | How to contribute; authorship is preserved on merge |
783
+ | Per-platform guides | 19+ setup docs in [docs/](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/docs/), linked from the [platform tables](#works-across-19-platforms) |
780
784
 
781
785
  ## Contributing
782
786
 
783
- Contributions welcome. Start with [CONTRIBUTING.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/CONTRIBUTING.md). Every shipped contribution is credited: commit authorship is preserved on merge, and contributors are listed in [CONTRIBUTORS.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/CONTRIBUTORS.md), the CHANGELOG Thanks section, and the release notes.
787
+ Contributions welcome. Start with [CONTRIBUTING.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/CONTRIBUTING.md). Every shipped contribution is credited: commit authorship is preserved on merge, and contributors are listed in [CONTRIBUTORS.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/CONTRIBUTORS.md), the CHANGELOG Thanks section, and the release notes.
784
788
 
785
789
  ## License
786
790
 
@@ -802,7 +806,7 @@ MIT License — feel free to use, modify, and distribute.
802
806
 
803
807
  ## Contributors
804
808
 
805
- Code, documentation, and issue contributors. Select a portrait to open a GitHub profile or archived credit. [Full credits](https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/CONTRIBUTORS.md).
809
+ Code, documentation, and issue contributors. Select a portrait to open a GitHub profile or archived credit. [Full credits](https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/CONTRIBUTORS.md).
806
810
 
807
811
  <!-- contributor-portraits:start -->
808
812
  <p align="center">
@@ -820,6 +824,11 @@ Code, documentation, and issue contributors. Select a portrait to open a GitHub
820
824
  <a href="https://github.com/mvanhorn" title="@mvanhorn"><img src="https://github.com/mvanhorn.png?size=56" width="48" height="48" alt="@mvanhorn"></a>
821
825
  <a href="https://github.com/ebrevdo" title="@ebrevdo"><img src="https://github.com/ebrevdo.png?size=56" width="48" height="48" alt="@ebrevdo"></a>
822
826
  <a href="https://github.com/bailob" title="@bailob"><img src="https://github.com/bailob.png?size=56" width="48" height="48" alt="@bailob"></a>
827
+ <a href="https://github.com/as992949791" title="@as992949791"><img src="https://github.com/as992949791.png?size=56" width="48" height="48" alt="@as992949791"></a>
828
+ <a href="https://github.com/shuoxuekeji" title="@shuoxuekeji"><img src="https://github.com/shuoxuekeji.png?size=56" width="48" height="48" alt="@shuoxuekeji"></a>
829
+ <a href="https://github.com/Jinzy" title="@Jinzy"><img src="https://github.com/Jinzy.png?size=56" width="48" height="48" alt="@Jinzy"></a>
830
+ <a href="https://github.com/SomSamantray" title="@SomSamantray"><img src="https://github.com/SomSamantray.png?size=56" width="48" height="48" alt="@SomSamantray"></a>
831
+ <a href="https://github.com/mmychu" title="@mmychu"><img src="https://github.com/mmychu.png?size=56" width="48" height="48" alt="@mmychu"></a>
823
832
  <a href="https://github.com/ericshunhinglee-cloud" title="@ericshunhinglee-cloud"><img src="https://github.com/ericshunhinglee-cloud.png?size=56" width="48" height="48" alt="@ericshunhinglee-cloud"></a>
824
833
  <a href="https://github.com/ShaunLinTW" title="@ShaunLinTW"><img src="https://github.com/ShaunLinTW.png?size=56" width="48" height="48" alt="@ShaunLinTW"></a>
825
834
  <a href="https://github.com/TayfurYldz" title="@TayfurYldz"><img src="https://github.com/TayfurYldz.png?size=56" width="48" height="48" alt="@TayfurYldz"></a>
@@ -848,7 +857,7 @@ Code, documentation, and issue contributors. Select a portrait to open a GitHub
848
857
  <a href="https://github.com/Skulli485" title="@Skulli485"><img src="https://github.com/Skulli485.png?size=56" width="48" height="48" alt="@Skulli485"></a>
849
858
  <a href="https://github.com/carterusedulm2-maker" title="@carterusedulm2-maker"><img src="https://github.com/carterusedulm2-maker.png?size=56" width="48" height="48" alt="@carterusedulm2-maker"></a>
850
859
  <a href="https://github.com/gauravvojha" title="@gauravvojha"><img src="https://github.com/gauravvojha.png?size=56" width="48" height="48" alt="@gauravvojha"></a>
851
- <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/CONTRIBUTORS.md" title="@CleanDev-Fix, archived credit"><img src="https://github.com/identicons/CleanDev-Fix.png" width="48" height="48" alt="@CleanDev-Fix"></a>
860
+ <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/CONTRIBUTORS.md" title="@CleanDev-Fix, archived credit"><img src="https://github.com/identicons/CleanDev-Fix.png" width="48" height="48" alt="@CleanDev-Fix"></a>
852
861
  <a href="https://github.com/bmyury" title="@bmyury"><img src="https://github.com/bmyury.png?size=56" width="48" height="48" alt="@bmyury"></a>
853
862
  <a href="https://github.com/oaabahussain" title="@oaabahussain"><img src="https://github.com/oaabahussain.png?size=56" width="48" height="48" alt="@oaabahussain"></a>
854
863
  <a href="https://github.com/gavinlinasd" title="@gavinlinasd"><img src="https://github.com/gavinlinasd.png?size=56" width="48" height="48" alt="@gavinlinasd"></a>
@@ -881,6 +890,6 @@ Code, documentation, and issue contributors. Select a portrait to open a GitHub
881
890
  <a href="https://github.com/Yigtwxx" title="@Yigtwxx"><img src="https://github.com/Yigtwxx.png?size=56" width="48" height="48" alt="@Yigtwxx"></a>
882
891
  <a href="https://github.com/RioTheGreat-ai" title="@RioTheGreat-ai"><img src="https://github.com/RioTheGreat-ai.png?size=56" width="48" height="48" alt="@RioTheGreat-ai"></a>
883
892
  <a href="https://github.com/kmichels" title="@kmichels"><img src="https://github.com/kmichels.png?size=56" width="48" height="48" alt="@kmichels"></a>
884
- <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.20.7/CONTRIBUTORS.md" title="@voidborne-d, archived credit"><img src="https://github.com/identicons/voidborne-d.png" width="48" height="48" alt="@voidborne-d"></a>
893
+ <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.23.0/CONTRIBUTORS.md" title="@voidborne-d, archived credit"><img src="https://github.com/identicons/voidborne-d.png" width="48" height="48" alt="@voidborne-d"></a>
885
894
  </p>
886
895
  <!-- contributor-portraits:end -->
package/SKILL.md CHANGED
@@ -28,7 +28,7 @@ hooks:
28
28
  - type: command
29
29
  command: "[ -n \"${CLAUDE_PLUGIN_ROOT:-}\" ] && exit 0; SH=\"${CLAUDE_SKILL_DIR}/scripts/skill-hook.sh\"; [ -f \"$SH\" ] || SH=$(ls \"$HOME/.claude/skills/planning-with-files/scripts/skill-hook.sh\" \"$HOME/.claude/plugins/marketplaces/planning-with-files/scripts/skill-hook.sh\" 2>/dev/null | head -1); [ -n \"$SH\" ] && [ -f \"$SH\" ] && sh \"$SH\" --event=precompact; exit 0"
30
30
  metadata:
31
- version: "3.20.7"
31
+ version: "3.23.0"
32
32
  ---
33
33
 
34
34
  # Planning with Files
@@ -325,9 +325,11 @@ For a "babysit until done" workflow, combine `/plan-loop` (cadence) with `/plan-
325
325
 
326
326
  For skill-only installs (no `commands/` folder) or sessions where the slash command refuses to fire, the model can produce the same effect by executing the wrapper steps inline.
327
327
 
328
+ For parallel tasks, pin each host with its task's `PLAN_ID` before starting it, or use separate worktrees. Set `PWF_PLAN_ROOT` when the project root differs from the host's working directory. `.planning/.active_plan` is a shared default; switching it does not bind parallel sessions to their tasks.
329
+
328
330
  **Manual `/plan-goal` procedure:**
329
331
 
330
- 1. Resolve the active plan: prefer `${PLAN_ID}` env var, then `.planning/.active_plan`, then newest `.planning/<dir>/`, then legacy `./task_plan.md`.
332
+ 1. If set, validate `PWF_PLAN_ROOT` as an absolute, existing project root. When `PLAN_ID` is set, use the installed `scripts/resolve-plan-dir.sh` (or `.ps1`) and stop if it returns no directory; the explicit pin was rejected. With `PLAN_ID` unset, first run the resolver with `--check-ambiguity` (`-CheckAmbiguity` in PowerShell); if it returns `PWF_PLAN_AMBIGUOUS_V1`, stop and set a task-specific `PLAN_ID`. Then run the resolver normally and read the selected directory. If it returns no directory and the project root has `task_plan.md`, use the legacy root files; otherwise stop recovery.
331
333
  2. Read the resolved `task_plan.md`.
332
334
  3. Compose a goal condition. Default: `"all phases in task_plan.md report Status: complete and check-complete.sh reports ALL PHASES COMPLETE"`. If the user passed additional clauses, append them.
333
335
  4. Issue Claude Code's native `/goal <condition>` (CC primitive, always available).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planning-with-files",
3
- "version": "3.20.7",
3
+ "version": "3.23.0",
4
4
  "description": "Official Planning with Files skill for AI coding agents. Keeps persistent project planning files and injects selected plan context. Automatic recovery reads project files only; explicit local session catchup has no network upload path. Includes scripts, templates, and a Pi Coding Agent extension.",
5
5
  "keywords": [
6
6
  "planning-with-files",
@@ -6,16 +6,19 @@
6
6
  # attested hash, surfacing a "[PLAN TAMPERED]" warning instead.
7
7
  #
8
8
  # Resolution:
9
- # 1. $PLAN_ID env var → ./.planning/$PLAN_ID/
10
- # 2. ./.planning/.active_plan
11
- # 3. Newest ./.planning/<dir>/ by mtime
12
- # 4. Current directory when it is .planning/<valid-slug>/
13
- # 5. Legacy ./task_plan.md at project root
9
+ # 1. --target root or <plan-id> → root or named plan under $PWF_PLAN_ROOT (default: cwd)
10
+ # 2. $PLAN_ID env var → ./.planning/$PLAN_ID/
11
+ # 3. ./.planning/.active_plan
12
+ # 4. Newest ./.planning/<dir>/ by mtime
13
+ # 5. Current directory when it is .planning/<valid-slug>/
14
+ # 6. Legacy ./task_plan.md at project root
14
15
  #
15
16
  # Usage:
16
17
  # sh scripts/attest-plan.sh # attest the active plan
17
18
  # sh scripts/attest-plan.sh --show # print the stored hash
18
19
  # sh scripts/attest-plan.sh --clear # remove the attestation (re-open the plan)
20
+ # sh scripts/attest-plan.sh --target root # attest the legacy root plan
21
+ # sh scripts/attest-plan.sh --target <plan-id> # attest one named plan
19
22
 
20
23
  set -u
21
24
 
@@ -42,6 +45,39 @@ resolve_from_slug_cwd() {
42
45
  }
43
46
 
44
47
  resolve_plan_file() {
48
+ if [ -n "${target:-}" ]; then
49
+ if [ "${target}" = "root" ]; then
50
+ target_root="."
51
+ if [ -n "${PWF_PLAN_ROOT:-}" ]; then
52
+ # Match the shared resolver's supported absolute local pins.
53
+ # A valid project-root junction is intentional, so resolve it.
54
+ case "${PWF_PLAN_ROOT}" in
55
+ \\\\*|//*|[A-Za-z]:[!\\/]*) return 1 ;;
56
+ /*|[A-Za-z]:[\\/]*) ;;
57
+ *) return 1 ;;
58
+ esac
59
+ target_root="$(cd "${PWF_PLAN_ROOT}" 2>/dev/null && pwd -P)" || return 1
60
+ fi
61
+ [ ! -L "${target_root}/task_plan.md" ] || return 1
62
+ [ -f "${target_root}/task_plan.md" ] || return 1
63
+ printf "%s\n" "${target_root}/task_plan.md"
64
+ return 0
65
+ fi
66
+ slug_is_valid "${target}" || return 1
67
+ # Reuse the binding, project-pin and containment rules. A flag replaces
68
+ # PLAN_ID for this call only; it does not change the shared pointer.
69
+ [ -f "${RESOLVER}" ] || return 1
70
+ target_dir="$(PLAN_ID="${target}" sh "${RESOLVER}" 2>/dev/null)" || return 1
71
+ [ -n "${target_dir}" ] || return 1
72
+ # Use the shell's physical path spelling: native Windows backslashes
73
+ # make sha256sum prefix its output with an escaped-filename marker.
74
+ target_dir="$(cd "${target_dir}" 2>/dev/null && pwd -P)" || return 1
75
+ [ ! -L "${target_dir}/task_plan.md" ] || return 1
76
+ [ -f "${target_dir}/task_plan.md" ] || return 1
77
+ printf "%s\n" "${target_dir}/task_plan.md"
78
+ return 0
79
+ fi
80
+
45
81
  plan_dir=""
46
82
  if [ -f "${RESOLVER}" ]; then
47
83
  plan_dir="$(sh "${RESOLVER}" 2>/dev/null)"
@@ -80,7 +116,9 @@ resolve_plan_file() {
80
116
  attestation_path_for() {
81
117
  plan_file="$1"
82
118
  plan_dir="$(dirname "${plan_file}")"
83
- if [ "${plan_dir}" = "." ]; then
119
+ if [ "${target:-}" = "root" ]; then
120
+ printf "%s\n" "${plan_dir}/.plan-attestation"
121
+ elif [ "${plan_dir}" = "." ]; then
84
122
  # Legacy mode: store at project root.
85
123
  printf "%s\n" "./.plan-attestation"
86
124
  else
@@ -101,14 +139,21 @@ compute_hash() {
101
139
  }
102
140
 
103
141
  mode="attest"
142
+ target=""
143
+ usage_error() {
144
+ printf "Usage: %s [--show|--clear|--target root|<plan-id>]\n" "$0" >&2
145
+ exit 2
146
+ }
104
147
  case "${1:-}" in
105
- --show) mode="show" ;;
106
- --clear) mode="clear" ;;
107
- "") mode="attest" ;;
108
- *)
109
- printf "Usage: %s [--show|--clear]\n" "$0" >&2
110
- exit 2
148
+ --show) [ "$#" -eq 1 ] || usage_error; mode="show" ;;
149
+ --clear) [ "$#" -eq 1 ] || usage_error; mode="clear" ;;
150
+ --target)
151
+ [ "$#" -eq 2 ] || usage_error
152
+ [ -n "$2" ] || usage_error
153
+ target="$2"
111
154
  ;;
155
+ "") [ "$#" -eq 0 ] || usage_error ;;
156
+ *) usage_error ;;
112
157
  esac
113
158
 
114
159
  plan_file="$(resolve_plan_file)" || {
@@ -117,7 +162,9 @@ plan_file="$(resolve_plan_file)" || {
117
162
  # a mistyped PLAN_ID attested a DIFFERENT plan at rc=0, and an operator
118
163
  # who now sees a generic not-found is likely to go looking for the wrong
119
164
  # problem. The selectors are bindings, so say which one refused.
120
- if [ -n "${PLAN_ID:-}" ]; then
165
+ if [ -n "${target:-}" ]; then
166
+ printf "[plan-attest] --target %s did not resolve to a plan. An explicit target is a binding: nothing was attested and no other plan was substituted.\n" "${target}" >&2
167
+ elif [ -n "${PLAN_ID:-}" ]; then
121
168
  printf "[plan-attest] PLAN_ID=%s names no plan directory under .planning. An explicit selector is a binding: nothing was attested and no other plan was substituted.\n" "${PLAN_ID}" >&2
122
169
  elif [ -n "${PWF_PLAN_ROOT:-}" ]; then
123
170
  printf "[plan-attest] PWF_PLAN_ROOT=%s did not resolve to a project root holding a plan. An explicit pin is a binding: nothing was attested and no other plan was substituted.\n" "${PWF_PLAN_ROOT}" >&2
@@ -156,6 +203,8 @@ case "${mode}" in
156
203
  fi
157
204
  ;;
158
205
  attest)
206
+ printf "Plan: %s\n" "${plan_file}"
207
+ printf "Attestation: %s\n" "${attestation_file}"
159
208
  hash_val="$(compute_hash "${plan_file}")" || exit 1
160
209
 
161
210
  # v2.40: protect the write with an advisory flock when available so
@@ -51,6 +51,8 @@ if ($PlanFile -ne "") {
51
51
  }
52
52
 
53
53
  if (-not (Test-Path $PlanFile)) {
54
+ # Automatic gate checks have nothing to report without a plan; the explicit report keeps its notice.
55
+ if ($Gate) { exit 0 }
54
56
  Write-Host '[planning-with-files] No task_plan.md found -- no active planning session.'
55
57
  exit 0
56
58
  }
@@ -79,6 +79,9 @@ else
79
79
  fi
80
80
 
81
81
  if [ ! -f "$PLAN_FILE" ]; then
82
+ # Automatic gate checks have nothing to report without a plan (header:
83
+ # "plans stay silent in --gate mode"); the explicit report keeps its notice.
84
+ [ "$GATE" -eq 1 ] && exit 0
82
85
  echo "[planning-with-files] No task_plan.md found — no active planning session."
83
86
  exit 0
84
87
  fi
@@ -368,8 +368,10 @@ if ($UsePlanDir) {
368
368
  # Another writer can replace the pointer between the selector's
369
369
  # Get-Item and final-path check. Retry only that transient result.
370
370
  $transientPointerRace = $selectorResult -is [System.Management.Automation.ErrorRecord] -and
371
- $selectorResult.Exception.Message -ceq
372
- 'Error: could not set the active plan pointer: the active plan pointer became unsafe during replacement'
371
+ $selectorResult.Exception.Message -in @(
372
+ 'Error: could not set the active plan pointer: the active plan pointer became unsafe during replacement',
373
+ 'Error: the active plan pointer must be a regular file within the project.'
374
+ )
373
375
  if ($attempt -eq 5 -or -not $transientPointerRace) {
374
376
  break
375
377
  }
@@ -132,6 +132,54 @@ function Test-SafeActiveFile {
132
132
  (Test-WithinRoot $ActiveFile)
133
133
  }
134
134
 
135
+ function Test-SafeOwnedBackupFile {
136
+ param([string]$Path)
137
+ $item = Get-Item -LiteralPath $Path -Force -ErrorAction SilentlyContinue
138
+ if (-not $item) { return $false }
139
+ $linked = ([string]$item.LinkType) -in @('SymbolicLink', 'Junction')
140
+ return -not $item.PSIsContainer -and -not $linked -and (Test-WithinRoot $Path)
141
+ }
142
+
143
+ function Resolve-OwnedPointerBackup {
144
+ param([string]$BackupFile, [switch]$ReplaceSucceeded)
145
+ # ReplaceFile can move the old destination before failing to move the new
146
+ # file. A caller-named backup makes that intermediate state attributable to
147
+ # this invocation, so recover or delete only this GUID path. Never glob for
148
+ # ~RF*.TMP: a concurrent selector may own those files.
149
+ $maxAttempts = 20
150
+ for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
151
+ $backupItem = Get-Item -LiteralPath $BackupFile -Force -ErrorAction SilentlyContinue
152
+ if (-not $backupItem) { return $true }
153
+ # A failed inspection is transient under concurrent writers: retry.
154
+ if (-not (Test-SafeOwnedBackupFile $BackupFile)) { Start-Sleep -Milliseconds 25; continue }
155
+
156
+ $currentActive = Get-Item -LiteralPath $ActiveFile -Force -ErrorAction SilentlyContinue
157
+ # After our own successful replacement the backup holds a superseded
158
+ # value: only delete it, never move it back over a newer pointer.
159
+ if ($ReplaceSucceeded -or $currentActive) {
160
+ if (-not $ReplaceSucceeded -and -not (Test-SafeActiveFile)) { Start-Sleep -Milliseconds 25; continue }
161
+ try {
162
+ [IO.File]::Delete($BackupFile)
163
+ return $true
164
+ } catch {
165
+ if ($attempt -eq $maxAttempts) { return $false }
166
+ }
167
+ } else {
168
+ try {
169
+ [IO.File]::Move($BackupFile, $ActiveFile)
170
+ return $true
171
+ } catch {
172
+ # Another selector may have recreated the pointer between the
173
+ # absence check and Move. Reinspect before deciding whether the
174
+ # owned backup is now redundant.
175
+ if ($attempt -eq $maxAttempts) { return $false }
176
+ }
177
+ }
178
+ Start-Sleep -Milliseconds 25
179
+ }
180
+ return $false
181
+ }
182
+
135
183
  function Get-CurrentActivePlan {
136
184
  if (-not (Test-SafeActiveFile -AllowLink)) { return "" }
137
185
  try {
@@ -306,9 +354,16 @@ if ($activeItem -and -not (Test-SafeActiveFile)) {
306
354
  $utf8NoBom = New-Object System.Text.UTF8Encoding($false)
307
355
  # Replace the directory entry instead of truncating an existing inode: a
308
356
  # hardlinked pointer must not overwrite another file. The exclusive temporary
309
- # file lives beside the pointer, keeping replacement on the same filesystem.
310
- $tempFile = Join-Path $PlanRoot ('.active_plan.' + [guid]::NewGuid().ToString('N') + '.tmp')
357
+ # file and caller-owned backup live beside the pointer, keeping replacement on
358
+ # the same filesystem. Naming the backup prevents ReplaceFile from inventing
359
+ # an unowned ~RF*.TMP path if its final rename fails.
360
+ $operationId = [guid]::NewGuid().ToString('N')
361
+ $tempFile = Join-Path $PlanRoot ('.active_plan.' + $operationId + '.tmp')
362
+ $backupFile = Join-Path $PlanRoot ('.active_plan.' + $operationId + '.replace-backup')
311
363
  $createdTemp = $false
364
+ $failureMessage = ""
365
+ $backupResolved = $true
366
+ $replaced = $false
312
367
  try {
313
368
  $stream = [IO.File]::Open($tempFile, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None)
314
369
  $createdTemp = $true
@@ -325,24 +380,40 @@ try {
325
380
  if (-not (Test-SafeActiveFile)) {
326
381
  throw [InvalidOperationException]::new("the active plan pointer became unsafe during replacement")
327
382
  }
328
- [IO.File]::Replace($tempFile, $ActiveFile, [NullString]::Value)
383
+ [IO.File]::Replace($tempFile, $ActiveFile, $backupFile)
329
384
  } else {
330
385
  [IO.File]::Move($tempFile, $ActiveFile)
331
386
  }
387
+ $replaced = $true
332
388
  break
333
389
  } catch [IO.IOException] {
390
+ if (-not (Resolve-OwnedPointerBackup -BackupFile $backupFile)) {
391
+ throw [IO.IOException]::new("could not safely recover the active plan pointer after replacement failure")
392
+ }
334
393
  if ($attempt -eq $maxAttempts) { throw }
335
394
  Start-Sleep -Milliseconds 25
336
395
  }
337
396
  }
338
397
  } catch {
339
- Write-Error "Error: could not set the active plan pointer: $($_.Exception.Message)"
340
- exit 1
398
+ $failureMessage = $_.Exception.Message
341
399
  } finally {
400
+ if (-not (Resolve-OwnedPointerBackup -BackupFile $backupFile -ReplaceSucceeded:$replaced)) {
401
+ # The pointer was written; a leftover backup is clutter, not failure.
402
+ if ($replaced) { Write-Warning "could not remove the replacement backup $backupFile" }
403
+ else { $backupResolved = $false }
404
+ }
342
405
  if ($createdTemp -and (Test-Path -LiteralPath $tempFile)) {
343
406
  Remove-Item -LiteralPath $tempFile -Force -ErrorAction SilentlyContinue
344
407
  }
345
408
  }
409
+ if (-not $backupResolved) {
410
+ Write-Error "Error: could not safely recover the active plan pointer backup."
411
+ exit 1
412
+ }
413
+ if ($failureMessage) {
414
+ Write-Error "Error: could not set the active plan pointer: $failureMessage"
415
+ exit 1
416
+ }
346
417
  Write-Output "Active plan set to: $PlanId"
347
418
  Write-Output "Path: $PlanDir"
348
419
  Write-Output ""