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.
- package/LICENSE +21 -0
- package/README.md +454 -0
- package/bin/commands/_helpers.js +53 -0
- package/bin/commands/_usage.js +67 -0
- package/bin/commands/capture.js +46 -0
- package/bin/commands/codebase-status.js +41 -0
- package/bin/commands/complete-milestone.js +57 -0
- package/bin/commands/config.js +70 -0
- package/bin/commands/doctor.js +139 -0
- package/bin/commands/gsd-import.js +90 -0
- package/bin/commands/inbox.js +81 -0
- package/bin/commands/index.js +33 -0
- package/bin/commands/init.js +87 -0
- package/bin/commands/install.js +43 -0
- package/bin/commands/scaffold-codebase.js +53 -0
- package/bin/commands/scaffold-milestone.js +58 -0
- package/bin/commands/scaffold-phase.js +65 -0
- package/bin/commands/status.js +42 -0
- package/bin/commands/statusline.js +108 -0
- package/bin/commands/tick.js +49 -0
- package/bin/commands/version.js +9 -0
- package/bin/commands/worktree.js +218 -0
- package/bin/commands/write-summary.js +54 -0
- package/bin/cp.cmd +2 -0
- package/bin/cp.js +54 -0
- package/commands/cp/capture.md +107 -0
- package/commands/cp/complete-milestone.md +166 -0
- package/commands/cp/execute-phase.md +220 -0
- package/commands/cp/map-codebase.md +211 -0
- package/commands/cp/new-milestone.md +136 -0
- package/commands/cp/new-project.md +132 -0
- package/commands/cp/plan-phase.md +195 -0
- package/commands/cp/progress.md +147 -0
- package/commands/cp/quick.md +104 -0
- package/commands/cp/resume.md +125 -0
- package/commands/cp/write-summary.md +33 -0
- package/docs/MIGRATION-v0.5.md +140 -0
- package/docs/architecture.md +189 -0
- package/docs/superpowers/plans/2026-05-20-v0-7-plan-16-01-design-md-infrastructure.md +1064 -0
- package/docs/superpowers/plans/2026-05-20-v0-7-plan-16-02-review-log-infrastructure.md +418 -0
- package/docs/superpowers/plans/2026-05-20-v0-7-plan-16-03-key-decisions-hard-block.md +295 -0
- package/docs/superpowers/specs/2026-05-20-generic-provider-harness-detection-design.md +380 -0
- package/docs/superpowers/specs/2026-05-20-v0-7-design-capture-design.md +400 -0
- package/docs/writing-providers.md +76 -0
- package/install/aider.js +204 -0
- package/install/claude.js +116 -0
- package/install/common.js +65 -0
- package/install/copilot.js +86 -0
- package/install/cursor.js +120 -0
- package/install/echo-provider.js +50 -0
- package/lib/codebase-mapper.js +169 -0
- package/lib/detect.js +280 -0
- package/lib/frontmatter.js +72 -0
- package/lib/gsd-compat.js +165 -0
- package/lib/import.js +543 -0
- package/lib/inbox.js +226 -0
- package/lib/lifecycle.js +929 -0
- package/lib/merge.js +157 -0
- package/lib/milestone.js +595 -0
- package/lib/paths.js +191 -0
- package/lib/provider.js +168 -0
- package/lib/roadmap.js +134 -0
- package/lib/state.js +99 -0
- package/lib/worktree.js +253 -0
- package/package.json +45 -0
- package/templates/DESIGN.md +78 -0
- package/templates/INBOX.md +13 -0
- package/templates/MILESTONE-CONTEXT.md +40 -0
- package/templates/MILESTONES.md +29 -0
- package/templates/PLAN.md +84 -0
- package/templates/PROJECT.md +43 -0
- package/templates/REVIEW-LOG.md +38 -0
- package/templates/ROADMAP.md +34 -0
- package/templates/STATE.md +78 -0
- package/templates/SUMMARY.md +75 -0
- package/templates/codebase/ARCHITECTURE.md +30 -0
- package/templates/codebase/CONCERNS.md +30 -0
- package/templates/codebase/CONVENTIONS.md +30 -0
- package/templates/codebase/INTEGRATIONS.md +30 -0
- package/templates/codebase/STACK.md +26 -0
- package/templates/codebase/STRUCTURE.md +32 -0
- package/templates/codebase/TESTING.md +39 -0
- package/templates/config.json +173 -0
- package/templates/phase-PLAN.md +32 -0
- package/templates/quick-PLAN.md +24 -0
- 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
|
+
[](https://github.com/shushenglihotmail/context-planning/actions/workflows/ci.yml)
|
|
10
|
+
[]()
|
|
11
|
+
[]()
|
|
12
|
+
[]()
|
|
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 };
|