planning-with-files 3.20.7 → 3.22.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.22.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.22.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.22.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.22.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.22.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.22.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.22.0/media/pwf-context-story-v1.mp4"><img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.22.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.22.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.22.0/docs/installation.md) | Plugin + SKILL.md + Hooks |
156
+ | Cursor | [Cursor Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.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.22.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.22.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.22.0/docs/gemini.md) | Skills + [Hooks](https://geminicli.com/docs/hooks/) |
160
+ | Kiro | [Kiro Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/kiro.md) | [Agent Skills](https://kiro.dev/docs/skills/) |
161
+ | Codex | [Codex Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.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.22.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.22.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.22.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.22.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.22.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.22.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.22.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.22.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.22.0/docs/autohand.md) | `~/.autohand/skills/` or `.autohand/skills/` |
179
+ | Antigravity | [Antigravity Setup](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.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.22.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.22.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.22.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.22.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,9 @@ 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.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). |
242
+ | **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). |
243
+ | **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
244
  | **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
245
  | **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
246
  | **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 +329,7 @@ One hook fire measures 289ms wall-clock since the v3.6.0 optimization, down from
326
329
  | **v2.7.0** | Gemini CLI support |
327
330
  | **v2.2.0** | Session recovery, Windows PowerShell, OS-aware hooks |
328
331
 
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)
332
+ [View all releases](https://github.com/OthmanAdi/planning-with-files/releases) · [CHANGELOG](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/CHANGELOG.md)
330
333
 
331
334
  > 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
335
 
@@ -364,7 +367,7 @@ One hook fire measures 289ms wall-clock since the v3.6.0 optimization, down from
364
367
 
365
368
  *Built something? [Open an issue](https://github.com/OthmanAdi/planning-with-files/issues) to get listed!*
366
369
 
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).
370
+ Full list of everyone who made this project better: [CONTRIBUTORS.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/CONTRIBUTORS.md).
368
371
 
369
372
  </details>
370
373
 
@@ -384,7 +387,7 @@ Full list of everyone who made this project better: [CONTRIBUTORS.md](https://gi
384
387
  | 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
388
  | Hooks that quietly stop firing | `/plan-doctor` self-checks resolution, injection, attestation, install surfaces and per-fire latency |
386
389
 
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).
390
+ 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.22.0/docs/long-running-agent-tasks.md).
388
391
 
389
392
  ### Installation routes
390
393
 
@@ -455,7 +458,7 @@ What each route actually ships:
455
458
  | DeepSeek Harness `dsh plugin add` | yes, with the skill | **yes**, `/pwf`, `/pwf-status` | **yes**, plugin hooks incl. the gate |
456
459
  | ClawHub / manual copy | yes | no | frontmatter hooks, see note |
457
460
 
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).
461
+ 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.22.0/docs/installation.md#what-each-install-route-actually-ships).
459
462
 
460
463
  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
464
 
@@ -472,7 +475,7 @@ One skill, three integration tiers. Know what your agent gets before you install
472
475
 
473
476
  | Tier | Platforms | What you get |
474
477
  |------|-----------|--------------|
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 |
478
+ | **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
479
  | **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
480
  | **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
481
 
@@ -492,7 +495,7 @@ Per-platform setup guides, discovery paths and sandbox runtimes are in the colla
492
495
  - **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
496
  - **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
497
 
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).
498
+ 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.22.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.22.0/docs/long-running-agent-tasks.md).
496
499
 
497
500
  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
501
 
@@ -533,7 +536,7 @@ Optional gated mode can request continuation only on a host that supports the re
533
536
 
534
537
  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
538
 
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/).
539
+ Maintainer depth (hook architecture, dispatcher layout, parity tooling) lives in [AGENTS.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/AGENTS.md) and [docs/](https://github.com/OthmanAdi/planning-with-files/tree/v3.22.0/docs/).
537
540
 
538
541
  ## Commands
539
542
 
@@ -697,12 +700,12 @@ Everything below is the proof and the reference half: the benchmarks and their l
697
700
 
698
701
  ## Benchmark Results
699
702
 
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).
703
+ > **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.22.0/docs/evals.md).
701
704
 
702
705
  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
706
 
704
707
  <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">
708
+ <img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.22.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
709
  </p>
707
710
 
708
711
  | Test | with_skill | without_skill |
@@ -714,17 +717,17 @@ Evaluated with Anthropic's [skill-creator](https://github.com/anthropics/skills/
714
717
 
715
718
  ### Recovery after a context wipe
716
719
 
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).
720
+ > **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.22.0/docs/evals.md#test-5-competitive-benchmark-v1-seven-planning-methods-head-to-head-2026-07-06-internal).
718
721
 
719
722
  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
723
 
721
724
  <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">
