code-as-plan 2.0.0 → 2.0.3
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/bin/install.js +58 -126
- package/cap/bin/lib/cap-migrate.cjs +513 -0
- package/cap/bin/lib/cap-tag-scanner.cjs +72 -0
- package/cap/workflows/update.md +24 -24
- package/commands/cap/migrate.md +177 -0
- package/commands/cap/update.md +48 -0
- package/hooks/dist/gsd-check-update.js +6 -6
- package/package.json +1 -1
package/cap/workflows/update.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<purpose>
|
|
2
|
-
Check for
|
|
2
|
+
Check for CAP updates via npm, display changelog for versions between installed and latest, obtain user confirmation, and execute clean installation with cache clearing.
|
|
3
3
|
</purpose>
|
|
4
4
|
|
|
5
5
|
<required_reading>
|
|
@@ -9,7 +9,7 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
9
9
|
<process>
|
|
10
10
|
|
|
11
11
|
<step name="get_installed_version">
|
|
12
|
-
Detect whether
|
|
12
|
+
Detect whether CAP is installed locally or globally by checking both locations and validating install integrity.
|
|
13
13
|
|
|
14
14
|
First, derive `PREFERRED_RUNTIME` from the invoking prompt's `execution_context` path:
|
|
15
15
|
- Path contains `/.codex/` -> `codex`
|
|
@@ -17,7 +17,7 @@ First, derive `PREFERRED_RUNTIME` from the invoking prompt's `execution_context`
|
|
|
17
17
|
- Path contains `/.config/opencode/` or `/.opencode/` -> `opencode`
|
|
18
18
|
- Otherwise -> `claude`
|
|
19
19
|
|
|
20
|
-
Use `PREFERRED_RUNTIME` as the first runtime checked so `/
|
|
20
|
+
Use `PREFERRED_RUNTIME` as the first runtime checked so `/cap:update` targets the runtime that invoked it.
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
# Runtime candidates: "<runtime>:<config-dir>" stored as an array.
|
|
@@ -130,7 +130,7 @@ If multiple runtime installs are detected and the invoking runtime cannot be det
|
|
|
130
130
|
|
|
131
131
|
**If VERSION file missing:**
|
|
132
132
|
```
|
|
133
|
-
##
|
|
133
|
+
## CAP Update
|
|
134
134
|
|
|
135
135
|
**Installed version:** Unknown
|
|
136
136
|
|
|
@@ -146,14 +146,14 @@ Proceed to install step (treat as version 0.0.0 for comparison).
|
|
|
146
146
|
Check npm for latest version:
|
|
147
147
|
|
|
148
148
|
```bash
|
|
149
|
-
npm view
|
|
149
|
+
npm view code-as-plan version 2>/dev/null
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
**If npm check fails:**
|
|
153
153
|
```
|
|
154
154
|
Couldn't check for updates (offline or npm unavailable).
|
|
155
155
|
|
|
156
|
-
To update manually: `npx
|
|
156
|
+
To update manually: `npx code-as-plan@latest --global`
|
|
157
157
|
```
|
|
158
158
|
|
|
159
159
|
Exit.
|
|
@@ -164,7 +164,7 @@ Compare installed vs latest:
|
|
|
164
164
|
|
|
165
165
|
**If installed == latest:**
|
|
166
166
|
```
|
|
167
|
-
##
|
|
167
|
+
## CAP Update
|
|
168
168
|
|
|
169
169
|
**Installed:** X.Y.Z
|
|
170
170
|
**Latest:** X.Y.Z
|
|
@@ -176,7 +176,7 @@ Exit.
|
|
|
176
176
|
|
|
177
177
|
**If installed > latest:**
|
|
178
178
|
```
|
|
179
|
-
##
|
|
179
|
+
## CAP Update
|
|
180
180
|
|
|
181
181
|
**Installed:** X.Y.Z
|
|
182
182
|
**Latest:** A.B.C
|
|
@@ -195,7 +195,7 @@ Exit.
|
|
|
195
195
|
3. Display preview and ask for confirmation:
|
|
196
196
|
|
|
197
197
|
```
|
|
198
|
-
##
|
|
198
|
+
## CAP Update Available
|
|
199
199
|
|
|
200
200
|
**Installed:** 1.5.10
|
|
201
201
|
**Latest:** 1.5.15
|
|
@@ -215,22 +215,22 @@ Exit.
|
|
|
215
215
|
|
|
216
216
|
────────────────────────────────────────────────────────────
|
|
217
217
|
|
|
218
|
-
⚠️ **Note:** The installer performs a clean install of
|
|
219
|
-
- `commands/
|
|
218
|
+
⚠️ **Note:** The installer performs a clean install of CAP folders:
|
|
219
|
+
- `commands/cap/` will be wiped and replaced
|
|
220
220
|
- `cap/` will be wiped and replaced
|
|
221
|
-
- `agents/
|
|
221
|
+
- `agents/cap-*` files will be replaced
|
|
222
222
|
|
|
223
223
|
(Paths are relative to detected runtime install location:
|
|
224
224
|
global: `~/.claude/`, `~/.config/opencode/`, `~/.opencode/`, `~/.gemini/`, or `~/.codex/`
|
|
225
225
|
local: `./.claude/`, `./.config/opencode/`, `./.opencode/`, `./.gemini/`, or `./.codex/`)
|
|
226
226
|
|
|
227
227
|
Your custom files in other locations are preserved:
|
|
228
|
-
- Custom commands not in `commands/
|
|
229
|
-
- Custom agents not prefixed with `
|
|
228
|
+
- Custom commands not in `commands/cap/` ✓
|
|
229
|
+
- Custom agents not prefixed with `cap-` ✓
|
|
230
230
|
- Custom hooks ✓
|
|
231
231
|
- Your CLAUDE.md files ✓
|
|
232
232
|
|
|
233
|
-
If you've modified any
|
|
233
|
+
If you've modified any CAP files directly, they'll be automatically backed up to `cap-local-patches/` and can be reapplied with `/cap:reapply-patches` after the update.
|
|
234
234
|
```
|
|
235
235
|
|
|
236
236
|
Use AskUserQuestion:
|
|
@@ -252,17 +252,17 @@ RUNTIME_FLAG="--$TARGET_RUNTIME"
|
|
|
252
252
|
|
|
253
253
|
**If LOCAL install:**
|
|
254
254
|
```bash
|
|
255
|
-
npx -y
|
|
255
|
+
npx -y code-as-plan@latest "$RUNTIME_FLAG" --local
|
|
256
256
|
```
|
|
257
257
|
|
|
258
258
|
**If GLOBAL install:**
|
|
259
259
|
```bash
|
|
260
|
-
npx -y
|
|
260
|
+
npx -y code-as-plan@latest "$RUNTIME_FLAG" --global
|
|
261
261
|
```
|
|
262
262
|
|
|
263
263
|
**If UNKNOWN install:**
|
|
264
264
|
```bash
|
|
265
|
-
npx -y
|
|
265
|
+
npx -y code-as-plan@latest --claude --global
|
|
266
266
|
```
|
|
267
267
|
|
|
268
268
|
Capture output. If install fails, show error and exit.
|
|
@@ -272,8 +272,8 @@ Clear the update cache so statusline indicator disappears:
|
|
|
272
272
|
```bash
|
|
273
273
|
# Clear update cache across all runtime directories
|
|
274
274
|
for dir in .claude .config/opencode .opencode .gemini .codex; do
|
|
275
|
-
rm -f "./$dir/cache/
|
|
276
|
-
rm -f "$HOME/$dir/cache/
|
|
275
|
+
rm -f "./$dir/cache/cap-update-check.json"
|
|
276
|
+
rm -f "$HOME/$dir/cache/cap-update-check.json"
|
|
277
277
|
done
|
|
278
278
|
```
|
|
279
279
|
|
|
@@ -285,12 +285,12 @@ Format completion message (changelog was already shown in confirmation step):
|
|
|
285
285
|
|
|
286
286
|
```
|
|
287
287
|
╔═══════════════════════════════════════════════════════════╗
|
|
288
|
-
║
|
|
288
|
+
║ CAP Updated: v1.5.10 → v1.5.15 ║
|
|
289
289
|
╚═══════════════════════════════════════════════════════════╝
|
|
290
290
|
|
|
291
291
|
⚠️ Restart your runtime to pick up the new commands.
|
|
292
292
|
|
|
293
|
-
[View full changelog](https://github.com/
|
|
293
|
+
[View full changelog](https://github.com/dwall-sys/code-as-plan/blob/main/CHANGELOG.md)
|
|
294
294
|
```
|
|
295
295
|
</step>
|
|
296
296
|
|
|
@@ -298,13 +298,13 @@ Format completion message (changelog was already shown in confirmation step):
|
|
|
298
298
|
<step name="check_local_patches">
|
|
299
299
|
After update completes, check if the installer detected and backed up any locally modified files:
|
|
300
300
|
|
|
301
|
-
Check for
|
|
301
|
+
Check for cap-local-patches/backup-meta.json in the config directory.
|
|
302
302
|
|
|
303
303
|
**If patches found:**
|
|
304
304
|
|
|
305
305
|
```
|
|
306
306
|
Local patches were backed up before the update.
|
|
307
|
-
Run /
|
|
307
|
+
Run /cap:reapply-patches to merge your modifications into the new version.
|
|
308
308
|
```
|
|
309
309
|
|
|
310
310
|
**If no patches:** Continue normally.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cap:migrate
|
|
3
|
+
description: "Migrate GSD Code-First v1.x projects to CAP v2.0 -- converts @gsd-* tags, planning artifacts, and session format."
|
|
4
|
+
argument-hint: "[--dry-run] [--tags-only] [--force]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Bash
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
- AskUserQuestion
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<!-- @cap-feature(feature:F-MIGRATE) Migration command -- converts GSD v1.x projects to CAP v2.0 format. -->
|
|
15
|
+
<!-- @cap-todo Supports --dry-run, --tags-only, and --force flags. -->
|
|
16
|
+
|
|
17
|
+
<objective>
|
|
18
|
+
Migrate a GSD Code-First v1.x project to CAP v2.0 format. Converts @gsd-* tags to @cap-* equivalents, transforms planning artifacts into FEATURE-MAP.md entries, and migrates .planning/SESSION.json to .cap/SESSION.json.
|
|
19
|
+
</objective>
|
|
20
|
+
|
|
21
|
+
<context>
|
|
22
|
+
$ARGUMENTS
|
|
23
|
+
|
|
24
|
+
@FEATURE-MAP.md
|
|
25
|
+
</context>
|
|
26
|
+
|
|
27
|
+
<process>
|
|
28
|
+
|
|
29
|
+
## Step 0: Parse flags
|
|
30
|
+
|
|
31
|
+
Check `$ARGUMENTS` for:
|
|
32
|
+
- `--dry-run` — show what would change without writing files
|
|
33
|
+
- `--tags-only` — only migrate tags, skip artifact and session migration
|
|
34
|
+
- `--force` — skip user confirmation gate
|
|
35
|
+
|
|
36
|
+
## Step 1: Analyze migration scope
|
|
37
|
+
|
|
38
|
+
Run the analysis to determine what needs migrating:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
node -e "
|
|
42
|
+
const migrate = require('./cap/bin/lib/cap-migrate.cjs');
|
|
43
|
+
const report = migrate.analyzeMigration(process.cwd());
|
|
44
|
+
console.log(JSON.stringify(report, null, 2));
|
|
45
|
+
"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Store as `analysis`. Present a summary to the user:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Migration Analysis
|
|
52
|
+
==================
|
|
53
|
+
|
|
54
|
+
@gsd-* tags found: {gsdTagCount}
|
|
55
|
+
Legacy artifacts: {gsdArtifacts.length} ({list})
|
|
56
|
+
.planning/ directory: {yes/no}
|
|
57
|
+
SESSION.json (v1.x): {yes/no}
|
|
58
|
+
|
|
59
|
+
Recommendations:
|
|
60
|
+
{For each recommendation:}
|
|
61
|
+
- {recommendation}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Step 2: Confirm with user (unless --force)
|
|
65
|
+
|
|
66
|
+
If `--force` is NOT set and this is NOT `--dry-run`, use AskUserQuestion to confirm:
|
|
67
|
+
|
|
68
|
+
> "Proceed with migration? This will modify source files and create CAP v2.0 artifacts. Use --dry-run first if you want to preview changes."
|
|
69
|
+
|
|
70
|
+
If user declines, abort with message: "Migration cancelled. Run with --dry-run to preview changes."
|
|
71
|
+
|
|
72
|
+
## Step 3: Migrate tags
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
node -e "
|
|
76
|
+
const migrate = require('./cap/bin/lib/cap-migrate.cjs');
|
|
77
|
+
const dryRun = process.argv[1] === 'true';
|
|
78
|
+
const result = migrate.migrateTags(process.cwd(), { dryRun });
|
|
79
|
+
console.log(JSON.stringify(result, null, 2));
|
|
80
|
+
" '<DRY_RUN_VALUE>'
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Store as `tag_result`. Report:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
Tag Migration
|
|
87
|
+
=============
|
|
88
|
+
Files scanned: {filesScanned}
|
|
89
|
+
Files modified: {filesModified}
|
|
90
|
+
Tags converted: {tagsConverted}
|
|
91
|
+
Tags removed: {tagsRemoved}
|
|
92
|
+
|
|
93
|
+
{If changes.length > 0, show first 20 changes:}
|
|
94
|
+
Changes:
|
|
95
|
+
{file}:{line} [{action}]
|
|
96
|
+
- {original}
|
|
97
|
+
+ {replaced}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If `--tags-only` is set, skip to Step 6.
|
|
101
|
+
|
|
102
|
+
## Step 4: Migrate artifacts
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
node -e "
|
|
106
|
+
const migrate = require('./cap/bin/lib/cap-migrate.cjs');
|
|
107
|
+
const dryRun = process.argv[1] === 'true';
|
|
108
|
+
const result = migrate.migrateArtifacts(process.cwd(), { dryRun });
|
|
109
|
+
console.log(JSON.stringify(result, null, 2));
|
|
110
|
+
" '<DRY_RUN_VALUE>'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Store as `artifact_result`. Report:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Artifact Migration
|
|
117
|
+
==================
|
|
118
|
+
Source: {source}
|
|
119
|
+
Features found: {featuresFound}
|
|
120
|
+
Feature Map: {featureMapCreated ? 'created/updated' : 'no changes'}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Step 5: Migrate session
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
node -e "
|
|
127
|
+
const migrate = require('./cap/bin/lib/cap-migrate.cjs');
|
|
128
|
+
const dryRun = process.argv[1] === 'true';
|
|
129
|
+
const result = migrate.migrateSession(process.cwd(), { dryRun });
|
|
130
|
+
console.log(JSON.stringify(result, null, 2));
|
|
131
|
+
" '<DRY_RUN_VALUE>'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Store as `session_result`. Report:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
Session Migration
|
|
138
|
+
=================
|
|
139
|
+
Old format: {oldFormat}
|
|
140
|
+
New format: {newFormat}
|
|
141
|
+
Migrated: {migrated ? 'yes' : 'no'}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Step 6: Final report and session update
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
Migration Complete
|
|
148
|
+
==================
|
|
149
|
+
|
|
150
|
+
Tags: {tagsConverted} converted, {tagsRemoved} removed
|
|
151
|
+
Artifacts: {featuresFound} features extracted → FEATURE-MAP.md
|
|
152
|
+
Session: {migrated ? 'migrated to .cap/SESSION.json' : 'no session to migrate'}
|
|
153
|
+
|
|
154
|
+
{If dry run:}
|
|
155
|
+
NOTE: This was a dry run. No files were modified. Run without --dry-run to apply changes.
|
|
156
|
+
|
|
157
|
+
{If not dry run:}
|
|
158
|
+
Next steps:
|
|
159
|
+
1. Review changes with `git diff`
|
|
160
|
+
2. Run /cap:scan to verify tag migration
|
|
161
|
+
3. Run /cap:status to see project state from Feature Map
|
|
162
|
+
4. Commit migrated files
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Update session state (unless dry run):
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
node -e "
|
|
169
|
+
const session = require('./cap/bin/lib/cap-session.cjs');
|
|
170
|
+
session.updateSession(process.cwd(), {
|
|
171
|
+
lastCommand: '/cap:migrate',
|
|
172
|
+
lastCommandTimestamp: new Date().toISOString()
|
|
173
|
+
});
|
|
174
|
+
"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
</process>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cap:update
|
|
3
|
+
description: "Update CAP to the latest version -- checks npm, shows changelog, performs clean install with cache clearing."
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Bash
|
|
7
|
+
- Glob
|
|
8
|
+
- Grep
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<objective>
|
|
12
|
+
Check for CAP updates via npm, display the changelog for versions between installed and latest, obtain user confirmation, and execute a clean installation with cache clearing.
|
|
13
|
+
|
|
14
|
+
This command orchestrates the update workflow defined in `cap/workflows/update.md`.
|
|
15
|
+
</objective>
|
|
16
|
+
|
|
17
|
+
<context>
|
|
18
|
+
$ARGUMENTS
|
|
19
|
+
|
|
20
|
+
execution_context: commands/cap/update.md
|
|
21
|
+
</context>
|
|
22
|
+
|
|
23
|
+
<process>
|
|
24
|
+
|
|
25
|
+
## Step 1: Load and execute the update workflow
|
|
26
|
+
|
|
27
|
+
Read and follow the full workflow defined in:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
cap/workflows/update.md
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
That workflow handles:
|
|
34
|
+
1. Detecting installed version and install scope (local/global)
|
|
35
|
+
2. Checking npm for the latest `code-as-plan` version
|
|
36
|
+
3. Comparing versions and showing changelog
|
|
37
|
+
4. Obtaining user confirmation before updating
|
|
38
|
+
5. Running `npx code-as-plan@latest` with correct flags
|
|
39
|
+
6. Clearing `cap-update-check.json` cache files
|
|
40
|
+
7. Checking for local patches that need reapplication
|
|
41
|
+
|
|
42
|
+
Follow every step in that workflow exactly as written.
|
|
43
|
+
|
|
44
|
+
</process>
|
|
45
|
+
|
|
46
|
+
<output>
|
|
47
|
+
The workflow produces its own formatted output at each step. Do not add extra framing -- let the workflow messages speak for themselves.
|
|
48
|
+
</output>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
3
|
-
// Check for
|
|
2
|
+
// cap-hook-version: {{GSD_VERSION}}
|
|
3
|
+
// Check for CAP updates in background, write result to cache
|
|
4
4
|
// Called by SessionStart hook - runs once per session
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
@@ -30,7 +30,7 @@ function detectConfigDir(baseDir) {
|
|
|
30
30
|
const globalConfigDir = detectConfigDir(homeDir);
|
|
31
31
|
const projectConfigDir = detectConfigDir(cwd);
|
|
32
32
|
const cacheDir = path.join(globalConfigDir, 'cache');
|
|
33
|
-
const cacheFile = path.join(cacheDir, '
|
|
33
|
+
const cacheFile = path.join(cacheDir, 'cap-update-check.json');
|
|
34
34
|
|
|
35
35
|
// VERSION file locations (check project first, then global)
|
|
36
36
|
const projectVersionFile = path.join(projectConfigDir, 'cap', 'VERSION');
|
|
@@ -71,11 +71,11 @@ const child = spawn(process.execPath, ['-e', `
|
|
|
71
71
|
const hooksDir = path.join(configDir, 'cap', 'hooks');
|
|
72
72
|
try {
|
|
73
73
|
if (fs.existsSync(hooksDir)) {
|
|
74
|
-
const hookFiles = fs.readdirSync(hooksDir).filter(f => f.startsWith('gsd-') && f.endsWith('.js'));
|
|
74
|
+
const hookFiles = fs.readdirSync(hooksDir).filter(f => (f.startsWith('gsd-') || f.startsWith('cap-')) && f.endsWith('.js'));
|
|
75
75
|
for (const hookFile of hookFiles) {
|
|
76
76
|
try {
|
|
77
77
|
const content = fs.readFileSync(path.join(hooksDir, hookFile), 'utf8');
|
|
78
|
-
const versionMatch = content.match(/\\/\\/ gsd-hook-version:\\s*(.+)/);
|
|
78
|
+
const versionMatch = content.match(/\\/\\/ (?:gsd|cap)-hook-version:\\s*(.+)/);
|
|
79
79
|
if (versionMatch) {
|
|
80
80
|
const hookVersion = versionMatch[1].trim();
|
|
81
81
|
if (hookVersion !== installed && !hookVersion.includes('{{')) {
|
|
@@ -93,7 +93,7 @@ const child = spawn(process.execPath, ['-e', `
|
|
|
93
93
|
|
|
94
94
|
let latest = null;
|
|
95
95
|
try {
|
|
96
|
-
latest = execSync('npm view
|
|
96
|
+
latest = execSync('npm view code-as-plan version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
|
|
97
97
|
} catch (e) {}
|
|
98
98
|
|
|
99
99
|
const result = {
|