context-planning 0.7.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.
Files changed (86) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +454 -0
  3. package/bin/commands/_helpers.js +53 -0
  4. package/bin/commands/_usage.js +67 -0
  5. package/bin/commands/capture.js +46 -0
  6. package/bin/commands/codebase-status.js +41 -0
  7. package/bin/commands/complete-milestone.js +57 -0
  8. package/bin/commands/config.js +70 -0
  9. package/bin/commands/doctor.js +139 -0
  10. package/bin/commands/gsd-import.js +90 -0
  11. package/bin/commands/inbox.js +81 -0
  12. package/bin/commands/index.js +33 -0
  13. package/bin/commands/init.js +87 -0
  14. package/bin/commands/install.js +43 -0
  15. package/bin/commands/scaffold-codebase.js +53 -0
  16. package/bin/commands/scaffold-milestone.js +58 -0
  17. package/bin/commands/scaffold-phase.js +65 -0
  18. package/bin/commands/status.js +42 -0
  19. package/bin/commands/statusline.js +108 -0
  20. package/bin/commands/tick.js +49 -0
  21. package/bin/commands/version.js +9 -0
  22. package/bin/commands/worktree.js +218 -0
  23. package/bin/commands/write-summary.js +54 -0
  24. package/bin/cp.cmd +2 -0
  25. package/bin/cp.js +54 -0
  26. package/commands/cp/capture.md +107 -0
  27. package/commands/cp/complete-milestone.md +166 -0
  28. package/commands/cp/execute-phase.md +220 -0
  29. package/commands/cp/map-codebase.md +211 -0
  30. package/commands/cp/new-milestone.md +136 -0
  31. package/commands/cp/new-project.md +132 -0
  32. package/commands/cp/plan-phase.md +195 -0
  33. package/commands/cp/progress.md +147 -0
  34. package/commands/cp/quick.md +104 -0
  35. package/commands/cp/resume.md +125 -0
  36. package/commands/cp/write-summary.md +33 -0
  37. package/docs/MIGRATION-v0.5.md +140 -0
  38. package/docs/architecture.md +189 -0
  39. package/docs/superpowers/plans/2026-05-20-v0-7-plan-16-01-design-md-infrastructure.md +1064 -0
  40. package/docs/superpowers/plans/2026-05-20-v0-7-plan-16-02-review-log-infrastructure.md +418 -0
  41. package/docs/superpowers/plans/2026-05-20-v0-7-plan-16-03-key-decisions-hard-block.md +295 -0
  42. package/docs/superpowers/specs/2026-05-20-generic-provider-harness-detection-design.md +380 -0
  43. package/docs/superpowers/specs/2026-05-20-v0-7-design-capture-design.md +400 -0
  44. package/docs/writing-providers.md +76 -0
  45. package/install/aider.js +204 -0
  46. package/install/claude.js +116 -0
  47. package/install/common.js +65 -0
  48. package/install/copilot.js +86 -0
  49. package/install/cursor.js +120 -0
  50. package/install/echo-provider.js +50 -0
  51. package/lib/codebase-mapper.js +169 -0
  52. package/lib/detect.js +280 -0
  53. package/lib/frontmatter.js +72 -0
  54. package/lib/gsd-compat.js +165 -0
  55. package/lib/import.js +543 -0
  56. package/lib/inbox.js +226 -0
  57. package/lib/lifecycle.js +929 -0
  58. package/lib/merge.js +157 -0
  59. package/lib/milestone.js +595 -0
  60. package/lib/paths.js +191 -0
  61. package/lib/provider.js +168 -0
  62. package/lib/roadmap.js +134 -0
  63. package/lib/state.js +99 -0
  64. package/lib/worktree.js +253 -0
  65. package/package.json +45 -0
  66. package/templates/DESIGN.md +78 -0
  67. package/templates/INBOX.md +13 -0
  68. package/templates/MILESTONE-CONTEXT.md +40 -0
  69. package/templates/MILESTONES.md +29 -0
  70. package/templates/PLAN.md +84 -0
  71. package/templates/PROJECT.md +43 -0
  72. package/templates/REVIEW-LOG.md +38 -0
  73. package/templates/ROADMAP.md +34 -0
  74. package/templates/STATE.md +78 -0
  75. package/templates/SUMMARY.md +75 -0
  76. package/templates/codebase/ARCHITECTURE.md +30 -0
  77. package/templates/codebase/CONCERNS.md +30 -0
  78. package/templates/codebase/CONVENTIONS.md +30 -0
  79. package/templates/codebase/INTEGRATIONS.md +30 -0
  80. package/templates/codebase/STACK.md +26 -0
  81. package/templates/codebase/STRUCTURE.md +32 -0
  82. package/templates/codebase/TESTING.md +39 -0
  83. package/templates/config.json +173 -0
  84. package/templates/phase-PLAN.md +32 -0
  85. package/templates/quick-PLAN.md +24 -0
  86. package/templates/quick-SUMMARY.md +25 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 shushenglihotmail and contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,454 @@