725
+ <img src="https://raw.githubusercontent.com/OthmanAdi/planning-with-files/v3.22.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
726
  </p>
724
727
 
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)).
728
+ **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.22.0/docs/benchmark/index.html) ([rendered view](https://htmlpreview.github.io/?https://github.com/OthmanAdi/planning-with-files/blob/master/docs/benchmark/index.html)).
726
729
 
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)
730
+ [Full methodology and results](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/evals.md) · [Technical write-up](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/article.md)
728
731
 
729
732
  ## File Structure
730
733
 
@@ -762,25 +765,25 @@ Every release maintains 20 tracked parity targets plus the gitignored ClawHub up
762
765
 
763
766
  | Doc | What it covers |
764
767
  |-----|----------------|
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) |
768
+ | [docs/installation.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/installation.md) | Every install route, the route matrix, the trust prerequisite |
769
+ | [docs/quickstart.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/quickstart.md) | Your first planning session in 5 steps |
770
+ | [docs/workflow.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/workflow.md) | Day-to-day usage, plan lifecycle, topic handoffs |
771
+ | [docs/hermes.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/hermes.md) | Hermes Agent CLI and Desktop: install, `/pwf`, the `pre_verify` gate, Windows, migration from Claude Code |
772
+ | [docs/opencode.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/opencode.md) | OpenCode: the native plugin, `/pwf`, the `session.idle` gate, `pwf_*` tools |
773
+ | [docs/deepseek-harness.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/deepseek-harness.md) | DeepSeek Harness: the native plugin, profiles, `/pwf`, the turn-boundary gate, what DSH does not expose |
774
+ | [docs/evals.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/evals.md) | Full benchmark methodology, raw numbers, disclosed limits |
775
+ | [docs/troubleshooting.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/troubleshooting.md) | When hooks are quiet, plus `/plan-doctor` |
776
+ | [docs/claude-code-lost-context-after-compaction.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/claude-code-lost-context-after-compaction.md) | Recovering and preventing context loss from compaction |
777
+ | [docs/agent-forgets-plan-after-clear.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/agent-forgets-plan-after-clear.md) | The file-based fix when an agent forgets its plan after `/clear` |
778
+ | [docs/long-running-agent-tasks.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/docs/long-running-agent-tasks.md) | Keeping a coding agent on track for hours: modes, gate, ledger |
779
+ | [MIGRATION.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/MIGRATION.md) | v2 to v3 migration and host capability tiers |
780
+ | [SECURITY.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/SECURITY.md) | Vulnerability reporting and hardening history |
781
+ | [CONTRIBUTING.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.0/CONTRIBUTING.md) | How to contribute; authorship is preserved on merge |
782
+ | Per-platform guides | 19+ setup docs in [docs/](https://github.com/OthmanAdi/planning-with-files/tree/v3.22.0/docs/), linked from the [platform tables](#works-across-19-platforms) |
780
783
 
781
784
  ## Contributing
782
785
 
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.
786
+ Contributions welcome. Start with [CONTRIBUTING.md](https://github.com/OthmanAdi/planning-with-files/blob/v3.22.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.22.0/CONTRIBUTORS.md), the CHANGELOG Thanks section, and the release notes.
784
787
 
785
788
  ## License
786
789
 
@@ -802,7 +805,7 @@ MIT License — feel free to use, modify, and distribute.
802
805
 
803
806
  ## Contributors
804
807
 
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).
808
+ 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.22.0/CONTRIBUTORS.md).
806
809
 
807
810
  <!-- contributor-portraits:start -->
808
811
  <p align="center">
@@ -820,6 +823,8 @@ Code, documentation, and issue contributors. Select a portrait to open a GitHub
820
823
  <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
824
  <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
825
  <a href="https://github.com/bailob" title="@bailob"><img src="https://github.com/bailob.png?size=56" width="48" height="48" alt="@bailob"></a>
826
+ <a href="https://github.com/SomSamantray" title="@SomSamantray"><img src="https://github.com/SomSamantray.png?size=56" width="48" height="48" alt="@SomSamantray"></a>
827
+ <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
828
  <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
829
  <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
830
  <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 +853,7 @@ Code, documentation, and issue contributors. Select a portrait to open a GitHub
848
853
  <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
854
  <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
855
  <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>
856
+ <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.22.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
857
  <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
858
  <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
859
  <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 +886,6 @@ Code, documentation, and issue contributors. Select a portrait to open a GitHub
881
886
  <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
887
  <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
888
  <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>
889
+ <a href="https://github.com/OthmanAdi/planning-with-files/blob/v3.22.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
890
  </p>
886
891
  <!-- 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.22.0"
32
32
  ---
33
33
 
34
34
  # Planning with Files
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planning-with-files",
3
- "version": "3.20.7",
3
+ "version": "3.22.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 ""