roadmapsmith 0.9.32 → 0.9.34
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +31 -3
- package/bin/cli.js +116 -27
- package/package.json +1 -1
- package/skills/roadmap/SKILL.md +4 -11
- package/skills/roadmap-audit/SKILL.md +2 -5
- package/skills/roadmap-generate/SKILL.md +4 -7
- package/skills/roadmap-init/SKILL.md +3 -6
- package/skills/roadmap-maintain/SKILL.md +4 -8
- package/skills/roadmap-setup/SKILL.md +3 -6
- package/skills/roadmap-status/SKILL.md +2 -5
- package/skills/roadmap-sync/SKILL.md +2 -2
- package/skills/roadmap-sync/agents/openai.yaml +1 -1
- package/skills/roadmap-update/SKILL.md +4 -7
- package/skills/roadmap-validate/SKILL.md +2 -5
- package/skills/roadmap-zero/SKILL.md +3 -6
- package/skills.json +16 -16
- package/src/zero.js +88 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roadmapsmith",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.34",
|
|
4
4
|
"description": "Evidence-backed ROADMAP.md workflows for AI coding agents, with canonical RoadmapSmith status and maintain surfaces plus advanced sync/generate tools and legacy compatibility aliases.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "PapiScholz"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roadmapsmith",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.34",
|
|
4
4
|
"description": "Evidence-backed ROADMAP.md workflows for AI coding agents, with canonical RoadmapSmith status and maintain surfaces plus advanced sync/generate tools and legacy compatibility aliases.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "PapiScholz"
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ This package owns the RoadmapSmith CLI, validator, sync engine, host setup files
|
|
|
8
8
|
|
|
9
9
|
- `roadmapsmith setup`
|
|
10
10
|
- `roadmapsmith zero`
|
|
11
|
-
- `roadmapsmith maintain`
|
|
11
|
+
- `roadmapsmith maintain [--dry-run]`
|
|
12
12
|
- `roadmapsmith status [--json]`
|
|
13
13
|
- `roadmapsmith validate [--json] [--strict]`
|
|
14
14
|
- `roadmapsmith update [--task <stable-id> --evidence "<single-line evidence>"]`
|
|
@@ -40,11 +40,39 @@ This package owns the RoadmapSmith CLI, validator, sync engine, host setup files
|
|
|
40
40
|
|
|
41
41
|
### Zero Mode
|
|
42
42
|
|
|
43
|
-
Use for empty or low-context repositories. `roadmapsmith zero` runs the terminal interview,
|
|
43
|
+
Use for empty or low-context repositories. `roadmapsmith zero` runs the terminal interview when TTY is available, or consumes a complete brief from config plus flags in non-interactive environments.
|
|
44
|
+
|
|
45
|
+
Non-interactive inputs:
|
|
46
|
+
|
|
47
|
+
- `--product-name`
|
|
48
|
+
- `--primary-user`
|
|
49
|
+
- `--problem-statement`
|
|
50
|
+
- `--target-outcome`
|
|
51
|
+
- `--anti-goal` (repeatable)
|
|
52
|
+
- `--preferred-stack`
|
|
53
|
+
- `--constraint` (repeatable)
|
|
54
|
+
- `--done-criterion` (repeatable)
|
|
55
|
+
|
|
56
|
+
Without TTY, Zero Mode requires a complete brief from config/flags and fails clearly when required fields are missing.
|
|
44
57
|
|
|
45
58
|
### Sync/Audit Mode
|
|
46
59
|
|
|
47
|
-
Use for repositories that already contain code, tests, docs, TODOs, or an existing roadmap. `roadmapsmith maintain` is the preserve-first one-command flow.
|
|
60
|
+
Use for repositories that already contain code, tests, docs, TODOs, or an existing roadmap. `roadmapsmith maintain` is the preserve-first one-command flow for an existing managed roadmap block.
|
|
61
|
+
|
|
62
|
+
If `ROADMAP.md` is authored and non-empty but has no `<!-- rs:managed:* -->` block:
|
|
63
|
+
|
|
64
|
+
- `maintain` refuses to seed managed content implicitly
|
|
65
|
+
- `update` is the conservative inline-annotation path
|
|
66
|
+
- `generate` is the explicit managed-section creation path
|
|
67
|
+
|
|
68
|
+
For write-capable surfaces (`maintain`, `generate`, `sync`, `update`), prefer `--dry-run` first.
|
|
69
|
+
|
|
70
|
+
## Managed Block Ownership
|
|
71
|
+
|
|
72
|
+
- `maintain` owns the managed roadmap block only.
|
|
73
|
+
- `update` can annotate existing task lines even when no managed block exists.
|
|
74
|
+
- `generate` is the explicit path that creates or replaces managed roadmap content.
|
|
75
|
+
- Manually inserting empty `<!-- rs:managed:start -->` markers is no longer required as a workaround.
|
|
48
76
|
|
|
49
77
|
## Verification Model
|
|
50
78
|
|
package/bin/cli.js
CHANGED
|
@@ -14,14 +14,21 @@ const { generateRoadmapDocument } = require('../src/generator');
|
|
|
14
14
|
const { parseRoadmap, tasksInManagedBlock } = require('../src/parser');
|
|
15
15
|
const { buildValidationContext, validateTasks, auditValidation, CONFIDENCE_RANK, applyMinimumConfidence } = require('../src/validator');
|
|
16
16
|
const { applySync } = require('../src/sync');
|
|
17
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
buildZeroModeConfigPatch,
|
|
19
|
+
collectZeroModeAnswers,
|
|
20
|
+
formatMissingZeroModeFields,
|
|
21
|
+
getMissingZeroModeFields,
|
|
22
|
+
isInteractiveTerminal,
|
|
23
|
+
resolveZeroModeAnswers
|
|
24
|
+
} = require('../src/zero');
|
|
18
25
|
|
|
19
26
|
function printHelp() {
|
|
20
27
|
console.log([
|
|
21
28
|
'Usage:',
|
|
22
29
|
' Canonical commands:',
|
|
23
|
-
' roadmapsmith zero [--project-root <path>] [--config <path>]',
|
|
24
|
-
' roadmapsmith maintain [--project-root <path>] [--config <path>] [--roadmap-file <path>] [--full-regen] [--refresh-annotations]',
|
|
30
|
+
' roadmapsmith zero [--project-root <path>] [--config <path>] [--product-name <text>] [--primary-user <text>] [--problem-statement <text>] [--target-outcome <text>] [--anti-goal <text> ...] [--preferred-stack <text>] [--constraint <text> ...] [--done-criterion <text> ...]',
|
|
31
|
+
' roadmapsmith maintain [--project-root <path>] [--config <path>] [--roadmap-file <path>] [--dry-run] [--full-regen] [--refresh-annotations]',
|
|
25
32
|
' roadmapsmith status [--roadmap-file <path>] [--project-root <path>] [--config <path>] [--json]',
|
|
26
33
|
' roadmapsmith validate [--roadmap-file <path>] [--project-root <path>] [--config <path>] [--task <id|text>] [--json] [--strict]',
|
|
27
34
|
' roadmapsmith update [--task <stable-id> --evidence <text>] [--roadmap-file <path>] [--project-root <path>] [--config <path>] [--dry-run]',
|
|
@@ -140,6 +147,42 @@ function formatSetupVerb(result, dryRun) {
|
|
|
140
147
|
return result.before == null ? 'Created' : 'Updated';
|
|
141
148
|
}
|
|
142
149
|
|
|
150
|
+
function emitPreWriteWarning(roadmapFile, options = {}) {
|
|
151
|
+
if (options.dryRun || options.suppressWarning) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (options.warningState && options.warningState.emitted) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const commandName = options.commandName || 'roadmapsmith';
|
|
159
|
+
console.log(`Warning: ${commandName} will modify ${roadmapFile}. Review the preview first with --dry-run.`);
|
|
160
|
+
if (options.managedSectionNote) {
|
|
161
|
+
console.log(options.managedSectionNote);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (options.warningState) {
|
|
165
|
+
options.warningState.emitted = true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function assertMaintainCanWrite(roadmapFile, content) {
|
|
170
|
+
if (content == null || String(content).trim().length === 0) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const parsed = parseRoadmap(content);
|
|
175
|
+
if (parsed.hasManagedBlock) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
throw new Error(
|
|
180
|
+
`Refusing to let roadmapsmith maintain seed a managed section into an authored roadmap without <!-- rs:managed:start --> markers: ${roadmapFile}\n` +
|
|
181
|
+
'For conservative inline annotations, run `roadmapsmith update --dry-run` then `roadmapsmith update`.\n' +
|
|
182
|
+
'To intentionally create a managed section, run `roadmapsmith generate --dry-run` then `roadmapsmith generate`.'
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
143
186
|
function runInitCommand(projectRoot, config, flags) {
|
|
144
187
|
const roadmapFile = resolveRoadmapFile(projectRoot, config, flags['roadmap-file']);
|
|
145
188
|
const agentsFile = resolveAgentsFile(projectRoot, config, flags['agents-file']);
|
|
@@ -187,6 +230,13 @@ function runGenerateCommand(projectRoot, config, flags, options = {}) {
|
|
|
187
230
|
forceFullRegenerate: options.forceFullRegenerate === true || isEnabled(flags['full-regen'])
|
|
188
231
|
});
|
|
189
232
|
|
|
233
|
+
emitPreWriteWarning(roadmapFile, {
|
|
234
|
+
commandName: options.commandName || 'roadmapsmith generate',
|
|
235
|
+
dryRun,
|
|
236
|
+
suppressWarning: options.suppressPreWriteWarning,
|
|
237
|
+
warningState: options.warningState,
|
|
238
|
+
managedSectionNote: 'This command may create or replace a managed roadmap section depending on the current file state and flags.'
|
|
239
|
+
});
|
|
190
240
|
const writeResult = writeText(roadmapFile, document, { dryRun });
|
|
191
241
|
if (dryRun) {
|
|
192
242
|
if (writeResult.changed) {
|
|
@@ -229,6 +279,12 @@ function runSyncCommand(projectRoot, config, flags, options = {}) {
|
|
|
229
279
|
const forceRefresh = isEnabled(flags['refresh-annotations']);
|
|
230
280
|
const next = applySync(content, syncTasks, results, { forceRefresh });
|
|
231
281
|
const dryRun = isEnabled(flags['dry-run']);
|
|
282
|
+
emitPreWriteWarning(roadmapFile, {
|
|
283
|
+
commandName: options.commandName || 'roadmapsmith sync',
|
|
284
|
+
dryRun,
|
|
285
|
+
suppressWarning: options.suppressPreWriteWarning,
|
|
286
|
+
warningState: options.warningState
|
|
287
|
+
});
|
|
232
288
|
const writeResult = writeText(roadmapFile, next, { dryRun });
|
|
233
289
|
|
|
234
290
|
if (dryRun) {
|
|
@@ -266,7 +322,7 @@ function runUpdateCommand(projectRoot, config, flags) {
|
|
|
266
322
|
const hasTask = flags.task != null;
|
|
267
323
|
const hasEvidence = flags.evidence != null;
|
|
268
324
|
if (!hasTask && !hasEvidence) {
|
|
269
|
-
runSyncCommand(projectRoot, config, flags);
|
|
325
|
+
runSyncCommand(projectRoot, config, flags, { commandName: 'roadmapsmith update' });
|
|
270
326
|
return;
|
|
271
327
|
}
|
|
272
328
|
if (!hasTask || !hasEvidence || Array.isArray(flags.task) || Array.isArray(flags.evidence)) {
|
|
@@ -306,6 +362,10 @@ function runUpdateCommand(projectRoot, config, flags) {
|
|
|
306
362
|
|
|
307
363
|
const next = applySync(draft, [draftTask], { [taskId]: result });
|
|
308
364
|
const dryRun = isEnabled(flags['dry-run']);
|
|
365
|
+
emitPreWriteWarning(roadmapFile, {
|
|
366
|
+
commandName: 'roadmapsmith update',
|
|
367
|
+
dryRun
|
|
368
|
+
});
|
|
309
369
|
const writeResult = writeText(roadmapFile, next, { dryRun });
|
|
310
370
|
if (dryRun) {
|
|
311
371
|
if (writeResult.changed) {
|
|
@@ -371,40 +431,69 @@ function runStatusCommand(projectRoot, config, flags, options = {}) {
|
|
|
371
431
|
async function runZeroCommand(projectRoot, flags) {
|
|
372
432
|
const configPath = resolveConfigPath({ projectRoot, configPath: flags.config });
|
|
373
433
|
const config = loadConfig({ projectRoot, configPath: flags.config });
|
|
374
|
-
|
|
375
|
-
|
|
434
|
+
const roadmapFile = resolveRoadmapFile(projectRoot, config, flags['roadmap-file']);
|
|
435
|
+
const roadmapExistedBeforeInit = fs.existsSync(roadmapFile);
|
|
436
|
+
const defaults = resolveZeroModeAnswers(projectRoot, config, flags);
|
|
437
|
+
const interactive = isInteractiveTerminal(process.stdin, process.stdout);
|
|
438
|
+
let answers = defaults;
|
|
439
|
+
|
|
440
|
+
if (!interactive) {
|
|
441
|
+
const missingFields = getMissingZeroModeFields(defaults);
|
|
442
|
+
if (missingFields.length > 0) {
|
|
443
|
+
throw new Error(
|
|
444
|
+
'Zero Mode requires a complete brief in non-interactive environments. Missing: ' +
|
|
445
|
+
`${formatMissingZeroModeFields(missingFields).join(', ')}. ` +
|
|
446
|
+
'Provide the missing values with CLI flags or in roadmap-skill.config.json before retrying.'
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
console.log('RoadmapSmith Zero Mode');
|
|
450
|
+
console.log('Using config/flag discovery inputs in non-interactive mode.\n');
|
|
451
|
+
} else {
|
|
452
|
+
const rl = readline.createInterface({
|
|
453
|
+
input: process.stdin,
|
|
454
|
+
output: process.stdout
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
try {
|
|
458
|
+
console.log('RoadmapSmith Zero Mode');
|
|
459
|
+
console.log('Answer the discovery interview to generate the first roadmap.\n');
|
|
460
|
+
answers = await collectZeroModeAnswers((prompt) => rl.question(prompt), defaults);
|
|
461
|
+
} finally {
|
|
462
|
+
rl.close();
|
|
463
|
+
}
|
|
376
464
|
}
|
|
377
465
|
|
|
378
|
-
const
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
466
|
+
const existingUserConfig = readUserConfig({ projectRoot, configPath: flags.config });
|
|
467
|
+
const nextUserConfig = buildZeroModeConfigPatch(projectRoot, existingUserConfig, answers);
|
|
468
|
+
writeText(configPath, JSON.stringify(nextUserConfig, null, 2));
|
|
469
|
+
console.log(`Updated ${configPath}`);
|
|
470
|
+
const nextConfig = loadConfig({ projectRoot, configPath: flags.config });
|
|
471
|
+
runInitCommand(projectRoot, nextConfig, flags);
|
|
472
|
+
runGenerateCommand(projectRoot, nextConfig, flags, {
|
|
473
|
+
commandName: 'roadmapsmith zero',
|
|
474
|
+
suppressPreWriteWarning: true,
|
|
475
|
+
forceFullRegenerate: !roadmapExistedBeforeInit
|
|
382
476
|
});
|
|
383
|
-
|
|
384
|
-
try {
|
|
385
|
-
console.log('RoadmapSmith Zero Mode');
|
|
386
|
-
console.log('Answer the discovery interview to generate the first roadmap.\n');
|
|
387
|
-
const answers = await collectZeroModeAnswers((prompt) => rl.question(prompt), defaults);
|
|
388
|
-
const existingUserConfig = readUserConfig({ projectRoot, configPath: flags.config });
|
|
389
|
-
const nextUserConfig = buildZeroModeConfigPatch(projectRoot, existingUserConfig, answers);
|
|
390
|
-
writeText(configPath, JSON.stringify(nextUserConfig, null, 2));
|
|
391
|
-
console.log(`Updated ${configPath}`);
|
|
392
|
-
const nextConfig = loadConfig({ projectRoot, configPath: flags.config });
|
|
393
|
-
runInitCommand(projectRoot, nextConfig, flags);
|
|
394
|
-
runGenerateCommand(projectRoot, nextConfig, flags);
|
|
395
|
-
} finally {
|
|
396
|
-
rl.close();
|
|
397
|
-
}
|
|
398
477
|
}
|
|
399
478
|
|
|
400
479
|
function runMaintainCommand(projectRoot, flags) {
|
|
401
480
|
const config = loadConfig({ projectRoot, configPath: flags.config });
|
|
481
|
+
const roadmapFile = resolveRoadmapFile(projectRoot, config, flags['roadmap-file']);
|
|
482
|
+
const existingContent = readTextIfExists(roadmapFile);
|
|
483
|
+
assertMaintainCanWrite(roadmapFile, existingContent);
|
|
402
484
|
const fullRegen = isEnabled(flags['full-regen']);
|
|
485
|
+
const warningState = { emitted: false };
|
|
403
486
|
runGenerateCommand(projectRoot, config, flags, {
|
|
487
|
+
commandName: 'roadmapsmith maintain',
|
|
404
488
|
preserveManagedBlock: !fullRegen,
|
|
405
|
-
forceFullRegenerate: fullRegen
|
|
489
|
+
forceFullRegenerate: fullRegen,
|
|
490
|
+
warningState
|
|
491
|
+
});
|
|
492
|
+
runSyncCommand(projectRoot, config, { ...flags, audit: true }, {
|
|
493
|
+
audit: true,
|
|
494
|
+
commandName: 'roadmapsmith maintain',
|
|
495
|
+
warningState
|
|
406
496
|
});
|
|
407
|
-
runSyncCommand(projectRoot, config, { ...flags, audit: true }, { audit: true });
|
|
408
497
|
}
|
|
409
498
|
|
|
410
499
|
async function run() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roadmapsmith",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.34",
|
|
4
4
|
"description": "Evidence-backed ROADMAP.md workflows for AI coding agents, with canonical RoadmapSmith status and maintain surfaces plus advanced sync/generate tools and legacy compatibility aliases.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
package/skills/roadmap/SKILL.md
CHANGED
|
@@ -10,21 +10,14 @@ Use this command as the native discovery entrypoint for the shared RoadmapSmith
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
12
|
1. Treat `/roadmap` as a no-side-effects palette. Do not run mutating commands from this skill.
|
|
13
|
-
2.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
3. Otherwise, if the `roadmapsmith` CLI is available, you may run `roadmapsmith /roadmap` from the project root and use that output directly. If its global shim cannot resolve `node`, use `& "C:\Program Files\nodejs\node.exe" "$env:APPDATA\npm\node_modules\roadmapsmith\bin\cli.js" /roadmap`.
|
|
17
|
-
4. If the CLI is missing, provide the palette manually and explain the install path:
|
|
18
|
-
- `npm install -g roadmapsmith`
|
|
19
|
-
- `npx skills add PapiScholz/roadmapsmith --skill '*' -a claude-code`
|
|
20
|
-
- run `/reload-skills`
|
|
21
|
-
- if RoadmapSmith was installed as a Claude plugin, also run `/reload-plugins`
|
|
22
|
-
5. Explain the preferred native host entrypoints:
|
|
13
|
+
2. If the `roadmapsmith` CLI is available, run `roadmapsmith /roadmap` from the project root and use that output directly.
|
|
14
|
+
3. If the CLI is missing, direct the user to the official repository README for installation instructions.
|
|
15
|
+
4. Explain the preferred native host entrypoints:
|
|
23
16
|
- `/roadmap-zero`
|
|
24
17
|
- `/roadmap-maintain`
|
|
25
18
|
- `/roadmap-status`
|
|
26
19
|
- `/roadmap-init`, `/roadmap-generate`, `/roadmap-validate`, `/roadmap-update`, `/roadmap-audit`, and `/roadmap-setup`
|
|
27
|
-
|
|
20
|
+
5. Mention that `/roadmap-sync <action>` remains a deprecated legacy CLI compatibility root, and `/road` plus `/road <action>` remain deprecated CLI compatibility aliases.
|
|
28
21
|
|
|
29
22
|
## Output contract
|
|
30
23
|
|
|
@@ -9,8 +9,5 @@ Use this command when the user wants the post-sync mismatch summary after applyi
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
|
|
14
|
-
- on this Windows machine, prefer `C:\Program Files\nodejs\node.exe roadmap-skill/bin/cli.js sync --audit --project-root .` if `node` is not in PATH
|
|
15
|
-
2. Otherwise prefer `roadmapsmith sync --audit --project-root .`.
|
|
16
|
-
3. Explain that this is the current sync-plus-audit flow, not a standalone read-only audit engine.
|
|
12
|
+
1. Run `roadmapsmith sync --audit --project-root .`.
|
|
13
|
+
2. Explain that this is the current sync-plus-audit flow, not a standalone read-only audit engine.
|
|
@@ -9,10 +9,7 @@ Use this command when the user wants the managed roadmap block updated from repo
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
3. Explain that `generate` is preserve-first when a substantive managed block already exists.
|
|
17
|
-
4. When the user explicitly wants the destructive path, use `roadmapsmith generate --project-root . --full-regen`.
|
|
18
|
-
5. Summarize what stayed preserved, whether generation refused, and what new additions, if any, were inserted.
|
|
12
|
+
1. Run `roadmapsmith generate --project-root .`.
|
|
13
|
+
2. Explain that `generate` is preserve-first when a substantive managed block already exists.
|
|
14
|
+
3. To allow full roadmap regeneration, add `--full-regen`: `roadmapsmith generate --project-root . --full-regen`.
|
|
15
|
+
4. Summarize what stayed preserved, whether generation refused, and what new additions, if any, were inserted.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: roadmap-init
|
|
3
|
-
description:
|
|
3
|
+
description: Initialize project governance files through the RoadmapSmith CLI.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# RoadmapSmith Init
|
|
@@ -9,8 +9,5 @@ Use this command when the governance files are missing and the user wants them c
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
|
|
14
|
-
- on this Windows machine, prefer `C:\Program Files\nodejs\node.exe roadmap-skill/bin/cli.js init --project-root .` if `node` is not in PATH
|
|
15
|
-
2. Otherwise prefer `roadmapsmith init`.
|
|
16
|
-
3. Treat this command as CLI-backed and summarize whether files were created or skipped.
|
|
12
|
+
1. Run `roadmapsmith init`.
|
|
13
|
+
2. Summarize whether files were created or skipped.
|
|
@@ -9,12 +9,8 @@ Use this command when the repository already has code, tests, docs, or an existi
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1. Prefer
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
3. Treat this command as CLI-backed. Do not silently replace it with manual reasoning when the CLI is unavailable.
|
|
17
|
-
4. Mention that maintain runs preserve-first generate, sync, and audit in one invocation.
|
|
12
|
+
1. Run `roadmapsmith maintain --project-root .`. Prefer `--dry-run` first when previewing impact.
|
|
13
|
+
2. Treat this command as CLI-backed. Do not silently replace it with manual reasoning when the CLI is unavailable.
|
|
14
|
+
3. Mention that maintain runs preserve-first generate, sync, and audit in one invocation, but only for an existing managed roadmap block.
|
|
15
|
+
4. If the roadmap is non-empty and lacks `<!-- rs:managed:* -->`, direct the user to `roadmapsmith update` for conservative inline annotations or `roadmapsmith generate` for explicit managed-section creation.
|
|
18
16
|
5. After a successful maintain cycle, do not propose generate, sync, or audit separately unless the user needs manual control or inspection.
|
|
19
|
-
6. Mention that `roadmapsmith maintain --full-regen` or `roadmapsmith generate --full-regen` is the explicit destructive rebuild path when the user truly wants a full managed-block replacement.
|
|
20
|
-
7. When the user wants stale or outdated warning annotations to be recomputed from scratch (including annotations that were written by a prior maintain run or an external agent), use `roadmapsmith maintain --refresh-annotations`. This forces all existing warning text to be replaced with the current deterministic result rather than preserved. It is distinct from `--full-regen` (which rebuilds the managed block structure) — `--refresh-annotations` only affects warning annotations on still-failing tasks.
|
|
@@ -9,9 +9,6 @@ Use this command when the user wants RoadmapSmith host integration files generat
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
2. Otherwise prefer `roadmapsmith setup --project-root . --hosts codex,claude`.
|
|
16
|
-
3. Explain that setup affects the repository host layer: VS Code tasks, launcher/wrappers, and the optional repo-local Claude hook.
|
|
17
|
-
4. Do not claim that setup alone creates native host slash commands; those come from the installed bundle/plugin.
|
|
12
|
+
1. Run `roadmapsmith setup --project-root . --hosts codex,claude`.
|
|
13
|
+
2. Explain that setup generates VS Code task definitions for the current repository.
|
|
14
|
+
3. Do not claim that setup alone creates native host slash commands; those come from the installed bundle/plugin.
|
|
@@ -9,10 +9,7 @@ Use this command to inspect whether the shared bundle, native host surfaces, CLI
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
|
|
14
|
-
- on this Windows machine, prefer `C:\Program Files\nodejs\node.exe roadmap-skill/bin/cli.js status --json --project-root .` if `node` is not in PATH
|
|
15
|
-
2. Otherwise prefer `roadmapsmith status --json --project-root .`. If its global shim cannot resolve `node`, use `& "C:\Program Files\nodejs\node.exe" "$env:APPDATA\npm\node_modules\roadmapsmith\bin\cli.js" status --json --project-root .`.
|
|
16
|
-
3. Treat `roadmapsmith doctor --json` as compatibility-only output for existing automation, not as the primary recommendation.
|
|
12
|
+
1. Run `roadmapsmith status --json --project-root .`.
|
|
13
|
+
2. Treat `roadmapsmith doctor --json` as compatibility-only output for existing automation, not as the primary recommendation.
|
|
17
14
|
4. Parse and summarize the JSON output in plain language.
|
|
18
15
|
5. Explicitly call out missing canonical commands, duplicate legacy `/roadmap-sync` registration, and any missing advanced VS Code labels as warnings rather than canonical-readiness failures.
|
|
@@ -16,5 +16,5 @@ Use this skill only when the host exposes or the user explicitly invokes `/roadm
|
|
|
16
16
|
- `/roadmap-maintain`
|
|
17
17
|
- `/roadmap-status`
|
|
18
18
|
- `/roadmap-init`, `/roadmap-generate`, `/roadmap-validate`, `/roadmap-update`, `/roadmap-audit`, and `/roadmap-setup`
|
|
19
|
-
3. When the user explicitly invokes `/roadmap-sync <action>`, route to the matching CLI-backed action without changing semantics and mention the migration path to
|
|
20
|
-
4.
|
|
19
|
+
3. When the user explicitly invokes `/roadmap-sync <action>`, route to the matching CLI-backed action without changing semantics and mention the migration path to the direct `/roadmap-*` command.
|
|
20
|
+
4. When routing `/roadmap-sync validate`, the tool uses the same validation rules as `/roadmap-validate`. Implementation tasks require an explicit `Evidence:` line or a `Verify:` check to be marked complete.
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"interface": {
|
|
3
3
|
"display_name": "Roadmap Sync (Deprecated)",
|
|
4
4
|
"short_description": "DEPRECATED legacy root; use /roadmap-maintain or /roadmap-update.",
|
|
5
|
-
"default_prompt": "Prefer /roadmap, /roadmap-status, /roadmap-maintain, and /roadmap-update."
|
|
5
|
+
"default_prompt": "Prefer /roadmap, /roadmap-status, /roadmap-maintain, and /roadmap-update; use /roadmap-update when markers are missing."
|
|
6
6
|
}
|
|
7
7
|
}
|
|
@@ -9,10 +9,7 @@ Use this command when the user wants the canonical public `update` surface witho
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
3. Explain that `/roadmap-update` is the visible namespaced command for the public `update` family, while `/roadmap-sync <action>` remains deprecated compatibility only.
|
|
17
|
-
4. Keep the evidence-backed refresh semantics unchanged: no-argument `update` syncs the roadmap from repository evidence, and `sync` remains the advanced CLI alias for that same mutating refresh path. It is not a full regeneration path and not an independent audit engine.
|
|
18
|
-
5. To complete one task, run `roadmapsmith update --task <stable-id> --evidence "<single-line evidence>"`. It writes only after the supplied evidence validates at high confidence; use `--dry-run` to preview it.
|
|
12
|
+
1. Run `roadmapsmith update --project-root .`.
|
|
13
|
+
2. Explain that `/roadmap-update` is the visible namespaced command for the public `update` family, while `/roadmap-sync <action>` remains deprecated compatibility only.
|
|
14
|
+
3. The no-argument `update` syncs the roadmap from repository evidence. The `sync` alias covers the same refresh path. It is not a full regeneration path and not an independent audit engine.
|
|
15
|
+
4. To mark a specific task complete, run `roadmapsmith update --task TASK-ID --evidence "description"`. The CLI validates before writing; use `--dry-run` to preview.
|
|
@@ -9,8 +9,5 @@ Use this command when the user wants per-task evidence status without mutating t
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
|
|
14
|
-
- on this Windows machine, prefer `C:\Program Files\nodejs\node.exe roadmap-skill/bin/cli.js validate --json --project-root .` if `node` is not in PATH
|
|
15
|
-
2. Otherwise prefer `roadmapsmith validate --json --project-root .`.
|
|
16
|
-
3. Treat this command as CLI-backed and non-mutating.
|
|
12
|
+
1. Run `roadmapsmith validate --json --project-root .`.
|
|
13
|
+
2. This command is non-mutating.
|
|
@@ -9,9 +9,6 @@ Use this command when the repository is empty or low-context and the user needs
|
|
|
9
9
|
|
|
10
10
|
## Required behavior
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
2. Otherwise prefer `roadmapsmith zero --project-root .`.
|
|
16
|
-
3. Treat this command as CLI-backed and interactive.
|
|
17
|
-
4. If the CLI is missing, explain the install path instead of improvising the workflow manually.
|
|
12
|
+
1. Run `roadmapsmith zero --project-root .`.
|
|
13
|
+
2. In non-interactive environments, provide or reuse a complete brief from config plus flags such as `--primary-user`, `--problem-statement`, `--target-outcome`, and repeatable `--done-criterion`.
|
|
14
|
+
3. If the CLI is missing, explain the install path instead of improvising the workflow manually.
|
package/skills.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"npx skills add PapiScholz/roadmapsmith --skill '*' -a claude-code",
|
|
13
13
|
"roadmapsmith setup",
|
|
14
14
|
"roadmapsmith zero",
|
|
15
|
-
"roadmapsmith maintain",
|
|
15
|
+
"roadmapsmith maintain --dry-run",
|
|
16
16
|
"roadmapsmith /roadmap",
|
|
17
17
|
"roadmapsmith update --task p2-customer-history --evidence \"src/app/api/customers/route.ts, test/customers.test.js\"",
|
|
18
18
|
"roadmapsmith validate --json"
|
|
@@ -21,74 +21,74 @@
|
|
|
21
21
|
"command": "npx skills add PapiScholz/roadmapsmith --skill '*' -a claude-code",
|
|
22
22
|
"source": "PapiScholz/roadmapsmith",
|
|
23
23
|
"skill": "*",
|
|
24
|
-
"notes": "Recommended Claude Code install path for native GUI slash commands. Canonical surfaces: /roadmap, /roadmap-zero, /roadmap-maintain, /roadmap-status, /roadmap-validate, /roadmap-update, /roadmap-setup. The public CLI update family covers both checklist refresh and verified single-task completion; sync remains the advanced alias for the mutating refresh path. Advanced surfaces: /roadmap-init, /roadmap-generate, /roadmap-audit. DEPRECATED: /roadmap-sync remains only as a compatibility root for existing automation; use /roadmap-maintain or /roadmap-update for new workflows. Install the roadmapsmith CLI separately for actual command execution; roadmapsmith status is the public readiness command and roadmapsmith doctor remains a compatibility alias. Then run /reload-skills and, if applicable, /reload-plugins. Codex native plugin installs use the repo/package .codex-plugin surface instead of this Claude-specific skills CLI path."
|
|
24
|
+
"notes": "Recommended Claude Code install path for native GUI slash commands. Canonical surfaces: /roadmap, /roadmap-zero, /roadmap-maintain, /roadmap-status, /roadmap-validate, /roadmap-update, /roadmap-setup. The public CLI update family covers both checklist refresh and verified single-task completion; sync remains the advanced alias for the mutating refresh path. /roadmap-maintain now owns only existing managed roadmap blocks, while /roadmap-update is the conservative annotation path for authored roadmaps without markers. /roadmap-zero can consume a complete discovery brief from config plus CLI flags in non-interactive environments. Advanced surfaces: /roadmap-init, /roadmap-generate, /roadmap-audit. DEPRECATED: /roadmap-sync remains only as a compatibility root for existing automation; use /roadmap-maintain or /roadmap-update for new workflows. Install the roadmapsmith CLI separately for actual command execution; roadmapsmith status is the public readiness command and roadmapsmith doctor remains a compatibility alias. Then run /reload-skills and, if applicable, /reload-plugins. Codex native plugin installs use the repo/package .codex-plugin surface instead of this Claude-specific skills CLI path."
|
|
25
25
|
},
|
|
26
26
|
"skills": [
|
|
27
27
|
{
|
|
28
28
|
"name": "roadmap",
|
|
29
29
|
"path": "skills/roadmap",
|
|
30
30
|
"description": "Native slash palette for RoadmapSmith commands and recommended entrypoints across supported hosts.",
|
|
31
|
-
"version": "0.9.
|
|
31
|
+
"version": "0.9.34"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"name": "roadmap-zero",
|
|
35
35
|
"path": "skills/roadmap-zero",
|
|
36
|
-
"description": "Native slash entrypoint for
|
|
37
|
-
"version": "0.9.
|
|
36
|
+
"description": "Native slash entrypoint for Zero Mode, including non-interactive config-plus-flag discovery.",
|
|
37
|
+
"version": "0.9.34"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"name": "roadmap-maintain",
|
|
41
41
|
"path": "skills/roadmap-maintain",
|
|
42
|
-
"description": "Native slash entrypoint for
|
|
43
|
-
"version": "0.9.
|
|
42
|
+
"description": "Native slash entrypoint for conservative managed-block maintenance plus sync and audit output.",
|
|
43
|
+
"version": "0.9.34"
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
"name": "roadmap-status",
|
|
47
47
|
"path": "skills/roadmap-status",
|
|
48
48
|
"description": "Native slash readiness check grounded in roadmapsmith status JSON.",
|
|
49
|
-
"version": "0.9.
|
|
49
|
+
"version": "0.9.34"
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"name": "roadmap-init",
|
|
53
53
|
"path": "skills/roadmap-init",
|
|
54
54
|
"description": "Native slash entrypoint for creating ROADMAP.md and AGENTS.md.",
|
|
55
|
-
"version": "0.9.
|
|
55
|
+
"version": "0.9.34"
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"name": "roadmap-generate",
|
|
59
59
|
"path": "skills/roadmap-generate",
|
|
60
60
|
"description": "Native slash entrypoint for managed roadmap updates that require --full-regen before destructive replacement.",
|
|
61
|
-
"version": "0.9.
|
|
61
|
+
"version": "0.9.34"
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"name": "roadmap-validate",
|
|
65
65
|
"path": "skills/roadmap-validate",
|
|
66
66
|
"description": "Native slash entrypoint for evidence-backed roadmap validation.",
|
|
67
|
-
"version": "0.9.
|
|
67
|
+
"version": "0.9.34"
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"name": "roadmap-update",
|
|
71
71
|
"path": "skills/roadmap-update",
|
|
72
|
-
"description": "Native slash entrypoint for evidence-backed
|
|
73
|
-
"version": "0.9.
|
|
72
|
+
"description": "Native slash entrypoint for evidence-backed inline annotation refresh and verified single-task completion.",
|
|
73
|
+
"version": "0.9.34"
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
"name": "roadmap-sync",
|
|
77
77
|
"path": "skills/roadmap-sync",
|
|
78
78
|
"description": "DEPRECATED legacy compatibility root; use roadmap-maintain or roadmap-update.",
|
|
79
|
-
"version": "0.9.
|
|
79
|
+
"version": "0.9.34"
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"name": "roadmap-audit",
|
|
83
83
|
"path": "skills/roadmap-audit",
|
|
84
84
|
"description": "Native slash entrypoint for the advanced sync-plus-audit mutating summary workflow.",
|
|
85
|
-
"version": "0.9.
|
|
85
|
+
"version": "0.9.34"
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
"name": "roadmap-setup",
|
|
89
89
|
"path": "skills/roadmap-setup",
|
|
90
90
|
"description": "Native slash entrypoint for generating RoadmapSmith host integration files.",
|
|
91
|
-
"version": "0.9.
|
|
91
|
+
"version": "0.9.34"
|
|
92
92
|
}
|
|
93
93
|
]
|
|
94
94
|
}
|
package/src/zero.js
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
|
|
5
|
+
const ZERO_MODE_FLAG_SPECS = {
|
|
6
|
+
productName: { flag: '--product-name', configPath: 'product.name', type: 'scalar' },
|
|
7
|
+
primaryUser: { flag: '--primary-user', configPath: 'product.primaryUser', type: 'scalar', required: true },
|
|
8
|
+
problemStatement: { flag: '--problem-statement', configPath: 'zeroMode.problemStatement', type: 'scalar', required: true },
|
|
9
|
+
targetOutcome: { flag: '--target-outcome', configPath: 'product.targetOutcome', type: 'scalar', required: true },
|
|
10
|
+
antiGoals: { flag: '--anti-goal', configPath: 'product.antiGoals', type: 'list' },
|
|
11
|
+
preferredStack: { flag: '--preferred-stack', configPath: 'zeroMode.preferredStack', type: 'scalar' },
|
|
12
|
+
constraints: { flag: '--constraint', configPath: 'zeroMode.constraints', type: 'list' },
|
|
13
|
+
doneCriteria: { flag: '--done-criterion', configPath: 'zeroMode.doneCriteria', type: 'list', required: true }
|
|
14
|
+
};
|
|
15
|
+
|
|
5
16
|
const ZERO_MODE_QUESTIONS = [
|
|
6
17
|
{ id: 'productName', prompt: '1. What product are we building?' },
|
|
7
18
|
{ id: 'primaryUser', prompt: '2. Who is the target user?' },
|
|
@@ -54,6 +65,80 @@ function buildZeroModeDefaults(projectRoot, config) {
|
|
|
54
65
|
};
|
|
55
66
|
}
|
|
56
67
|
|
|
68
|
+
function getSingleFlagValue(value) {
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
return value[value.length - 1];
|
|
71
|
+
}
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function getListFlagValues(value) {
|
|
76
|
+
const rawValues = Array.isArray(value) ? value : [value];
|
|
77
|
+
return rawValues.flatMap((item) => splitListAnswer(item));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function resolveZeroModeAnswers(projectRoot, config, flags = {}) {
|
|
81
|
+
const defaults = buildZeroModeDefaults(projectRoot, config);
|
|
82
|
+
const answers = { ...defaults };
|
|
83
|
+
|
|
84
|
+
for (const [field, spec] of Object.entries(ZERO_MODE_FLAG_SPECS)) {
|
|
85
|
+
const flagKey = spec.flag.slice(2);
|
|
86
|
+
if (!Object.prototype.hasOwnProperty.call(flags, flagKey)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (spec.type === 'list') {
|
|
91
|
+
answers[field] = getListFlagValues(flags[flagKey]).join('; ');
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const raw = getSingleFlagValue(flags[flagKey]);
|
|
96
|
+
answers[field] = String(raw == null ? '' : raw).trim();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!String(answers.productName || '').trim()) {
|
|
100
|
+
answers.productName = path.basename(projectRoot);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return answers;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getMissingZeroModeFields(answers = {}) {
|
|
107
|
+
const missing = [];
|
|
108
|
+
for (const [field, spec] of Object.entries(ZERO_MODE_FLAG_SPECS)) {
|
|
109
|
+
if (!spec.required) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (spec.type === 'list') {
|
|
114
|
+
if (splitListAnswer(answers[field]).length === 0) {
|
|
115
|
+
missing.push({
|
|
116
|
+
field,
|
|
117
|
+
flag: spec.flag,
|
|
118
|
+
configPath: spec.configPath
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!String(answers[field] || '').trim()) {
|
|
125
|
+
missing.push({
|
|
126
|
+
field,
|
|
127
|
+
flag: spec.flag,
|
|
128
|
+
configPath: spec.configPath
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return missing;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function formatMissingZeroModeFields(missingFields) {
|
|
136
|
+
return missingFields.map((item) => {
|
|
137
|
+
const label = item.field.replace(/([A-Z])/g, ' $1').toLowerCase();
|
|
138
|
+
return `${label} (${item.flag} or config ${item.configPath})`;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
57
142
|
async function collectZeroModeAnswers(ask, defaults = {}) {
|
|
58
143
|
const answers = {};
|
|
59
144
|
for (const question of ZERO_MODE_QUESTIONS) {
|
|
@@ -124,6 +209,9 @@ module.exports = {
|
|
|
124
209
|
buildZeroModeConfigPatch,
|
|
125
210
|
buildZeroModeDefaults,
|
|
126
211
|
collectZeroModeAnswers,
|
|
212
|
+
formatMissingZeroModeFields,
|
|
213
|
+
getMissingZeroModeFields,
|
|
127
214
|
isInteractiveTerminal,
|
|
215
|
+
resolveZeroModeAnswers,
|
|
128
216
|
splitListAnswer
|
|
129
217
|
};
|