1
+ # context-planning (`cplan` / `cp`)
2
+
3
+ > **GSD's brain. Superpowers' hands.**
4
+ > A lightweight, harness-agnostic plugin that keeps long-lived AI development
5
+ > work — milestones, phases, plans, summaries — coherent across sessions, while
6
+ > handing the actual "how do I write this code" workflow to whatever
7
+ > coding-agent skill set you already use.
8
+
9
+ [![ci](https://github.com/shushenglihotmail/context-planning/actions/workflows/ci.yml/badge.svg)](https://github.com/shushenglihotmail/context-planning/actions/workflows/ci.yml)
10
+ [![tests](https://img.shields.io/badge/tests-751%20passing-brightgreen)]()
11
+ [![node](https://img.shields.io/badge/node-%E2%89%A518-blue)]()
12
+ [![license](https://img.shields.io/badge/license-MIT-blue)]()
13
+
14
+ > **CLI binary names:** as of v0.6 the canonical command is **`cplan`**.
15
+ > The original short name **`cp`** still works on every platform.
16
+ > PowerShell users — Windows ships `cp` as an alias for `Copy-Item`, so
17
+ > bare `cp` may not resolve to our binary unless you `Remove-Alias cp`.
18
+ > Use `cplan` to avoid the clash entirely. Examples below show both.
19
+
20
+ ---
21
+
22
+ ## TL;DR
23
+
24
+ ```text
25
+ You ──▶ /cp-new-milestone "v0.2 Auth" (state layer: cp)
26
+ ├─▶ /cp-plan-phase 1 (workflow: superpowers/brainstorming + writing-plans)
27
+ ├─▶ /cp-execute-phase 1 (workflow: superpowers/subagent-driven-development)
28
+ └─▶ /cp-complete-milestone (state layer: cp aggregates, archives, resets)
29
+ ```
30
+
31
+ `cp` owns the *project state docs* in `.planning/` (PROJECT.md / ROADMAP.md /
32
+ STATE.md / phase dirs / MILESTONES.md). It delegates the *workflow* — how to
33
+ brainstorm, plan, code, review, test — to a configurable provider, defaulting
34
+ to **[Superpowers](https://github.com/obra/superpowers)**. Falls back to a
35
+ built-in `manual` provider if Superpowers isn't installed.
36
+
37
+ ## Why?
38
+
39
+ | Pain | Existing tool | What `cp` does |
40
+ |---|---|---|
41
+ | **GSD** has great stateful context management but its workflow pipeline is heavy (60+ commands, 30+ subagents, multi-stage gates). | [get-shit-done](https://github.com/gsd-build/get-shit-done) | Keeps GSD's `.planning/` shapes; throws away everything else. |
42
+ | **Superpowers** has a fast brainstorm → plan → TDD-execute → review → ship loop but doesn't track multi-week project state. | [obra/superpowers](https://github.com/obra/superpowers) | Stitches in superpowers skills as the workflow engine, called by *role*, not by name. |
43
+ | Restarting an LLM session loses everything you were working on. | — | Reads `STATE.md` + `.continue-here.md` → `/cp-resume` picks up exactly where you were. |
44
+
45
+ **Net result:** ~8 commands, the markdown state docs you already love, and
46
+ every "do the work" step hands off to whatever skill set you have installed.
47
+
48
+ ## Install
49
+
50
+ ### Node CLI
51
+
52
+ ```bash
53
+ git clone https://github.com/yourname/context-planning
54
+ cd context-planning
55
+ npm install # only dep: yaml
56
+ npm test # 328 assertions; should all pass
57
+ npm link # exposes BOTH `cplan` and `cp` on PATH (or use: node bin/cp.js ...)
58
+ ```
59
+
60
+ ### Into an AI harness
61
+
62
+ ```bash
63
+ cd <your-project>
64
+ cp install copilot # writes .github/skills/cp/*.md + .github/agents/*.md
65
+ cp install claude # writes .claude/commands/cp/*.md + .claude/agents/*.md + CLAUDE.md merge
66
+ ```
67
+
68
+ Then ensure your provider is available in the same harness:
69
+
70
+ - **Superpowers** (recommended): see https://github.com/obra/superpowers
71
+ - **Manual** (no extra install): cp ships full inline prompts for every role.
72
+
73
+ ### Initialise a project
74
+
75
+ ```bash
76
+ cd <your-project>
77
+ cp init # idempotent — adds .planning/{PROJECT,ROADMAP,STATE,MILESTONES,config}.json
78
+ ```
79
+
80
+ If the dir is already a GSD project, `cp init` is purely additive: it writes a
81
+ `cp:` block into the existing `config.json` and leaves every GSD file alone.
82
+
83
+ ## Worked example — the **linkmark** demo
84
+
85
+ The repo ships a driver script (`drive-cp.js`, not committed) that walks a
86
+ fresh project through a full milestone lifecycle, simulating every slash
87
+ command by calling `cp` lib functions directly. Here's what it produces:
88
+
89
+ ```text
90
+ .planning/
91
+ ├── PROJECT.md # linkmark vision + constraints (cp-new-project)
92
+ ├── ROADMAP.md # v0.1 MVP with 2 phases, 3 plans, all ticked done
93
+ ├── STATE.md # "Idle, ready for v0.2" after close-out
94
+ ├── MILESTONES.md # auto-generated digest of shipped milestone
95
+ ├── config.json # cp block + provider config
96
+ └── phases/
97
+ ├── 01-foundation/
98
+ │ ├── PLAN.md # phase plan
99
+ │ ├── 01-01-storage.md # per-plan files
100
+ │ ├── 01-01-SUMMARY.md # written on execute completion
101
+ │ ├── 01-02-list.md
102
+ │ └── 01-02-SUMMARY.md
103
+ └── 02-search/
104
+ ├── PLAN.md
105
+ ├── 02-01-search.md
106
+ └── 02-01-SUMMARY.md
107
+ ```
108
+
109
+ After `/cp-complete-milestone` runs, `ROADMAP.md` collapses the milestone into
110
+ a `<details>` block:
111
+
112
+ ```markdown
113
+ ## Phases
114
+
115
+ <details>
116
+ <summary>✅ v0.1 MVP (Phases 1-2) — SHIPPED 2026-05-19</summary>
117
+
118
+ Goal: ship a usable CLI that can add, list, and search bookmarks.
119
+
120
+ ### Phase 1: Foundation
121
+ - [x] 01-01: storage + add
122
+ - [x] 01-02: list command
123
+
124
+ ### Phase 2: Search
125
+ - [x] 02-01: search command
126
+
127
+ </details>
128
+ ```
129
+
130
+ …and `MILESTONES.md` gets an auto-generated digest with subsystems,
131
+ decisions, patterns, and files touched — aggregated across every SUMMARY.md.
132
+
133
+ ## Command surface
134
+
135
+ ### Slash commands (live inside your AI harness)
136
+
137
+ | Command | Stateful work cp does | Workflow handoff |
138
+ |---|---|---|
139
+ | `/cp-new-project` | Scaffold `.planning/`, seed PROJECT.md/ROADMAP.md/STATE.md | `brainstorm` → fill in vision/constraints |
140
+ | `/cp-new-milestone <name>` | Append milestone shell to ROADMAP, write MILESTONE-CONTEXT.md | `brainstorm` → spec the milestone → break into phases |
141
+ | `/cp-plan-phase <N>` | Create `phases/{NN-slug}/`, scaffold `PLAN.md` | `plan` → produce per-plan files |
142
+ | `/cp-execute-phase <N>` | For each plan: hand off, on success tick ROADMAP, write SUMMARY.md, update STATE.md | `execute` → write & verify code |
143
+ | `/cp-quick <task>` | Create `quick/{YYYYMMDD-slug}/PLAN.md`, atomic-commit on done | `execute_simple` → quick fix |
144
+ | `/cp-progress` | Read STATE + ROADMAP → "you are here, next is X" | — |
145
+ | `/cp-resume` | Restore from `.continue-here.md` + STATE | `execute` or whatever role was paused |
146
+ | `/cp-complete-milestone` | Verify all phases done, aggregate SUMMARY frontmatter, append digest to MILESTONES.md, collapse milestone in ROADMAP, clear MILESTONE-CONTEXT.md, reset STATE | — |
147
+ | `/cp-map-codebase` | Scaffold `.planning/codebase/` (7 GSD-compatible docs: STACK, INTEGRATIONS, ARCHITECTURE, STRUCTURE, CONVENTIONS, TESTING, CONCERNS); dispatch 4 parallel sub-agents to fill them. **cp-native** — no provider required. | Harness sub-agent dispatch (Copilot CLI `task` / Claude `Task` tool) |
148
+ | `/cp-capture` | Walk `.planning/INBOX.md` open items and route each to a quick task / phase note / seed / discard. cp tracks state; harness performs the routing edits. **cp-native** — no provider required for capture/list/tick. | Harness-driven routing; optional provider for `quick:*` items |
149
+
150
+ ### Node CLI (operational tooling — not used inside the AI loop)
151
+
152
+ ```bash
153
+ cp install <copilot|claude|cursor|aider> # Install slash-commands + agents into a harness
154
+ cp init # Scaffold .planning/ (idempotent; safe over GSD projects)
155
+ cp doctor # Show resolved config, provider status, GSD compat report
156
+ cp gsd-import [--root <dir>] [--json] [--apply]
157
+ # Read-only audit of any planning project (cp or GSD).
158
+ # exit 0 = clean, 1 = errors, 2 = changes pending
159
+ cp status [--json] # "You are here": current milestone, phase, next plan
160
+ cp scaffold-milestone <name> [--planned] [--no-commit] [--dry-run]
161
+ # Add `### 🚧 <name> (In Progress)` heading to
162
+ # ROADMAP `## Phases` section. Refuses duplicates.
163
+ # Use --planned for `### 📋 <name> (Planned)`.
164
+ cp scaffold-phase <N> --name <name> [--plans <count>] [--milestone <name>] [--no-commit] [--dry-run]
165
+ # Add `### Phase N: <name>` under the active
166
+ # milestone in ROADMAP + create
167
+ # .planning/phases/{NN-slug}/PLAN.md from
168
+ # template. --plans pre-fills N empty
169
+ # `- [ ] NN-MM` checkboxes.
170
+ cp scaffold-codebase [--force] [--no-commit] [--dry-run]
171
+ # Create .planning/codebase/ with 7 stub docs
172
+ # (STACK, INTEGRATIONS, ARCHITECTURE, STRUCTURE,
173
+ # CONVENTIONS, TESTING, CONCERNS) matching GSD's
174
+ # layout exactly. Filled by `/cp-map-codebase`.
175
+ # Refuses to overwrite without --force.
176
+ cp codebase-status [--json] # Inventory .planning/codebase/: which docs
177
+ # exist, line counts, which still look like
178
+ # stubs (heuristic: <=40 lines OR contains
179
+ # the "/cp-map-codebase" placeholder marker).
180
+ cp capture "<text>" [--no-commit]
181
+ # Append a free-form line to .planning/INBOX.md
182
+ # under `## Open` with an ISO-minute timestamp.
183
+ # Auto-commits scoped to INBOX.md only.
184
+ cp inbox [--json] [--all] [--tick <N> [--note <dest>]] [--no-commit]
185
+ # List the inbox (Open by default; --all adds
186
+ # Triaged). `--tick N` moves open item N to
187
+ # Triaged with an optional `--note` destination
188
+ # tag (e.g. `quick:rename`, `phase:02-mvp`,
189
+ # `seed:routing-redesign`, `discard`).
190
+ cp statusline [--format <fmt>] [--json] [--no-color]
191
+ # Print a one-line prompt-friendly status string
192
+ # (e.g. `cp ▸ v0.5 ▸ 01-mvp 1/3 ▸ 01-02`).
193
+ # Silent outside a cp project. Tokens: %M
194
+ # (milestone), %P (phase slug), %D (done/total),
195
+ # %N (next plan id), %B (branch).
196
+ cp worktree create <name> [--branch <b>] [--from <base>] [--path <dir>] [--phase <N>] [--use-provider] [--no-create]
197
+ # Run `git worktree add <path> -b cp/<slug>`
198
+ # and record in .planning/WORKTREES.md. With
199
+ # --use-provider, delegates to the configured
200
+ # provider's worktree skill (Superpowers:
201
+ # using-git-worktrees) instead of running git
202
+ # directly.
203
+ cp worktree list [--json] # List cp-tracked worktrees, cross-referenced
204
+ # against `git worktree list --porcelain`.
205
+ cp worktree remove <slug> [--force] [--no-commit]
206
+ # `git worktree remove` + drop the registry
207
+ # entry. Refuses if git refuses (dirty
208
+ # worktree) unless --force.
209
+ cp tick <plan-id> [--undo] [--no-commit] [--dry-run]
210
+ # Mark a plan done in ROADMAP + phase PLAN.md.
211
+ # Idempotent. Commits unless --no-commit.
212
+ cp write-summary <plan-id> --from <json> [--body <md>] [--overwrite] [--dry-run]
213
+ # Write {NN-MM}-SUMMARY.md with validated/normalised
214
+ # frontmatter. Accepts kebab-case OR snake_case keys
215
+ # and normalises to the canonical kebab-case names
216
+ # aggregateSummaries reads.
217
+ cp complete-milestone [<name>] [--dry-run] [--no-commit] [--json]
218
+ # Full close-out: verify all phases done → aggregate
219
+ # SUMMARYs → render digest → append to MILESTONES.md
220
+ # → collapse milestone in ROADMAP → clear
221
+ # MILESTONE-CONTEXT.md → reset STATE → commit.
222
+ # Use --dry-run to preview the actions list.
223
+ cp config get [<key>] # Print a cp config value (or the whole cp block)
224
+ cp config set <key> <value> # Update cp.<key>
225
+ cp version # Print version
226
+ cp help # Show command summary
227
+ ```
228
+
229
+ The lifecycle wrappers (`status`, `tick`, `write-summary`,
230
+ `complete-milestone`) exist so that the LLM-driven slash commands and your
231
+ own scripts never have to learn the underlying lib contracts (SUMMARY
232
+ filename format, frontmatter aliases, descriptor-object return shapes,
233
+ etc.). See [Troubleshooting](#troubleshooting) for the contract details
234
+ they hide.
235
+
236
+ ## State layer
237
+
238
+ ```
239
+ .planning/
240
+ ├── PROJECT.md # Living what/why/requirements/constraints/decisions
241
+ ├── ROADMAP.md # Milestones → phases → plans tree (checkboxes)
242
+ ├── STATE.md # <120-line "you are here" digest
243
+ ├── MILESTONES.md # Archive of shipped milestones (GSD-compatible)
244
+ ├── MILESTONE-CONTEXT.md # Transient: current milestone spec (deleted on close)
245
+ ├── config.json # Shared GSD+cp config (cp settings under `cp:` key)
246
+ ├── phases/
247
+ │ └── 01-foundation/
248
+ │ ├── PLAN.md # Phase-level plan (cp-friendly short form)
249
+ │ ├── 01-01-PLAN.md # GSD-shape per-plan file: {phase}-{plan}-PLAN.md
250
+ │ └── 01-01-SUMMARY.md # written on execute completion
251
+ └── quick/
252
+ └── 20260519-fix-login-test/
253
+ ├── PLAN.md
254
+ └── SUMMARY.md
255
+ ```
256
+
257
+ `.continue-here.md` is written inside the active phase dir when work is
258
+ paused (`/cp-pause` or LLM session ends mid-execute). `/cp-resume` reads it.
259
+
260
+ ## Provider abstraction
261
+
262
+ `cp` calls workflow providers by **role**, not by name, so users can swap
263
+ implementations without touching `cp` itself.
264
+
265
+ ```jsonc
266
+ // .planning/config.json — cp block
267
+ {
268
+ // ... GSD-compatible top-level keys (mode, workflow, gates, ...) ...
269
+ "cp": {
270
+ "workflow_provider": "superpowers",
271
+ "providers": {
272
+ "superpowers": {
273
+ "skills": {
274
+ "brainstorm": "brainstorming",
275
+ "plan": "writing-plans",
276
+ "execute": "subagent-driven-development",
277
+ "execute_simple": "executing-plans",
278
+ "review": "requesting-code-review",
279
+ "receive_review": "receiving-code-review",
280
+ "finish": "finishing-a-development-branch",
281
+ "worktree": "using-git-worktrees",
282
+ "tdd": "test-driven-development",
283
+ "debug": "systematic-debugging",
284
+ "verify": "verification-before-completion"
285
+ }
286
+ },
287
+ "manual": { "skills": { /* full inline prompts for each role */ } }
288
+ },
289
+ "behavior": {
290
+ "atomic_commits": true,
291
+ "fall_back_to_manual_if_provider_missing": true,
292
+ "gsd_compat_mode": true
293
+ }
294
+ }
295
+ }
296
+ ```
297
+
298
+ Swap providers with `cp config set workflow_provider <name>`. Missing skill?
299
+ `cp doctor` flags it, and at runtime `cp` warns and falls back to `manual`.
300
+
301
+ Want to write your own? See [`docs/writing-providers.md`](docs/writing-providers.md).
302
+
303
+ ## GSD compatibility
304
+
305
+ `cp` is a **drop-in superset** of [get-shit-done](https://github.com/gsd-build/get-shit-done).
306
+
307
+ | Concern | What cp does |
308
+ |---|---|
309
+ | **Filenames** | Same: `PROJECT.md`, `ROADMAP.md`, `STATE.md`, `MILESTONES.md`, `MILESTONE-CONTEXT.md`, `phases/{NN-slug}/{phase}-{plan}-PLAN.md`, `quick/{YYYYMMDD-slug}/PLAN.md`. |
310
+ | **Frontmatter** | Same field names: `wave`, `depends_on`, `requirements`, `must_haves.*` for PLAN; `requires`/`provides`/`affects`, `subsystem`, `tags`, `tech-stack`, `key-files`, `key-decisions`, `patterns-established`, `requirements-completed` for SUMMARY. |
311
+ | **Config** | Same file (`.planning/config.json`). cp keys live under the `cp:` top-level block; GSD ignores unknown keys. |
312
+ | **Round-trip** | `cp` only ADDS to `.planning/` (new cp block, milestone bullets, ticked checkboxes). It never rewrites GSD-shape files in incompatible ways. |
313
+ | **Audit** | `cp gsd-import` classifies any project (none / pure-GSD / cp-aware / cp-aware-GSD-superset) and reports exactly what `cp init` would change. Read-only by default. |
314
+
315
+ You can switch back to GSD at any time. Run `cp doctor` to see the live
316
+ compatibility report.
317
+
318
+ > **Status:** format parity with GSD is a hard contract while cp is in
319
+ > active development. Long-term, cp may evolve its own conventions, but
320
+ > only after we've documented a migration path.
321
+
322
+ ## Architecture
323
+
324
+ ```
325
+ bin/cp.js # CLI entry: install / init / doctor / config / gsd-import
326
+ install/
327
+ copilot.js # writes .github/skills/cp/*.md + .github/agents/*.md
328
+ claude.js # writes .claude/commands/cp/*.md + idempotent CLAUDE.md merge
329
+ commands/cp/ # harness-agnostic slash-command markdown (9 commands)
330
+ lib/
331
+ frontmatter.js # YAML frontmatter read/write (yaml dep, parseError on bad input)
332
+ roadmap.js # ROADMAP traversal: listPhases, setPlanDone, appendPhaseBlock
333
+ state.js # STATE.md "Current Position" updater
334
+ paths.js # phase dir / SUMMARY filename resolution (GSD conventions)
335
+ milestone.js # close-out: verify, aggregate, render digest, collapse milestone
336
+ provider.js # role → skill resolution with installed-check + fallback
337
+ gsd-compat.js # detect/classify pure-GSD vs cp-aware vs GSD-superset
338
+ import.js # read-only auditor (74-test fixture suite)
339
+ templates/ # PROJECT/ROADMAP/STATE/MILESTONES seeds
340
+ test/ # 6 test files, 328 assertions, plain Node (no test runner)
341
+ docs/
342
+ architecture.md
343
+ writing-providers.md
344
+ ```
345
+
346
+ ## Troubleshooting
347
+
348
+ **`cp doctor` says provider not installed.**
349
+ Either install Superpowers in the same harness, or `cp config set
350
+ workflow_provider manual` to use the built-in inline prompts.
351
+
352
+ **`cp gsd-import` returns exit code 1 (errors).**
353
+ Frontmatter parse failure or required GSD/cp file missing. Run with
354
+ `--json` to see the structured report; the offending file is listed under
355
+ `issues[*].file`.
356
+
357
+ **`/cp-complete-milestone` fails with `summariesMissing: ['01-01']`.**
358
+ `cp` looks for `{NN-MM}-SUMMARY.md` in each phase dir (e.g.
359
+ `01-01-SUMMARY.md`). If your executor writes `01-01-storage-SUMMARY.md`
360
+ (slug in the middle), rename without the slug.
361
+
362
+ **`fs.writeFileSync` `ERR_INVALID_ARG_TYPE` when calling lib functions.**
363
+ Several lib functions return `{content, changed, reason}` descriptor
364
+ objects, not raw strings. Always use `.content` before writing:
365
+ `fs.writeFileSync(p, milestone.collapseMilestoneInRoadmap(...).content)`.
366
+
367
+ **`/cp-resume` jumps to the wrong plan.**
368
+ Check STATE.md's "Session Continuity" section — `Resume file:` should point
369
+ to `.continue-here.md` inside the phase dir, not the project root.
370
+ `cp` normalises plan IDs (`02` vs `"02"`) when computing the next plan.
371
+
372
+ ## Roadmap
373
+
374
+ **v0.1 (current)** — vertical slice for GitHub Copilot CLI: 9 slash commands
375
+ (`new-project`, `new-milestone`, `plan-phase`, `execute-phase`, `quick`,
376
+ `progress`, `resume`, `complete-milestone`, `config`), Claude installer,
377
+ manual provider with 11 inline role prompts.
378
+
379
+ **v0.2 (shipped)** — CLI lifecycle wrappers (`cp status`, `cp tick`,
380
+ `cp write-summary`, `cp complete-milestone`) so slash-command implementations
381
+ and external scripts never touch the lib contracts directly. 394 tests,
382
+ end-to-end smoke tested on the `linkmark` demo + `cp-cli-smoke` fixture.
383
+
384
+ **v0.3 (shipped)** — Scaffolding wrappers (`cp scaffold-milestone`,
385
+ `cp scaffold-phase`) that produce the exact ROADMAP shape the parser
386
+ expects, eliminating the H3-vs-bullet template gotcha. Fresh
387
+ `cp init` → `cp scaffold-milestone` → `cp scaffold-phase` → `cp tick` →
388
+ `cp complete-milestone` round-trips without any hand-editing. 429 tests.
389
+
390
+ **v0.3.x — `/cp-map-codebase` + safety hotfixes** (shipped) — cp-native
391
+ codebase mapping. New `cp scaffold-codebase` + `cp codebase-status` CLI
392
+ wrappers and a `/cp-map-codebase` slash command that dispatches 4 parallel
393
+ sub-agents (tech / arch / quality / concerns) via the harness's native task
394
+ tool to produce 7 GSD-compatible docs in `.planning/codebase/`. **No
395
+ workflow provider involved** — proves cp's state-layer ops (init,
396
+ scaffold-*, map-codebase) don't need Superpowers; the provider is for
397
+ *workflow* work (brainstorm, plan, execute, review, debug) only. v0.3.2
398
+ added atomic multi-file writes; v0.3.3 fixed `gitCommit` to never sweep the
399
+ working tree (now stages only `.planning/` or an explicit paths list) and
400
+ dropped the misleading short-form `PLAN.md` self-warning; v0.3.4 made
401
+ `writeBatch` rollback-safe, added installer collision protection
402
+ (`--force` to overwrite), and fixed the `--key=value` argv form. 558 tests.
403
+
404
+ **v0.4.0 — `/cp-capture` inbox triage** (shipped) — `cp capture "..."`
405
+ appends an ISO-minute-stamped line to `.planning/INBOX.md`; `cp inbox`
406
+ lists / triages (`--tick N --note <dest>` moves an item to the Triaged
407
+ section with a free-form destination tag like `quick:rename`,
408
+ `phase:02-mvp`, `seed:routing-redesign`, or `discard`). `/cp-capture`
409
+ slash command walks the open items interactively, proposes a routing
410
+ disposition per item (always user-confirmed), performs the routing edit
411
+ (quick task via the workflow provider, append to a phase PLAN.md, append
412
+ to STATE.md), and ticks the item triaged. Same auto-commit-scoping
413
+ invariant as v0.3.3 — `cp capture` commits never sweep unrelated dirty
414
+ files. 603 tests.
415
+
416
+ **v0.4.1 — shell statusline** (shipped) — `cp statusline` for prompt
417
+ integration. Default output `cp ▸ v0.5 ▸ 01-mvp 1/3 ▸ 01-02`. Silent
418
+ outside a cp project (safe for PS1 / Starship / tmux). `--format`
419
+ supports `%M %P %D %N %B` tokens; `--json` for harness consumption.
420
+ 631 tests.
421
+
422
+ **v0.4.2 — Cursor + Aider installers** (shipped) — `cp install cursor`
423
+ writes each cp slash-command as a `.cursor/rules/cp-<name>.mdc` rule
424
+ (invokable via `@cp-<name>` in Cursor chat) plus an ambient routing rule
425
+ (`alwaysApply: true`). `cp install aider` writes `.aider/CP-CONTEXT.md` +
426
+ `.aider/cp-commands/<name>.md` and patches `.aider.conf.yml` with a
427
+ fenced `read:` block (preserves any other YAML you've added). 681 tests.
428
+
429
+ **v0.4.3 — git worktree integration** (shipped) — `cp worktree create/list/remove`
430
+ wraps `git worktree` with cp-aware defaults (sibling-dir layout, `cp/<slug>`
431
+ branch) and records each worktree in `.planning/WORKTREES.md`. `--use-provider`
432
+ opt-in delegates to the configured workflow provider's `worktree` skill
433
+ (Superpowers maps it to `using-git-worktrees`); cp-native fallback uses
434
+ `git worktree add` directly. 751 tests.
435
+
436
+ **v0.4.4 — dogfood hotfix** (shipped) — re-ran `/cp-map-codebase --force`
437
+ against v0.4.3 source, surfaced two HIGH concerns, fixed both: `install/aider.js`
438
+ now uses the `yaml` parser (preserves user `read:` entries; auto-migrates
439
+ v0.4.2/v0.4.3 fenced blocks); `lib/worktree.js` now owns the git shell-outs
440
+ (`runGitWorktreeAdd/Remove`, `listGitWorktrees`) so `bin/cp.js` handlers stay
441
+ pure dispatch.
442
+
443
+ **v0.4.x — planned** — multi-workspace; further dogfood cycles as new
444
+ concerns surface.
445
+
446
+ ## Credits
447
+
448
+ - State-management patterns forked and stripped down from
449
+ [get-shit-done](https://github.com/gsd-build/get-shit-done) by TÂCHES.
450
+ - Workflow provider model designed around
451
+ [Superpowers](https://github.com/obra/superpowers) by Jesse Vincent.
452
+
453
+ MIT.
454
+
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { pluginRoot } = require('../../lib/paths');
6
+
7
+ /**
8
+ * Internal helpers shared across command modules.
9
+ * These were inlined in bin/cp.js before v0.6.
10
+ */
11
+
12
+ function available(name) {
13
+ return fs.existsSync(path.join(pluginRoot(), 'install', `${name}.js`));
14
+ }
15
+
16
+ function today() {
17
+ return new Date().toISOString().slice(0, 10);
18
+ }
19
+
20
+ function renderTemplate(text, vars) {
21
+ return Object.entries(vars).reduce(
22
+ (acc, [k, v]) => acc.replace(new RegExp(`\\{\\{${k}\\}\\}`, 'g'), String(v)),
23
+ text
24
+ );
25
+ }
26
+
27
+ /**
28
+ * Pre-process argv to normalize `--key=value` → `--key value`. Lets every
29
+ * subcommand's hand-rolled parser keep using the simpler "next-slot" model
30
+ * without each one having to handle `=` separately.
31
+ *
32
+ * v0.3.4 — closes CONCERNS Low "argv parser doesn't support --key=value".
33
+ *
34
+ * - Leaves bare flags (`--force`, `-v`) alone.
35
+ * - Splits `--name=value` → ['--name', 'value']. The empty `--key=` form
36
+ * becomes ['--key', ''] which is preserved as a real empty-string value.
37
+ * - Does NOT touch short combined flags like `-abc` (we don't use any).
38
+ */
39
+ function normalizeArgv(argv) {
40
+ const out = [];
41
+ for (const tok of argv) {
42
+ if (typeof tok === 'string' && tok.startsWith('--') && tok.includes('=')) {
43
+ const eq = tok.indexOf('=');
44
+ out.push(tok.slice(0, eq));
45
+ out.push(tok.slice(eq + 1));
46
+ } else {
47
+ out.push(tok);
48
+ }
49
+ }
50
+ return out;
51
+ }
52
+
53
+ module.exports = { available, today, renderTemplate, normalizeArgv };
@@ -0,0 +1,67 @@
1
+ 'use strict';
2
+
3
+ const pkg = require('../../package.json');
4
+
5
+ function usage() {
6
+ console.log(`cp v${pkg.version} — context-planning CLI (invocable as \`cplan\` or \`cp\`)
7
+
8
+ Usage:
9
+ cp install <harness> Install into a harness (copilot | claude | cursor | aider)
10
+ cp init Scaffold .planning/ in this repo
11
+ cp gsd-import [--root <dir>] [--json] [--apply]
12
+ Read-only audit of any planning project
13
+ (--apply runs \`cp init\` after the audit)
14
+ cp doctor [--json] [--quiet] Show resolved config, provider status, GSD compat
15
+ cp status [--json] Show "you are here": current milestone, phase, next plan
16
+ cp tick <plan-id> [--undo] [--no-commit]
17
+ Mark a plan done in ROADMAP + phase PLAN.md
18
+ (idempotent; commits unless --no-commit)
19
+ cp write-summary <plan-id> --from <json-file> [--body <md-file>] [--overwrite]
20
+ Write {NN-MM}-SUMMARY.md with validated frontmatter
21
+ (normalises snake_case -> kebab-case aliases)
22
+ cp scaffold-milestone <name> [--planned] [--no-commit] [--dry-run]
23
+ Add \`### 🚧 <name> (In Progress)\` heading to ROADMAP
24
+ (use --planned for \`### 📋 <name> (Planned)\`)
25
+ cp scaffold-phase <N> --name <name> [--plans <count>] [--milestone <name>]
26
+ Add \`### Phase N: <name>\` under active milestone +
27
+ create .planning/phases/{NN-slug}/PLAN.md
28
+ cp scaffold-codebase [--force] [--no-commit] [--dry-run]
29
+ Create .planning/codebase/ with 7 stub docs
30
+ (STACK, INTEGRATIONS, ARCHITECTURE, STRUCTURE,
31
+ CONVENTIONS, TESTING, CONCERNS). Filled by
32
+ \`/cp-map-codebase\`.
33
+ cp codebase-status [--json] Inventory .planning/codebase/ — which docs
34
+ exist, line counts, which still look like stubs
35
+ cp capture <text> Append a free-form item to .planning/INBOX.md
36
+ with a timestamp (use \`/cp-capture\` to triage)
37
+ cp inbox [--json] [--all] [--tick <N> [--note <dest>]]
38
+ List open items (default) or all; --tick N moves
39
+ open item N to Triaged (optionally with a note like
40
+ --note "quick:rename-version-flag")
41
+ cp statusline [--format <fmt>] [--json] [--no-color]
42
+ Print a one-line prompt-friendly status string
43
+ (for shell PS1, Starship, tmux, etc). Silent
44
+ outside a cp project. Format tokens: %M
45
+ (milestone), %P (phase), %D (done/total),
46
+ %N (next plan id), %B (branch).
47
+ cp worktree create <name> [--branch <b>] [--from <base>] [--path <dir>] [--phase <N>] [--no-create]
48
+ cp worktree list [--json]
49
+ cp worktree remove <slug> [--force]
50
+ Manage cp-tracked git worktrees. \`create\`
51
+ runs \`git worktree add <path> -b cp/<slug>\`
52
+ and records it in .planning/WORKTREES.md.
53
+ Delegates to the configured provider's
54
+ worktree skill when --use-provider is set
55
+ (Superpowers: using-git-worktrees).
56
+ cp complete-milestone [<name>] [--dry-run] [--no-commit] [--json]
57
+ Full milestone close-out (verify, aggregate digest,
58
+ collapse in ROADMAP, clear context, reset STATE, commit)
59
+ cp config get [<key>] Print a cp.<key> value (or whole cp block)
60
+ cp config set <key> <value> Update a cp.<key> value
61
+ cp config refresh [--dry-run] Merge upstream defaults into your project config
62
+ cp version Print version
63
+ cp help Show this message
64
+ `);
65
+ }
66
+
67
+ module.exports = usage;
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ const { repoRoot } = require('../../lib/paths');
4
+ const lifecycle = require('../../lib/lifecycle');
5
+ const inbox = require('../../lib/inbox');
6
+
7
+ function run(args = []) {
8
+ // Collect everything up to first -- flag as the text. Allow --no-commit too.
9
+ let noCommit = false;
10
+ const positional = [];
11
+ for (let i = 0; i < args.length; i++) {
12
+ const a = args[i];
13
+ if (a === '--no-commit') noCommit = true;
14
+ else if (a === '--dry-run') {
15
+ // Treat dry-run as no-commit + no-write. Useful for the slash command
16
+ // when proposing what would be captured.
17
+ console.error(`(dry-run not supported on capture — use \`cp inbox\` to see what would happen)`);
18
+ process.exit(2);
19
+ } else if (a.startsWith('--')) { console.error(`unknown option: ${a}`); process.exit(2); }
20
+ else positional.push(a);
21
+ }
22
+ const text = positional.join(' ').trim();
23
+ if (!text) {
24
+ console.error('Usage: cp capture <text> [--no-commit]');
25
+ process.exit(2);
26
+ }
27
+ const root = repoRoot();
28
+ let r;
29
+ try { r = inbox.appendItem(root, text); }
30
+ catch (e) { console.error(`capture: ${e.message}`); process.exit(1); }
31
+
32
+ lifecycle.writeBatch(r.actions);
33
+ console.log(`✓ inbox #${r.item.idx} [${r.item.ts}] ${r.item.text}`);
34
+ if (r.alreadyPresent) {
35
+ console.log(` (note: an identical item already exists at the same minute — kept both)`);
36
+ }
37
+
38
+ if (!noCommit) {
39
+ const commit = lifecycle.gitCommit(root, `cp: capture inbox item #${r.item.idx}`, {
40
+ paths: lifecycle.pathsFromActions(r.actions),
41
+ });
42
+ if (commit) console.log(`committed ${commit}`);
43
+ }
44
+ }
45
+
46
+ module.exports = { name: 'capture', run };