@codeyam/codeyam-cli 0.1.18 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/analyzer-template/.build-info.json +6 -6
  2. package/analyzer-template/log.txt +3 -3
  3. package/codeyam-cli/src/cli.js +15 -0
  4. package/codeyam-cli/src/cli.js.map +1 -1
  5. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js +9 -9
  6. package/codeyam-cli/src/commands/editor.js +334 -254
  7. package/codeyam-cli/src/commands/editor.js.map +1 -1
  8. package/codeyam-cli/src/utils/__tests__/editorGuardMiddleware.test.js +67 -0
  9. package/codeyam-cli/src/utils/__tests__/editorGuardMiddleware.test.js.map +1 -0
  10. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js +16 -1
  11. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js.map +1 -1
  12. package/codeyam-cli/src/utils/editorGuard.js +36 -0
  13. package/codeyam-cli/src/utils/editorGuard.js.map +1 -0
  14. package/codeyam-cli/src/utils/editorScenarios.js +1 -1
  15. package/codeyam-cli/src/utils/simulationGateMiddleware.js +9 -0
  16. package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -1
  17. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js +17 -6
  18. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js.map +1 -1
  19. package/codeyam-cli/src/webserver/__tests__/stripClaudeCommand.test.js +79 -0
  20. package/codeyam-cli/src/webserver/__tests__/stripClaudeCommand.test.js.map +1 -0
  21. package/codeyam-cli/src/webserver/build/client/assets/{editor.entity.(_sha)-Bnx7yUP0.js → editor.entity.(_sha)-CGzKlIHg.js} +13 -13
  22. package/codeyam-cli/src/webserver/build/client/assets/globals-Yn9W3zp3.css +1 -0
  23. package/codeyam-cli/src/webserver/build/client/assets/{manifest-b9d4d267.js → manifest-2ef99f38.js} +1 -1
  24. package/codeyam-cli/src/webserver/build/client/assets/{root-DB3O9_9j.js → root-BxUQigda.js} +5 -5
  25. package/codeyam-cli/src/webserver/build/server/assets/{analysisRunner-CGwTN3V2.js → analysisRunner-BPmOG9bE.js} +1 -1
  26. package/codeyam-cli/src/webserver/build/server/assets/{index-D4meMKy3.js → index-Cd-ufawF.js} +1 -1
  27. package/codeyam-cli/src/webserver/build/server/assets/{init-odGJ_c2-.js → init-CzeBGOto.js} +1 -1
  28. package/codeyam-cli/src/webserver/build/server/assets/{server-build-TmPfF7pT.js → server-build-Dht7CKXY.js} +102 -102
  29. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  30. package/codeyam-cli/src/webserver/build-info.json +5 -5
  31. package/codeyam-cli/src/webserver/terminalServer.js +85 -19
  32. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  33. package/codeyam-cli/templates/__tests__/editor-step-hook.prompt-capture.test.ts +118 -0
  34. package/codeyam-cli/templates/codeyam-editor-claude.md +2 -0
  35. package/codeyam-cli/templates/codeyam-editor-reference.md +1 -1
  36. package/codeyam-cli/templates/editor-step-hook.py +72 -46
  37. package/package.json +1 -1
  38. package/codeyam-cli/src/webserver/build/client/assets/globals-fAqOD9ex.css +0 -1
@@ -16,7 +16,7 @@ import { APP_FORMATS, TECH_STACKS } from "../data/techStacks.js";
16
16
  import { getProjectRoot as getStateProjectRoot } from "../state.js";
17
17
  import initCommand from "./init.js";
18
18
  import { scanScenarioFiles, syncScenarioFilesToDatabase, backfillScenarioMetadata, migrateScenarioFormats, } from "../utils/scenariosManifest.js";
19
- import { clearEditorState, clearEditorUserPrompt, validateStepTransition, backfillEntityShaOnScenarios, } from "../utils/editorScenarios.js";
19
+ import { clearEditorState, validateStepTransition, backfillEntityShaOnScenarios, } from "../utils/editorScenarios.js";
20
20
  import { validateSeedData, detectSeedAdapter, validateSeedKeysAgainstPrisma, } from "../utils/editorSeedAdapter.js";
21
21
  import { deleteScenarioViaCli } from "../utils/editorDeleteScenario.js";
22
22
  import { buildEditorApiRequest, callEditorApi, EDITOR_API_SUBCOMMANDS, } from "../utils/editorApi.js";
@@ -27,21 +27,23 @@ const __filename = fileURLToPath(import.meta.url);
27
27
  const __dirname = path.dirname(__filename);
28
28
  const STEP_LABELS = {
29
29
  1: 'Plan',
30
- 2: 'Prototype',
31
- 3: 'Confirm',
32
- 4: 'Deconstruct',
33
- 5: 'Extract',
34
- 6: 'Glossary',
35
- 7: 'Analyze',
36
- 8: 'App Scenarios',
37
- 9: 'User Scenarios',
38
- 10: 'Verify',
39
- 11: 'Journal',
40
- 12: 'Review',
41
- 13: 'Present',
42
- 14: 'Commit',
43
- 15: 'Finalize',
44
- 16: 'Push',
30
+ 2: 'Prepare',
31
+ 3: 'Prototype',
32
+ 4: 'Verify Prototype',
33
+ 5: 'Confirm',
34
+ 6: 'Deconstruct',
35
+ 7: 'Extract',
36
+ 8: 'Glossary',
37
+ 9: 'Analyze',
38
+ 10: 'App Scenarios',
39
+ 11: 'User Scenarios',
40
+ 12: 'Verify',
41
+ 13: 'Journal',
42
+ 14: 'Review',
43
+ 15: 'Present',
44
+ 16: 'Commit',
45
+ 17: 'Finalize',
46
+ 18: 'Push',
45
47
  };
46
48
  const MIGRATION_STEP_LABELS = {
47
49
  1: 'Survey',
@@ -122,8 +124,9 @@ function writeState(root, state) {
122
124
  }
123
125
  /**
124
126
  * Clear the editor state (for starting a new feature).
125
- * Does NOT clear the user prompt file — that's handled separately
126
- * via clearEditorUserPrompt when the previous feature commits.
127
+ * Does NOT clear the user prompt file — the prompt is cleared
128
+ * by the journal API after recording, and the hook captures
129
+ * a fresh prompt for the next feature on UserPromptSubmit.
127
130
  */
128
131
  function clearState(root) {
129
132
  clearEditorState(root);
@@ -208,8 +211,9 @@ function printAppScenarioInstructions(pageName, route) {
208
211
  const root = process.cwd();
209
212
  const hasSeedAdapter = !!detectSeedAdapter(root);
210
213
  checkbox('Check existing scenarios: `codeyam editor scenarios`');
211
- console.log(chalk.dim(' Review existing scenarios — reuse and update their data rather than'));
212
- console.log(chalk.dim(' creating duplicates. Re-register with the same name to update a scenario.'));
214
+ console.log(chalk.dim(' Review existing scenarios — enhance their seed data to exercise new features.'));
215
+ console.log(chalk.dim(' A rich scenario that exercises 5 features is better than 5 thin scenarios with one feature each.'));
216
+ console.log(chalk.dim(' Rename scenarios if their data scope has grown beyond the original name.'));
213
217
  console.log();
214
218
  console.log(chalk.bold.yellow('App scenarios vs component scenarios — these are DIFFERENT:'));
215
219
  console.log(chalk.yellow(' App scenarios: show the FULL PAGE with seeded data at a real route (/, /library, etc.)'));
@@ -305,7 +309,7 @@ function printExtractionPlanInstructions() {
305
309
  console.log(chalk.yellow(' — Where it currently lives (source file + approximate lines)'));
306
310
  console.log(chalk.yellow(' — Where it will go (new file path)'));
307
311
  console.log();
308
- console.log(chalk.dim('Present the numbered plan, then proceed to step 5 to execute it.'));
312
+ console.log(chalk.dim('Present the numbered plan, then proceed to step 7 to execute it.'));
309
313
  }
310
314
  /**
311
315
  * Shared component capture instructions used by editor Step 7 and migration Steps 3/8.
@@ -362,13 +366,13 @@ function stepHeader(step, title, feature) {
362
366
  console.log();
363
367
  }
364
368
  /**
365
- * Print a colored progress tracker showing all 16 steps.
369
+ * Print a colored progress tracker showing all 18 steps.
366
370
  * Steps before `current` are green ✓, `current` is bold cyan →, future steps are dim ○.
367
371
  */
368
372
  function printProgressTracker(current) {
369
373
  console.log();
370
374
  console.log(chalk.dim(' ┌─────────────────────────────────────┐'));
371
- for (let i = 1; i <= 16; i++) {
375
+ for (let i = 1; i <= 18; i++) {
372
376
  const label = STEP_LABELS[i];
373
377
  const num = i < 10 ? ` ${i}` : `${i}`;
374
378
  const content = `${num}. ${label.padEnd(28)}`;
@@ -406,13 +410,13 @@ function stopGate(current, opts) {
406
410
  console.log(chalk.yellow('For the CURRENT step (→), show each checklist item with ✓ (done) or ✗ (skipped + reason).'));
407
411
  console.log(chalk.yellow('If any items are ✗, explain why and ask if the user wants to address them.'));
408
412
  console.log();
409
- if (current < 16) {
413
+ if (current < 18) {
410
414
  console.log(chalk.green('When done, run: ') +
411
415
  chalk.bold(`codeyam editor ${current + 1}`));
412
416
  }
413
417
  else {
414
418
  console.log(chalk.green('Feature complete! Run: ') +
415
- chalk.bold('codeyam editor 1') +
419
+ chalk.bold('codeyam editor steps') +
416
420
  chalk.green(' to start the next feature'));
417
421
  }
418
422
  console.log();
@@ -428,34 +432,36 @@ function printResumptionHeader(step) {
428
432
  'Check if plan was already written to context file:\n `cat .codeyam/editor-mode-context.md`',
429
433
  ],
430
434
  2: ['Check if project files already exist:\n `ls package.json src/`'],
431
- 3: ['This is a confirmation step — just re-present to user'],
432
- 4: [
435
+ 3: ['Re-check is safe — just re-run the step'],
436
+ 4: ['Re-verify is safe to repeat — just re-run the checks'],
437
+ 5: ['This is a confirmation step — just re-present to user'],
438
+ 6: [
433
439
  'Check if extraction plan already exists in context file:\n `cat .codeyam/editor-mode-context.md`',
434
440
  ],
435
- 5: [
441
+ 7: [
436
442
  'Check if components/functions already extracted:\n `ls src/components/ src/lib/`',
437
443
  ],
438
- 6: [
444
+ 8: [
439
445
  'Check if glossary already populated:\n `cat .codeyam/glossary.json`',
440
446
  ],
441
- 7: ['Check if isolation routes and registered scenarios already exist'],
442
- 8: ['Check existing scenarios:\n `codeyam editor scenarios`'],
443
- 9: [
447
+ 9: ['Check if isolation routes and registered scenarios already exist'],
448
+ 10: ['Check existing scenarios:\n `codeyam editor scenarios`'],
449
+ 11: [
444
450
  'Check existing user-persona scenarios:\n `codeyam editor scenarios`',
445
451
  ],
446
- 10: ['Re-verify is safe to repeat — just re-run the checks'],
447
- 11: [
452
+ 12: ['Re-verify is safe to repeat — just re-run the checks'],
453
+ 13: [
448
454
  'Check if a journal entry already exists for this feature:\n `codeyam editor journal-list`',
449
455
  'If an entry exists, use PATCH to update it — do NOT create a new one',
450
456
  ],
451
- 12: ['Re-verify is safe to repeat — just re-run the checks'],
452
- 13: ['Check if commit already made:\n `git log --oneline -3`'],
453
- 14: ['Check if commit already made:\n `git log --oneline -3`'],
454
- 15: [
457
+ 14: ['Re-verify is safe to repeat — just re-run the checks'],
458
+ 15: ['Check if commit already made:\n `git log --oneline -3`'],
459
+ 16: ['Check if commit already made:\n `git log --oneline -3`'],
460
+ 17: [
455
461
  'Check if journal was already updated with commit SHA:\n `codeyam editor journal-list`',
456
462
  'Check if commit was already amended:\n `git log --oneline -3`',
457
463
  ],
458
- 16: [
464
+ 18: [
459
465
  'Check if already pushed:\n `git remote -v && git log --oneline origin/HEAD..HEAD 2>/dev/null`',
460
466
  ],
461
467
  };
@@ -562,7 +568,7 @@ function parseDebugTargets(target) {
562
568
  }
563
569
  if (entry.startsWith('step-')) {
564
570
  const num = parseInt(entry.replace('step-', ''), 10);
565
- if (!isNaN(num) && num >= 1 && num <= 16) {
571
+ if (!isNaN(num) && num >= 1 && num <= 18) {
566
572
  valid.add(`step-${num}`);
567
573
  continue;
568
574
  }
@@ -788,24 +794,26 @@ function printCycleOverview(root, state) {
788
794
  console.log(chalk.yellow('This applies even after committing — always use the change workflow.'));
789
795
  }
790
796
  else {
791
- console.log('Each feature follows 16 steps. You MUST run each command in order:');
797
+ console.log('Each feature follows 18 steps. You MUST run each command in order:');
792
798
  console.log();
793
- console.log(` ${chalk.bold.yellow(' 1')} ${chalk.bold('Plan')} — Plan the feature, confirm with user`);
794
- console.log(` ${chalk.bold.yellow(' 2')} ${chalk.bold('Prototype')} Build a working prototype fast`);
795
- console.log(` ${chalk.bold.yellow(' 3')} ${chalk.bold('Confirm')} Confirm prototype with user`);
796
- console.log(` ${chalk.bold.yellow(' 4')} ${chalk.bold('Deconstruct')} Read code, plan all extractions`);
797
- console.log(` ${chalk.bold.yellow(' 5')} ${chalk.bold('Extract')} TDD extraction of functions + components`);
798
- console.log(` ${chalk.bold.yellow(' 6')} ${chalk.bold('Glossary')} — Record functions in glossary`);
799
- console.log(` ${chalk.bold.yellow(' 7')} ${chalk.bold('Analyze')} Analyze and verify components`);
800
- console.log(` ${chalk.bold.yellow(' 8')} ${chalk.bold('App Scenarios')} Create app-level scenarios`);
801
- console.log(` ${chalk.bold.yellow(' 9')} ${chalk.bold('User Scenarios')} Create user-persona scenarios`);
802
- console.log(` ${chalk.bold.yellow('10')} ${chalk.bold('Verify')} Review screenshots, check for errors`);
803
- console.log(` ${chalk.bold.yellow('11')} ${chalk.bold('Journal')} — Create/update journal entry`);
804
- console.log(` ${chalk.bold.yellow('12')} ${chalk.bold('Review')} Verify screenshots and audit`);
805
- console.log(` ${chalk.bold.yellow('13')} ${chalk.bold('Present')} Present summary, get approval`);
806
- console.log(` ${chalk.bold.yellow('14')} ${chalk.bold('Commit')} Commit all changes`);
807
- console.log(` ${chalk.bold.yellow('15')} ${chalk.bold('Finalize')} Journal update + amend commit`);
808
- console.log(` ${chalk.bold.yellow('16')} ${chalk.bold('Push')} Push to remote`);
799
+ console.log(` ${chalk.bold.yellow(' 1')} ${chalk.bold('Plan')} — Plan the feature, confirm with user`);
800
+ console.log(` ${chalk.bold.yellow(' 2')} ${chalk.bold('Prepare')} Set up project and dependencies`);
801
+ console.log(` ${chalk.bold.yellow(' 3')} ${chalk.bold('Prototype')} Build a working prototype fast`);
802
+ console.log(` ${chalk.bold.yellow(' 4')} ${chalk.bold('Verify Prototype')} Verify prototype works correctly`);
803
+ console.log(` ${chalk.bold.yellow(' 5')} ${chalk.bold('Confirm')} Confirm prototype with user`);
804
+ console.log(` ${chalk.bold.yellow(' 6')} ${chalk.bold('Deconstruct')} — Read code, plan all extractions`);
805
+ console.log(` ${chalk.bold.yellow(' 7')} ${chalk.bold('Extract')} TDD extraction of functions + components`);
806
+ console.log(` ${chalk.bold.yellow(' 8')} ${chalk.bold('Glossary')} Record functions in glossary`);
807
+ console.log(` ${chalk.bold.yellow(' 9')} ${chalk.bold('Analyze')} Analyze and verify components`);
808
+ console.log(` ${chalk.bold.yellow('10')} ${chalk.bold('App Scenarios')} Create app-level scenarios`);
809
+ console.log(` ${chalk.bold.yellow('11')} ${chalk.bold('User Scenarios')} — Create user-persona scenarios`);
810
+ console.log(` ${chalk.bold.yellow('12')} ${chalk.bold('Verify')} Review screenshots, check for errors`);
811
+ console.log(` ${chalk.bold.yellow('13')} ${chalk.bold('Journal')} Create/update journal entry`);
812
+ console.log(` ${chalk.bold.yellow('14')} ${chalk.bold('Review')} Verify screenshots and audit`);
813
+ console.log(` ${chalk.bold.yellow('15')} ${chalk.bold('Present')} Present summary, get approval`);
814
+ console.log(` ${chalk.bold.yellow('16')} ${chalk.bold('Commit')} Commit all changes`);
815
+ console.log(` ${chalk.bold.yellow('17')} ${chalk.bold('Finalize')} — Journal update + amend commit`);
816
+ console.log(` ${chalk.bold.yellow('18')} ${chalk.bold('Push')} — Push to remote`);
809
817
  console.log();
810
818
  console.log(chalk.green('Start now: ') + chalk.bold('codeyam editor 1'));
811
819
  console.log(chalk.dim(' If the user already described what they want, pass it: codeyam editor 1 --prompt "their message"'));
@@ -897,7 +905,7 @@ function printStep1(root, feature, options, userPrompt) {
897
905
  console.log(chalk.dim(' Replace "Feature Name" with a short title for what you just described.'));
898
906
  console.log();
899
907
  }
900
- // ─── Step 2: Prototype ────────────────────────────────────────────────
908
+ // ─── Step 2: Prepare ──────────────────────────────────────────────────
901
909
  function printStep2(root, feature) {
902
910
  const port = getServerPort();
903
911
  const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
@@ -914,12 +922,19 @@ function printStep2(root, feature) {
914
922
  appFormats: prevState?.appFormats,
915
923
  techStackId: prevState?.techStackId,
916
924
  });
917
- logEvent(root, 'step', { step: 2, label: 'Prototype', feature });
918
- stepHeader(2, 'Prototype', feature);
925
+ logEvent(root, 'step', { step: 2, label: 'Prepare', feature });
926
+ stepHeader(2, 'Prepare', feature);
919
927
  if (isResuming) {
920
928
  printResumptionHeader(2);
921
929
  }
922
- console.log('Build fast with real data. Prioritize speed over quality.');
930
+ console.log(chalk.bold.red('━━━ MANDATORY: CREATE TASK NOW ━━━'));
931
+ console.log();
932
+ console.log(chalk.red(`Run TaskCreate with title: "Use \`codeyam editor\` to work on ${feature}"`));
933
+ console.log(chalk.red('DO NOT read files, scaffold, write code, or do ANYTHING else until this task exists.'));
934
+ console.log(chalk.red('This is not optional. Create the task, then continue below.'));
935
+ console.log(chalk.bold.red('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
936
+ console.log();
937
+ console.log('Get the project ready to build.');
923
938
  console.log();
924
939
  // If no project exists yet, include scaffolding instructions first
925
940
  if (!projectExists) {
@@ -948,7 +963,6 @@ function printStep2(root, feature) {
948
963
  console.log(chalk.dim(' Key: import { prisma } from "@/app/lib/prisma" in API routes.'));
949
964
  console.log(chalk.dim(' Key: Seed scripts must use the adapter pattern (see prisma/seed.ts).'));
950
965
  console.log();
951
- console.log(chalk.bold('Build the feature:'));
952
966
  }
953
967
  else {
954
968
  console.log(chalk.bold('Prepare the database for this feature:'));
@@ -964,6 +978,32 @@ function printStep2(root, feature) {
964
978
  console.log(chalk.dim(' If no existing scenario fits, use the default seed: npm run db:seed'));
965
979
  console.log();
966
980
  }
981
+ stopGate(2);
982
+ }
983
+ // ─── Step 3: Prototype ────────────────────────────────────────────────
984
+ function printStep3(root, feature) {
985
+ const port = getServerPort();
986
+ const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
987
+ const projectExists = hasProject(root);
988
+ const prevState = readState(root);
989
+ const isResuming = prevState?.step === 3;
990
+ const now = new Date().toISOString();
991
+ writeState(root, {
992
+ feature,
993
+ step: 3,
994
+ label: STEP_LABELS[3],
995
+ startedAt: isResuming ? prevState.startedAt : now,
996
+ featureStartedAt: prevState?.featureStartedAt || now,
997
+ appFormats: prevState?.appFormats,
998
+ techStackId: prevState?.techStackId,
999
+ });
1000
+ logEvent(root, 'step', { step: 3, label: 'Prototype', feature });
1001
+ stepHeader(3, 'Prototype', feature);
1002
+ if (isResuming) {
1003
+ printResumptionHeader(3);
1004
+ }
1005
+ console.log('Build fast with real data. Prioritize speed over quality.');
1006
+ console.log();
967
1007
  console.log(chalk.bold('Checklist:'));
968
1008
  checkbox('Create API routes that read from the database via Prisma');
969
1009
  if (!projectExists) {
@@ -1012,6 +1052,28 @@ function printStep2(root, feature) {
1012
1052
  console.log(chalk.cyan(` codeyam editor preview '{"path":"/drinks/1","dimension":"${dim}"}'`));
1013
1053
  printDimensionGuidance(dim, dimNames);
1014
1054
  console.log();
1055
+ stopGate(3);
1056
+ }
1057
+ // ─── Step 4: Verify Prototype ─────────────────────────────────────────
1058
+ function printStep4(root, feature) {
1059
+ const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1060
+ const prevState = readState(root);
1061
+ const isResuming = prevState?.step === 4;
1062
+ const now = new Date().toISOString();
1063
+ writeState(root, {
1064
+ feature,
1065
+ step: 4,
1066
+ label: STEP_LABELS[4],
1067
+ startedAt: isResuming ? prevState.startedAt : now,
1068
+ featureStartedAt: prevState?.featureStartedAt || now,
1069
+ });
1070
+ logEvent(root, 'step', { step: 4, label: 'Verify Prototype', feature });
1071
+ stepHeader(4, 'Verify Prototype', feature);
1072
+ if (isResuming) {
1073
+ printResumptionHeader(4);
1074
+ }
1075
+ console.log('Verify everything works before presenting the prototype.');
1076
+ console.log();
1015
1077
  console.log(chalk.bold('Verify the dev server:'));
1016
1078
  console.log(chalk.dim(` # Get dev server URL: codeyam editor dev-server`));
1017
1079
  console.log(chalk.dim(' # Check page loads: curl -s -o /dev/null -w "%{http_code}" http://localhost:<dev-port>'));
@@ -1038,26 +1100,26 @@ function printStep2(root, feature) {
1038
1100
  console.log(chalk.dim(' A new clone should work with just: git clone → npm run setup → npm run dev'));
1039
1101
  console.log();
1040
1102
  console.log(chalk.dim('Focus on building the prototype. Scenarios and refactoring happen in later steps.'));
1041
- stopGate(2);
1103
+ stopGate(4);
1042
1104
  }
1043
- // ─── Step 3: Confirm ──────────────────────────────────────────────────
1044
- function printStep3(root, feature) {
1105
+ // ─── Step 5: Confirm ──────────────────────────────────────────────────
1106
+ function printStep5(root, feature) {
1045
1107
  const port = getServerPort();
1046
1108
  const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1047
1109
  const prevState = readState(root);
1048
- const isResuming = prevState?.step === 3;
1110
+ const isResuming = prevState?.step === 5;
1049
1111
  const now = new Date().toISOString();
1050
1112
  writeState(root, {
1051
1113
  feature,
1052
- step: 3,
1053
- label: STEP_LABELS[3],
1114
+ step: 5,
1115
+ label: STEP_LABELS[5],
1054
1116
  startedAt: isResuming ? prevState.startedAt : now,
1055
1117
  featureStartedAt: prevState?.featureStartedAt || now,
1056
1118
  });
1057
- logEvent(root, 'step', { step: 3, label: 'Confirm', feature });
1058
- stepHeader(3, 'Confirm', feature);
1119
+ logEvent(root, 'step', { step: 5, label: 'Confirm', feature });
1120
+ stepHeader(5, 'Confirm', feature);
1059
1121
  if (isResuming) {
1060
- printResumptionHeader(3);
1122
+ printResumptionHeader(5);
1061
1123
  }
1062
1124
  console.log('Summarize what was built and get user confirmation.');
1063
1125
  console.log();
@@ -1074,6 +1136,11 @@ function printStep3(root, feature) {
1074
1136
  console.log(chalk.dim(' If there are errors, fix the underlying issue before presenting.'));
1075
1137
  checkbox('Verify `hasContent=true` and `liveErrors=0` — do NOT ask the user to confirm if the preview is broken');
1076
1138
  console.log();
1139
+ console.log(chalk.bold('Verify the captured user prompt:'));
1140
+ checkbox("Read `.codeyam/editor-user-prompt.txt` — this is the user's original feature request");
1141
+ checkbox('If the file is missing or does not match what the user actually asked for, write the correct prompt text to `.codeyam/editor-user-prompt.txt`');
1142
+ console.log(chalk.dim(" This must be the user's exact words, not a summary. It gets recorded in the journal."));
1143
+ console.log();
1077
1144
  console.log(chalk.bold('Then present to the user:'));
1078
1145
  checkbox('Summarize what was built (routes, components, data)');
1079
1146
  checkbox(`Navigate the preview to the feature's primary page: \`codeyam editor preview '{"path":"/your-page","dimension":"${dim}"}'\``);
@@ -1087,62 +1154,62 @@ function printStep3(root, feature) {
1087
1154
  checkbox('Ask the user: "Does everything work as expected?"');
1088
1155
  console.log();
1089
1156
  console.log(chalk.bold('Present a selection menu to the user (use AskUserQuestion with these EXACT option labels):'));
1090
- console.log(chalk.green(' Option 1 label: "The live preview is displaying what I expected"') + chalk.dim(' — proceed to step 4'));
1157
+ console.log(chalk.green(' Option 1 label: "The live preview is displaying what I expected"') + chalk.dim(' — proceed to step 6'));
1091
1158
  console.log(chalk.yellow(' Option 2 label: "I\'d like some changes"') +
1092
- chalk.dim(' — make changes, refresh preview, re-run `codeyam editor 3`'));
1159
+ chalk.dim(' — make changes, refresh preview, re-run `codeyam editor 5`'));
1093
1160
  console.log();
1094
1161
  console.log(chalk.dim('Wait for user approval before moving on. Refactoring and scenarios happen in later steps.'));
1095
- stopGate(3, { confirm: true });
1162
+ stopGate(5, { confirm: true });
1096
1163
  }
1097
- // ─── Step 4: Deconstruct ──────────────────────────────────────────────
1098
- function printStep4(root, feature) {
1164
+ // ─── Step 6: Deconstruct ──────────────────────────────────────────────
1165
+ function printStep6(root, feature) {
1099
1166
  const prevState = readState(root);
1100
- const isResuming = prevState?.step === 4;
1167
+ const isResuming = prevState?.step === 6;
1101
1168
  const now = new Date().toISOString();
1102
1169
  writeState(root, {
1103
1170
  feature,
1104
- step: 4,
1105
- label: STEP_LABELS[4],
1171
+ step: 6,
1172
+ label: STEP_LABELS[6],
1106
1173
  startedAt: isResuming ? prevState.startedAt : now,
1107
1174
  featureStartedAt: prevState?.featureStartedAt || now,
1108
1175
  });
1109
- logEvent(root, 'step', { step: 4, label: 'Deconstruct', feature });
1110
- stepHeader(4, 'Deconstruct', feature);
1176
+ logEvent(root, 'step', { step: 6, label: 'Deconstruct', feature });
1177
+ stepHeader(6, 'Deconstruct', feature);
1111
1178
  if (isResuming) {
1112
- printResumptionHeader(4);
1179
+ printResumptionHeader(6);
1113
1180
  }
1114
1181
  console.log(chalk.bold('Goal: pages contain ONLY components. Components contain ONLY sub-components.'));
1115
- console.log(chalk.yellow('This step is read and plan only. Code extraction happens in step 5.'));
1182
+ console.log(chalk.yellow('This step is read and plan only. Code extraction happens in step 7.'));
1116
1183
  console.log();
1117
1184
  printExtractionPlanInstructions();
1118
- stopGate(4);
1185
+ stopGate(6);
1119
1186
  }
1120
- // ─── Step 5: Extract ──────────────────────────────────────────────────
1121
- function printStep5(root, feature) {
1187
+ // ─── Step 7: Extract ──────────────────────────────────────────────────
1188
+ function printStep7(root, feature) {
1122
1189
  const port = getServerPort();
1123
1190
  const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1124
1191
  const prevState = readState(root);
1125
- const isResuming = prevState?.step === 5;
1192
+ const isResuming = prevState?.step === 7;
1126
1193
  const now = new Date().toISOString();
1127
1194
  writeState(root, {
1128
1195
  feature,
1129
- step: 5,
1130
- label: STEP_LABELS[5],
1196
+ step: 7,
1197
+ label: STEP_LABELS[7],
1131
1198
  startedAt: isResuming ? prevState.startedAt : now,
1132
1199
  featureStartedAt: prevState?.featureStartedAt || now,
1133
1200
  });
1134
- logEvent(root, 'step', { step: 5, label: 'Extract', feature });
1135
- stepHeader(5, 'Extract', feature);
1201
+ logEvent(root, 'step', { step: 7, label: 'Extract', feature });
1202
+ stepHeader(7, 'Extract', feature);
1136
1203
  if (isResuming) {
1137
- printResumptionHeader(5);
1204
+ printResumptionHeader(7);
1138
1205
  }
1139
- console.log('Execute your extraction plan from step 4.');
1206
+ console.log('Execute your extraction plan from step 6.');
1140
1207
  console.log();
1141
1208
  console.log(chalk.bold('Components:'));
1142
1209
  checkbox('Extract each component from your plan into its own file');
1143
1210
  checkbox('Page/route files must contain ZERO direct JSX — only imported components');
1144
1211
  checkbox('Every component that renders multiple sections must be split into sub-components');
1145
- console.log(chalk.dim(' No tests needed — visual verification happens in step 7'));
1212
+ console.log(chalk.dim(' No tests needed — visual verification happens in step 9'));
1146
1213
  console.log();
1147
1214
  console.log(chalk.bold('Library functions AND hooks (TDD):'));
1148
1215
  checkbox('For each function/hook: write MULTIPLE failing tests FIRST, then extract to make them pass');
@@ -1150,7 +1217,7 @@ function printStep5(root, feature) {
1150
1217
  console.log(chalk.dim(' Aim for 3-8 test cases per function depending on complexity'));
1151
1218
  console.log(chalk.dim(' Hooks count as functions — useDrinks, useAuth, etc. all need test files'));
1152
1219
  checkbox('Place test files next to source: `app/lib/drinks.ts` → `app/lib/drinks.test.ts`');
1153
- console.log(chalk.yellow(' Tests ARE the only coverage for library functions/hooks — step 7 only captures component screenshots.'));
1220
+ console.log(chalk.yellow(' Tests ARE the only coverage for library functions/hooks — step 9 only captures component screenshots.'));
1154
1221
  console.log();
1155
1222
  console.log(chalk.bold('Recursive pass:'));
1156
1223
  checkbox('Re-read EVERY new file you just created — extract components from components, functions from functions');
@@ -1168,55 +1235,55 @@ function printStep5(root, feature) {
1168
1235
  console.log(chalk.dim('Reuse glossary functions when they fit naturally. Extract a new function when the use case diverges.'));
1169
1236
  console.log();
1170
1237
  console.log(chalk.dim('Focus on TDD for functions and extraction for components. Scenarios come in later steps.'));
1171
- stopGate(5);
1238
+ stopGate(7);
1172
1239
  }
1173
- // ─── Step 6: Glossary ─────────────────────────────────────────────────
1174
- function printStep6(root, feature) {
1240
+ // ─── Step 8: Glossary ─────────────────────────────────────────────────
1241
+ function printStep8(root, feature) {
1175
1242
  const prevState = readState(root);
1176
- const isResuming = prevState?.step === 6;
1243
+ const isResuming = prevState?.step === 8;
1177
1244
  const now = new Date().toISOString();
1178
1245
  writeState(root, {
1179
1246
  feature,
1180
- step: 6,
1181
- label: STEP_LABELS[6],
1247
+ step: 8,
1248
+ label: STEP_LABELS[8],
1182
1249
  startedAt: isResuming ? prevState.startedAt : now,
1183
1250
  featureStartedAt: prevState?.featureStartedAt || now,
1184
1251
  });
1185
- logEvent(root, 'step', { step: 6, label: 'Glossary', feature });
1186
- stepHeader(6, 'Glossary', feature);
1252
+ logEvent(root, 'step', { step: 8, label: 'Glossary', feature });
1253
+ stepHeader(8, 'Glossary', feature);
1187
1254
  if (isResuming) {
1188
- printResumptionHeader(6);
1255
+ printResumptionHeader(8);
1189
1256
  }
1190
1257
  console.log('Record all new functions/components in `.codeyam/glossary.json`.');
1191
1258
  console.log();
1192
1259
  printGlossaryInstructions(feature);
1193
1260
  console.log();
1194
1261
  console.log(chalk.dim('Focus on updating the glossary. Application code and scenarios come in later steps.'));
1195
- stopGate(6);
1262
+ stopGate(8);
1196
1263
  }
1197
- // ─── Step 7: Analyze ──────────────────────────────────────────────────
1198
- function printStep7(root, feature) {
1264
+ // ─── Step 9: Analyze ──────────────────────────────────────────────────
1265
+ function printStep9(root, feature) {
1199
1266
  const port = getServerPort();
1200
1267
  const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1201
1268
  const prevState = readState(root);
1202
- const isResuming = prevState?.step === 7;
1269
+ const isResuming = prevState?.step === 9;
1203
1270
  const now = new Date().toISOString();
1204
1271
  writeState(root, {
1205
1272
  feature,
1206
- step: 7,
1207
- label: STEP_LABELS[7],
1273
+ step: 9,
1274
+ label: STEP_LABELS[9],
1208
1275
  startedAt: isResuming ? prevState.startedAt : now,
1209
1276
  featureStartedAt: prevState?.featureStartedAt || now,
1210
1277
  });
1211
- logEvent(root, 'step', { step: 7, label: 'Analyze', feature });
1212
- stepHeader(7, 'Analyze and Verify', feature);
1278
+ logEvent(root, 'step', { step: 9, label: 'Analyze', feature });
1279
+ stepHeader(9, 'Analyze and Verify', feature);
1213
1280
  if (isResuming) {
1214
- printResumptionHeader(7);
1281
+ printResumptionHeader(9);
1215
1282
  }
1216
1283
  console.log('Verify visual components (via isolation routes) and library functions (via tests).');
1217
1284
  console.log();
1218
1285
  console.log(chalk.bold('Visual Components — Component Isolation:'));
1219
- checkbox('List all files with new/modified visual components from step 5');
1286
+ checkbox('List all files with new/modified visual components from step 7');
1220
1287
  checkbox('Check existing scenarios: `codeyam editor scenarios`');
1221
1288
  console.log(chalk.dim(' Reuse and improve existing scenarios where possible — update mock data'));
1222
1289
  console.log(chalk.dim(' to reflect current changes. Add new scenarios only for genuinely new states.'));
@@ -1224,7 +1291,7 @@ function printStep7(root, feature) {
1224
1291
  printComponentCaptureInstructions();
1225
1292
  console.log();
1226
1293
  console.log(chalk.bold('Library Functions — run tests:'));
1227
- checkbox('Run ALL test files created in step 5');
1294
+ checkbox('Run ALL test files created in step 7');
1228
1295
  console.log(chalk.dim(' Example: npx vitest run app/lib/drinks.test.ts'));
1229
1296
  checkbox('Verify every test passes');
1230
1297
  checkbox('If any test fails, fix the source code and re-run');
@@ -1232,29 +1299,29 @@ function printStep7(root, feature) {
1232
1299
  console.log(chalk.dim('Do not proceed until both component isolations and library tests pass.'));
1233
1300
  console.log();
1234
1301
  checkbox('Run `codeyam editor audit` to verify all components have scenarios and all functions/hooks have tests');
1235
- console.log(chalk.red.bold(' The audit is a HARD GATE — step 8 will refuse to run until the audit passes.'));
1302
+ console.log(chalk.red.bold(' The audit is a HARD GATE — step 10 will refuse to run until the audit passes.'));
1236
1303
  console.log(chalk.dim(' When audit passes, the import graph is built automatically for change tracking.'));
1237
1304
  console.log();
1238
- stopGate(7);
1305
+ stopGate(9);
1239
1306
  }
1240
- // ─── Step 8: App Scenarios ────────────────────────────────────────────
1241
- function printStep8(root, feature) {
1307
+ // ─── Step 10: App Scenarios ────────────────────────────────────────────
1308
+ function printStep10(root, feature) {
1242
1309
  const port = getServerPort();
1243
1310
  const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1244
1311
  const prevState = readState(root);
1245
- const isResuming = prevState?.step === 8;
1312
+ const isResuming = prevState?.step === 10;
1246
1313
  const now = new Date().toISOString();
1247
1314
  writeState(root, {
1248
1315
  feature,
1249
- step: 8,
1250
- label: STEP_LABELS[8],
1316
+ step: 10,
1317
+ label: STEP_LABELS[10],
1251
1318
  startedAt: isResuming ? prevState.startedAt : now,
1252
1319
  featureStartedAt: prevState?.featureStartedAt || now,
1253
1320
  });
1254
- logEvent(root, 'step', { step: 8, label: 'App Scenarios', feature });
1255
- stepHeader(8, 'App Scenarios', feature);
1321
+ logEvent(root, 'step', { step: 10, label: 'App Scenarios', feature });
1322
+ stepHeader(10, 'App Scenarios', feature);
1256
1323
  if (isResuming) {
1257
- printResumptionHeader(8);
1324
+ printResumptionHeader(10);
1258
1325
  }
1259
1326
  console.log('Create app-level scenarios with rich data that robustly demonstrates this feature.');
1260
1327
  console.log();
@@ -1276,13 +1343,19 @@ function printStep8(root, feature) {
1276
1343
  console.log(chalk.cyan(" • New data states that can't coexist in one scenario (empty vs rich, error vs success) → new scenario"));
1277
1344
  console.log(chalk.cyan(" • Don't duplicate — if an existing scenario can cover a state with richer data, enhance it instead"));
1278
1345
  console.log();
1346
+ console.log(chalk.bold.cyan('Scenario naming — describe data states, not features:'));
1347
+ console.log(chalk.cyan(' • Name scenarios by what they represent: "Rich Data", "Empty", "Mobile", "Minimal"'));
1348
+ console.log(chalk.cyan(' • When enhancing a scenario with new feature data, update the name if it has grown beyond its original scope'));
1349
+ console.log(chalk.cyan(' • A single rich scenario exercising multiple features is more valuable than separate thin scenarios per feature'));
1350
+ console.log(chalk.cyan(' • Re-register with the same name to update; to rename, register with the new name'));
1351
+ console.log();
1279
1352
  checkbox('Ensure scenarios clearly demonstrate what changed in this session');
1280
1353
  console.log(chalk.dim(' If data models changed: update existing scenarios seed data to match'));
1281
1354
  console.log(chalk.dim(' If UI changed: re-register existing scenarios so screenshots reflect the update'));
1282
1355
  console.log(chalk.dim(' Add new scenarios only for genuinely new data states not covered by existing ones'));
1283
1356
  printAppScenarioInstructions();
1284
1357
  console.log();
1285
- console.log(chalk.dim('Focus on creating and registering app-level scenarios. Code fixes happen in step 10 if needed.'));
1358
+ console.log(chalk.dim('Focus on creating and registering app-level scenarios. Code fixes happen in step 12 if needed.'));
1286
1359
  console.log();
1287
1360
  console.log(chalk.bold.cyan("Verify your work — screenshots don't lie:"));
1288
1361
  console.log(chalk.cyan(' • View every captured screenshot. Does it show what the scenario name promises?'));
@@ -1293,43 +1366,43 @@ function printStep8(root, feature) {
1293
1366
  console.log(chalk.bold.yellow('GATE: Before proceeding, run `codeyam editor scenario-coverage`'));
1294
1367
  console.log(chalk.yellow(' This checks which existing scenarios have stale screenshots.'));
1295
1368
  console.log(chalk.yellow(' Re-register every stale scenario listed until the check passes.'));
1296
- stopGate(8);
1369
+ stopGate(10);
1297
1370
  }
1298
- // ─── Step 9: User Scenarios ───────────────────────────────────────────
1299
- function printStep9(root, feature) {
1371
+ // ─── Step 11: User Scenarios ───────────────────────────────────────────
1372
+ function printStep11(root, feature) {
1300
1373
  const port = getServerPort();
1301
1374
  const prevState = readState(root);
1302
- const isResuming = prevState?.step === 9;
1375
+ const isResuming = prevState?.step === 11;
1303
1376
  const now = new Date().toISOString();
1304
1377
  writeState(root, {
1305
1378
  feature,
1306
- step: 9,
1307
- label: STEP_LABELS[9],
1379
+ step: 11,
1380
+ label: STEP_LABELS[11],
1308
1381
  startedAt: isResuming ? prevState.startedAt : now,
1309
1382
  featureStartedAt: prevState?.featureStartedAt || now,
1310
1383
  });
1311
- logEvent(root, 'step', { step: 9, label: 'User Scenarios', feature });
1312
- stepHeader(9, 'User Scenarios', feature);
1384
+ logEvent(root, 'step', { step: 11, label: 'User Scenarios', feature });
1385
+ stepHeader(11, 'User Scenarios', feature);
1313
1386
  if (isResuming) {
1314
- printResumptionHeader(9);
1387
+ printResumptionHeader(11);
1315
1388
  }
1316
- console.log('Create per-persona variations of existing scenarios. Skip to step 10 if no users.');
1389
+ console.log('Create per-persona variations of existing scenarios. Skip to step 12 if no users.');
1317
1390
  console.log();
1318
1391
  console.log(chalk.bold('If the app has NO users/auth:'));
1319
- console.log(chalk.dim(' Skip this step and proceed to step 10 (Verify).'));
1392
+ console.log(chalk.dim(' Skip this step and proceed to step 12 (Verify).'));
1320
1393
  console.log();
1321
1394
  console.log(chalk.bold('If the app has users/auth:'));
1322
1395
  console.log();
1323
1396
  console.log(chalk.bold('Goal: Create persona variations of EXISTING app scenarios.'));
1324
1397
  console.log(chalk.dim(' Do NOT create standalone persona scenarios. Each user-persona scenario should be'));
1325
- console.log(chalk.dim(' a variation of an existing app scenario from step 8, with user-specific state layered on.'));
1398
+ console.log(chalk.dim(' a variation of an existing app scenario from step 10, with user-specific state layered on.'));
1326
1399
  console.log();
1327
1400
  console.log(chalk.bold('Checklist:'));
1328
1401
  checkbox('Run `codeyam editor scenarios` — list all existing app scenarios');
1329
1402
  checkbox('For EACH existing app scenario, create a logged-in variation:');
1330
1403
  console.log(chalk.dim(' Copy the scenario seed data and add "session":{"cookieValue":"sess_alice"} + user seed'));
1331
1404
  console.log(chalk.dim(' Name: "<Original Name> - Logged In" (e.g. "Full Catalog - Logged In")'));
1332
- console.log(chalk.dim(' Step 8 scenarios already serve as logged-out versions (no session cookie)'));
1405
+ console.log(chalk.dim(' Step 10 scenarios already serve as logged-out versions (no session cookie)'));
1333
1406
  checkbox('If there are multiple user roles (admin, regular, etc.), create role-specific variations too');
1334
1407
  console.log(chalk.dim(' Each persona scenario layers user-specific seed data on top of an app scenario'));
1335
1408
  checkbox('Include "dimensions" — inherit from the base app scenario, or override if the persona implies a different device');
@@ -1338,26 +1411,26 @@ function printStep9(root, feature) {
1338
1411
  console.log(chalk.yellow(' If clientErrors is non-empty → fix the issue and re-register the scenario'));
1339
1412
  console.log();
1340
1413
  console.log(chalk.dim('See FEATURE_PATTERNS.md and AUTH_PATTERNS.md for auth scenario guidance.'));
1341
- stopGate(9);
1414
+ stopGate(11);
1342
1415
  }
1343
- // ─── Step 10: Verify ──────────────────────────────────────────────────
1344
- function printStep10(root, feature) {
1416
+ // ─── Step 12: Verify ──────────────────────────────────────────────────
1417
+ function printStep12(root, feature) {
1345
1418
  const port = getServerPort();
1346
1419
  const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1347
1420
  const prevState = readState(root);
1348
- const isResuming = prevState?.step === 10;
1421
+ const isResuming = prevState?.step === 12;
1349
1422
  const now = new Date().toISOString();
1350
1423
  writeState(root, {
1351
1424
  feature,
1352
- step: 10,
1353
- label: STEP_LABELS[10],
1425
+ step: 12,
1426
+ label: STEP_LABELS[12],
1354
1427
  startedAt: isResuming ? prevState.startedAt : now,
1355
1428
  featureStartedAt: prevState?.featureStartedAt || now,
1356
1429
  });
1357
- logEvent(root, 'step', { step: 10, label: 'Verify', feature });
1358
- stepHeader(10, 'Verify', feature);
1430
+ logEvent(root, 'step', { step: 12, label: 'Verify', feature });
1431
+ stepHeader(12, 'Verify', feature);
1359
1432
  if (isResuming) {
1360
- printResumptionHeader(10);
1433
+ printResumptionHeader(12);
1361
1434
  }
1362
1435
  console.log('Verify component isolation screenshots, editor scenarios, and library tests.');
1363
1436
  console.log();
@@ -1380,63 +1453,63 @@ function printStep10(root, feature) {
1380
1453
  checkbox('Verify no broken images: `codeyam editor verify-images \'{"paths":["/"], "imageUrls":["url1"]}\'` with all page paths and image URLs');
1381
1454
  console.log();
1382
1455
  console.log(chalk.bold('Library functions — test check:'));
1383
- checkbox('Re-run all test files from step 5 to confirm they still pass');
1456
+ checkbox('Re-run all test files from step 7 to confirm they still pass');
1384
1457
  console.log(chalk.dim(' Example: npx vitest run app/lib/drinks.test.ts'));
1385
1458
  checkbox('If any test fails, fix the source code and re-run');
1386
1459
  console.log();
1387
1460
  console.log(chalk.dim('Focus on fixing issues. All component screenshots, scenarios, and tests must be clean before proceeding.'));
1388
- stopGate(10);
1461
+ stopGate(12);
1389
1462
  }
1390
- // ─── Step 11: Journal ─────────────────────────────────────────────────
1391
- function printStep11(root, feature) {
1463
+ // ─── Step 13: Journal ─────────────────────────────────────────────────
1464
+ function printStep13(root, feature) {
1392
1465
  const port = getServerPort();
1393
1466
  const prevState = readState(root);
1394
- const isResuming = prevState?.step === 11;
1467
+ const isResuming = prevState?.step === 13;
1395
1468
  const now = new Date().toISOString();
1396
1469
  writeState(root, {
1397
1470
  feature,
1398
- step: 11,
1399
- label: STEP_LABELS[11],
1471
+ step: 13,
1472
+ label: STEP_LABELS[13],
1400
1473
  startedAt: isResuming ? prevState.startedAt : now,
1401
1474
  featureStartedAt: prevState?.featureStartedAt || now,
1402
1475
  });
1403
- logEvent(root, 'step', { step: 11, label: 'Journal', feature });
1404
- stepHeader(11, 'Journal', feature);
1476
+ logEvent(root, 'step', { step: 13, label: 'Journal', feature });
1477
+ stepHeader(13, 'Journal', feature);
1405
1478
  if (isResuming) {
1406
- printResumptionHeader(11);
1479
+ printResumptionHeader(13);
1407
1480
  }
1408
1481
  console.log('Create or update the journal entry for this feature.');
1409
1482
  console.log();
1410
1483
  console.log(chalk.bold('Checklist:'));
1411
1484
  checkbox('Write a concise description of what was built (2-3 sentences)');
1412
- checkbox(`First time at step 11 — create journal entry with ALL session screenshots:`);
1485
+ checkbox(`First time at step 13 — create journal entry with ALL session screenshots:`);
1413
1486
  console.log(chalk.dim(` codeyam editor journal '{"title":"...","type":"feature","description":"...","includeSessionScenarios":true}'`));
1414
1487
  console.log(chalk.dim(' includeSessionScenarios auto-discovers component + app + user persona screenshots'));
1415
- checkbox(`Returning to step 11 (before commit) — update the existing journal entry:`);
1488
+ checkbox(`Returning to step 13 (before commit) — update the existing journal entry:`);
1416
1489
  console.log(chalk.dim(` codeyam editor journal-update '{"time":"<journal entry time>","description":"<updated>","includeSessionScenarios":true}'`));
1417
1490
  console.log(chalk.dim(' Note: PATCH only works before the entry is committed. After commit, use POST to create a new entry.'));
1418
1491
  console.log();
1419
- console.log(chalk.dim('Focus on creating or updating the journal entry. Summary and presentation happen in step 13.'));
1420
- stopGate(11);
1492
+ console.log(chalk.dim('Focus on creating or updating the journal entry. Summary and presentation happen in step 15.'));
1493
+ stopGate(13);
1421
1494
  }
1422
- // ─── Step 12: Review ──────────────────────────────────────────────────
1423
- function printStep12(root, feature) {
1495
+ // ─── Step 14: Review ──────────────────────────────────────────────────
1496
+ function printStep14(root, feature) {
1424
1497
  const port = getServerPort();
1425
1498
  const { defaultName: dim, names: dimNames } = getProjectDimensions(root);
1426
1499
  const prevState = readState(root);
1427
- const isResuming = prevState?.step === 12;
1500
+ const isResuming = prevState?.step === 14;
1428
1501
  const now = new Date().toISOString();
1429
1502
  writeState(root, {
1430
1503
  feature,
1431
- step: 12,
1432
- label: STEP_LABELS[12],
1504
+ step: 14,
1505
+ label: STEP_LABELS[14],
1433
1506
  startedAt: isResuming ? prevState.startedAt : now,
1434
1507
  featureStartedAt: prevState?.featureStartedAt || now,
1435
1508
  });
1436
- logEvent(root, 'step', { step: 12, label: 'Review', feature });
1437
- stepHeader(12, 'Review', feature);
1509
+ logEvent(root, 'step', { step: 14, label: 'Review', feature });
1510
+ stepHeader(14, 'Review', feature);
1438
1511
  if (isResuming) {
1439
- printResumptionHeader(12);
1512
+ printResumptionHeader(14);
1440
1513
  }
1441
1514
  console.log('Verify all screenshots and checks pass before presenting to the user.');
1442
1515
  console.log();
@@ -1452,24 +1525,24 @@ function printStep12(root, feature) {
1452
1525
  checkbox('Recapture stale scenarios: `codeyam editor recapture-stale`');
1453
1526
  checkbox('Run `codeyam editor audit` to verify completeness of scenarios and tests');
1454
1527
  checkbox('Do not proceed until all checks pass');
1455
- stopGate(12);
1528
+ stopGate(14);
1456
1529
  }
1457
- // ─── Step 13: Present ─────────────────────────────────────────────────
1458
- function printStep13(root, feature) {
1530
+ // ─── Step 15: Present ─────────────────────────────────────────────────
1531
+ function printStep15(root, feature) {
1459
1532
  const prevState = readState(root);
1460
- const isResuming = prevState?.step === 13;
1533
+ const isResuming = prevState?.step === 15;
1461
1534
  const now = new Date().toISOString();
1462
1535
  writeState(root, {
1463
1536
  feature,
1464
- step: 13,
1465
- label: STEP_LABELS[13],
1537
+ step: 15,
1538
+ label: STEP_LABELS[15],
1466
1539
  startedAt: isResuming ? prevState.startedAt : now,
1467
1540
  featureStartedAt: prevState?.featureStartedAt || now,
1468
1541
  });
1469
- logEvent(root, 'step', { step: 13, label: 'Present', feature });
1470
- stepHeader(13, 'Present', feature);
1542
+ logEvent(root, 'step', { step: 15, label: 'Present', feature });
1543
+ stepHeader(15, 'Present', feature);
1471
1544
  if (isResuming) {
1472
- printResumptionHeader(13);
1545
+ printResumptionHeader(15);
1473
1546
  }
1474
1547
  console.log('Present the results to the user and get their approval.');
1475
1548
  console.log();
@@ -1488,7 +1561,7 @@ function printStep13(root, feature) {
1488
1561
  chalk.dim(' — describe changes, then re-verify'));
1489
1562
  console.log();
1490
1563
  console.log(chalk.bold('If the user chooses "Save & commit":'));
1491
- checkbox('Advance to the commit step: `codeyam editor 14`');
1564
+ checkbox('Advance to the commit step: `codeyam editor 16`');
1492
1565
  console.log();
1493
1566
  console.log(chalk.bold('If the user chooses "Make changes" (or asks for ANY change, even as a question):'));
1494
1567
  checkbox(`Hide the results panel: \`codeyam editor hide-results\``);
@@ -1496,7 +1569,7 @@ function printStep13(root, feature) {
1496
1569
  checkbox(`Run: \`codeyam editor change "${feature}"\` — this gives you the change checklist`);
1497
1570
  checkbox('THEN make the requested changes and follow the checklist');
1498
1571
  console.log(chalk.red.bold(' IMPORTANT: Always run the change command BEFORE writing any code.'));
1499
- stopGate(13, { confirm: true });
1572
+ stopGate(15, { confirm: true });
1500
1573
  }
1501
1574
  // ─── Migration Mode ──────────────────────────────────────────────────
1502
1575
  /**
@@ -2103,22 +2176,22 @@ function handleMigrateCommand(root, subArg) {
2103
2176
  };
2104
2177
  stepFns[step](root);
2105
2178
  }
2106
- // ─── Step 14: Commit ─────────────────────────────────────────────────
2107
- function printStep14(root, feature) {
2179
+ // ─── Step 16: Commit ─────────────────────────────────────────────────
2180
+ function printStep16(root, feature) {
2108
2181
  const prevState = readState(root);
2109
- const isResuming = prevState?.step === 14;
2182
+ const isResuming = prevState?.step === 16;
2110
2183
  const now = new Date().toISOString();
2111
2184
  writeState(root, {
2112
2185
  feature,
2113
- step: 14,
2114
- label: STEP_LABELS[14],
2186
+ step: 16,
2187
+ label: STEP_LABELS[16],
2115
2188
  startedAt: isResuming ? prevState.startedAt : now,
2116
2189
  featureStartedAt: prevState?.featureStartedAt || now,
2117
2190
  });
2118
- logEvent(root, 'step', { step: 14, label: 'Commit', feature });
2119
- stepHeader(14, 'Commit', feature);
2191
+ logEvent(root, 'step', { step: 16, label: 'Commit', feature });
2192
+ stepHeader(16, 'Commit', feature);
2120
2193
  if (isResuming) {
2121
- printResumptionHeader(14);
2194
+ printResumptionHeader(16);
2122
2195
  }
2123
2196
  console.log('Commit all changes for this feature.');
2124
2197
  console.log();
@@ -2127,24 +2200,24 @@ function printStep14(root, feature) {
2127
2200
  checkbox(`Hide the results panel: \`codeyam editor hide-results\``);
2128
2201
  checkbox(`Git commit using the journal description: \`codeyam editor commit '{"message":"feat: <title>\\n\\n<journal description>"}'\``);
2129
2202
  console.log(chalk.dim(' The commit message body MUST match the journal description exactly'));
2130
- stopGate(14);
2203
+ stopGate(16);
2131
2204
  }
2132
- // ─── Step 15: Finalize ───────────────────────────────────────────────
2133
- function printStep15(root, feature) {
2205
+ // ─── Step 17: Finalize ───────────────────────────────────────────────
2206
+ function printStep17(root, feature) {
2134
2207
  const prevState = readState(root);
2135
- const isResuming = prevState?.step === 15;
2208
+ const isResuming = prevState?.step === 17;
2136
2209
  const now = new Date().toISOString();
2137
2210
  writeState(root, {
2138
2211
  feature,
2139
- step: 15,
2140
- label: STEP_LABELS[15],
2212
+ step: 17,
2213
+ label: STEP_LABELS[17],
2141
2214
  startedAt: isResuming ? prevState.startedAt : now,
2142
2215
  featureStartedAt: prevState?.featureStartedAt || now,
2143
2216
  });
2144
- logEvent(root, 'step', { step: 15, label: 'Finalize', feature });
2145
- stepHeader(15, 'Finalize', feature);
2217
+ logEvent(root, 'step', { step: 17, label: 'Finalize', feature });
2218
+ stepHeader(17, 'Finalize', feature);
2146
2219
  if (isResuming) {
2147
- printResumptionHeader(15);
2220
+ printResumptionHeader(17);
2148
2221
  }
2149
2222
  console.log('Update the journal with the commit SHA and amend the commit.');
2150
2223
  console.log();
@@ -2152,24 +2225,24 @@ function printStep15(root, feature) {
2152
2225
  checkbox(`Update journal with commit SHA: \`codeyam editor journal-update '{"time":"<journal entry time>","commitSha":"<sha>","commitMessage":"feat: <title>"}'\``);
2153
2226
  checkbox('Amend the commit to include the journal update: `git add .codeyam/journal/ && git commit --amend --no-edit`');
2154
2227
  console.log(chalk.dim(' The journal-update modifies journal files after the commit — amend to keep the tree clean.'));
2155
- stopGate(15);
2228
+ stopGate(17);
2156
2229
  }
2157
- // ─── Step 16: Push ───────────────────────────────────────────────────
2158
- function printStep16(root, feature) {
2230
+ // ─── Step 18: Push ───────────────────────────────────────────────────
2231
+ function printStep18(root, feature) {
2159
2232
  const prevState = readState(root);
2160
- const isResuming = prevState?.step === 16;
2233
+ const isResuming = prevState?.step === 18;
2161
2234
  const now = new Date().toISOString();
2162
2235
  writeState(root, {
2163
2236
  feature,
2164
- step: 16,
2165
- label: STEP_LABELS[16],
2237
+ step: 18,
2238
+ label: STEP_LABELS[18],
2166
2239
  startedAt: isResuming ? prevState.startedAt : now,
2167
2240
  featureStartedAt: prevState?.featureStartedAt || now,
2168
2241
  });
2169
- logEvent(root, 'step', { step: 16, label: 'Push', feature });
2170
- stepHeader(16, 'Push', feature);
2242
+ logEvent(root, 'step', { step: 18, label: 'Push', feature });
2243
+ stepHeader(18, 'Push', feature);
2171
2244
  if (isResuming) {
2172
- printResumptionHeader(16);
2245
+ printResumptionHeader(18);
2173
2246
  }
2174
2247
  console.log('Push the commit to the remote repository.');
2175
2248
  console.log();
@@ -2180,12 +2253,17 @@ function printStep16(root, feature) {
2180
2253
  console.log(chalk.dim(' If the user says yes, run: `git push`'));
2181
2254
  console.log(chalk.dim(' If NO remote exists, ask (AskUserQuestion): "This project doesn\'t have a git remote yet. Would you like help setting one up? I can walk you through creating a GitHub repository." with options "Yes, set up remote" and "No, skip"'));
2182
2255
  console.log(chalk.dim(' If the user wants help, guide them through `gh repo create` or manual GitHub setup, then push.'));
2183
- checkbox('After the user responds, run: `codeyam editor steps` to start the next feature');
2184
- console.log();
2185
- console.log(chalk.red.bold(' If the user reports a bug or requests a fix after committing:'));
2186
- console.log(chalk.red.bold(' You MUST still run `codeyam editor change` before making any changes.'));
2187
- console.log(chalk.red.bold(' The change workflow applies to ALL changes — post-commit fixes are not an exception.'));
2188
- stopGate(16, { confirm: true });
2256
+ checkbox('Mark the current build task as complete');
2257
+ checkbox('Create a new task with EXACTLY this title: "Ask the user what to build next, then run `codeyam editor 1` to start the next feature"');
2258
+ console.log(chalk.dim(' There must ALWAYS be an active task. Never leave the task list empty.'));
2259
+ console.log(chalk.dim(' This task reminds you to use the editor workflow for the next feature.'));
2260
+ console.log();
2261
+ console.log(chalk.bold.yellow('IMPORTANT: After this step, the current feature is DONE.'));
2262
+ console.log(chalk.yellow(' Any new user request — even if it sounds related — is a NEW feature.'));
2263
+ console.log(chalk.yellow(' Do NOT use `codeyam editor change` or start building directly.'));
2264
+ console.log(chalk.yellow(' The next feature MUST start with `codeyam editor 1`.'));
2265
+ console.log(chalk.yellow(' The change workflow is ONLY for modifications during steps 1-15, not after commit.'));
2266
+ stopGate(18, { confirm: true });
2189
2267
  }
2190
2268
  // ─── Command definition ───────────────────────────────────────────────
2191
2269
  // ─── Analyze-imports subcommand ────────────────────────────────────────
@@ -2205,7 +2283,7 @@ async function handleAnalyzeImports(options = {}) {
2205
2283
  return;
2206
2284
  }
2207
2285
  console.error(chalk.red('Error: .codeyam/glossary.json not found.'));
2208
- console.error(chalk.dim(' Run codeyam editor 6 to create the glossary first.'));
2286
+ console.error(chalk.dim(' Run codeyam editor 8 to create the glossary first.'));
2209
2287
  process.exit(1);
2210
2288
  }
2211
2289
  let glossaryEntries;
@@ -2659,8 +2737,14 @@ async function handleRegister(jsonArg) {
2659
2737
  else {
2660
2738
  parts.push(`errors=0`);
2661
2739
  }
2662
- if (data.seedResult)
2663
- parts.push(`seed=${data.seedResult.success}`);
2740
+ if (data.seedResult) {
2741
+ if (data.seedResult.success) {
2742
+ parts.push(`seed=ok`);
2743
+ }
2744
+ else {
2745
+ parts.push(chalk.red(`seed=FAILED${data.seedResult.error ? ` (${data.seedResult.error})` : ''}`));
2746
+ }
2747
+ }
2664
2748
  if (data.captureError)
2665
2749
  parts.push(chalk.yellow(`captureError="${data.captureError}"`));
2666
2750
  console.log(prefix + parts.join(' '));
@@ -2879,7 +2963,7 @@ async function handleDependents(entityName) {
2879
2963
  *
2880
2964
  * Prints a condensed post-change checklist that guides Claude through
2881
2965
  * re-verifying after user-requested modifications. When called from
2882
- * step 13+, this loops back to step 13 (present). When called from an
2966
+ * step 15+, this loops back to step 15 (present). When called from an
2883
2967
  * earlier step, it returns to that step so the normal flow continues.
2884
2968
  */
2885
2969
  function handleChange(feature) {
@@ -2897,7 +2981,7 @@ function handleChange(feature) {
2897
2981
  process.exit(1);
2898
2982
  }
2899
2983
  }
2900
- const currentStep = state?.step ?? 13;
2984
+ const currentStep = state?.step ?? 15;
2901
2985
  const port = getServerPort();
2902
2986
  console.log();
2903
2987
  console.log(chalk.bold.cyan('━━━ Change Loop ━━━'));
@@ -2945,6 +3029,7 @@ function handleChange(feature) {
2945
3029
  console.log(chalk.dim(' re-register "Home - Default", "Catalog - Full", "Detail - WithReviews", etc.'));
2946
3030
  checkbox("Enrich existing scenario data to exercise the change — don't just re-register unchanged data");
2947
3031
  console.log(chalk.dim(' Add data that demonstrates what changed: new fields, relationships, states, content variety.'));
3032
+ console.log(chalk.dim(' If the enriched data makes the scenario name too narrow, rename it to reflect its broader coverage.'));
2948
3033
  checkbox('After each re-registration, view the screenshot to verify data is visible');
2949
3034
  console.log(chalk.dim(" If the screenshot doesn't show the data you put in, the scenario is broken."));
2950
3035
  console.log();
@@ -2968,10 +3053,10 @@ function handleChange(feature) {
2968
3053
  console.log(chalk.dim(' Always update the existing uncommitted entry — do NOT create a new one.'));
2969
3054
  console.log(chalk.dim(' Only create a new entry (POST) if no uncommitted entry exists for this feature.'));
2970
3055
  console.log();
2971
- // If the change was initiated from a step before 13, return to that step
2972
- // instead of jumping to step 13. The change workflow should only loop to
2973
- // step 13 when changes are requested FROM step 13.
2974
- if (currentStep < 13) {
3056
+ // If the change was initiated from a step before 15, return to that step
3057
+ // instead of jumping to step 15. The change workflow should only loop to
3058
+ // step 15 when changes are requested FROM step 15.
3059
+ if (currentStep < 15) {
2975
3060
  console.log(chalk.red(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
2976
3061
  console.log(chalk.red.bold(' REQUIRED: Return to current step'));
2977
3062
  console.log(chalk.red.bold(' When all checks pass, you MUST run: ') +
@@ -2982,7 +3067,7 @@ function handleChange(feature) {
2982
3067
  console.log(chalk.red(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
2983
3068
  console.log(chalk.red.bold(' REQUIRED: Show Results'));
2984
3069
  console.log(chalk.red.bold(' When all checks pass, you MUST run: ') +
2985
- chalk.bold(`codeyam editor 13`));
3070
+ chalk.bold(`codeyam editor 15`));
2986
3071
  console.log(chalk.red.bold(' The user ALWAYS expects to see results after changes. DO NOT skip this step.'));
2987
3072
  console.log(chalk.red(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
2988
3073
  }
@@ -3129,8 +3214,6 @@ function printAuditGateFailures(data) {
3129
3214
  }
3130
3215
  }
3131
3216
  console.error(chalk.yellow('\nFix: Fix the code errors above, then re-capture the affected scenarios.'));
3132
- console.error(chalk.yellow('If errors reference browser APIs (localStorage, sessionStorage, window, document),'));
3133
- console.error(chalk.yellow('create a universal mock: codeyam detect-universal-mocks'));
3134
3217
  }
3135
3218
  }
3136
3219
  console.error(chalk.dim('\nRun `codeyam editor audit` for full details.\n'));
@@ -3219,14 +3302,6 @@ async function handleAudit() {
3219
3302
  if (c.clientErrors.length > 3) {
3220
3303
  console.log(chalk.dim(` … and ${c.clientErrors.length - 3} more`));
3221
3304
  }
3222
- // Detect browser API errors and provide actionable guidance
3223
- const browserApiPattern = /\b(localStorage|sessionStorage|window\.|document\.|navigator\.|indexedDB|matchMedia|ResizeObserver|IntersectionObserver|MutationObserver)\b/;
3224
- const hasBrowserApiErrors = c.clientErrors.some((err) => browserApiPattern.test(err));
3225
- if (hasBrowserApiErrors) {
3226
- console.log(chalk.yellow(` ⚠ These errors are caused by browser APIs that don't exist during server-side analysis.`));
3227
- console.log(chalk.yellow(` Fix: Create a universal mock to stub the missing API. Run: codeyam detect-universal-mocks`));
3228
- console.log(chalk.yellow(` DO NOT re-run the audit or analyze-imports — the error will persist until a mock is created.`));
3229
- }
3230
3305
  }
3231
3306
  }
3232
3307
  console.log();
@@ -3287,11 +3362,9 @@ async function handleAudit() {
3287
3362
  console.log(chalk.red(' analyze-imports was run automatically but these entities are STILL incomplete.'));
3288
3363
  console.log(chalk.red(' DO NOT re-run analyze-imports or the audit in a loop — the result will be the same.'));
3289
3364
  console.log(chalk.yellow(' This means the analysis failed for these entities. Common causes:'));
3290
- console.log(chalk.yellow(' • Entity code uses browser APIs (localStorage, window, document) — create a universal mock'));
3291
3365
  console.log(chalk.yellow(' • Source file was renamed/deleted but glossary still references the old path'));
3292
3366
  console.log(chalk.yellow(' • Entity has import errors that prevent analysis'));
3293
3367
  console.log(chalk.yellow(' To investigate: run `codeyam editor analyze-imports` (without --silent) to see the full error.'));
3294
- console.log(chalk.yellow(' To fix browser API issues: run `codeyam detect-universal-mocks`'));
3295
3368
  }
3296
3369
  else {
3297
3370
  console.log(chalk.yellow(' Run `codeyam editor analyze-imports` to analyze these entities'));
@@ -3745,7 +3818,7 @@ async function handleTemplate() {
3745
3818
  console.log(chalk.green(' Git initialized.'));
3746
3819
  }
3747
3820
  // 4. Run codeyam init
3748
- console.log(chalk.bold('Running codeyam init...'));
3821
+ console.log(chalk.bold('Initializing project...'));
3749
3822
  await initCommand.handler({
3750
3823
  force: true,
3751
3824
  'keep-server': true,
@@ -3824,7 +3897,7 @@ async function handleSync() {
3824
3897
  // fall through
3825
3898
  }
3826
3899
  if (!projectSlug) {
3827
- console.error(chalk.red('Error: No project slug found. Run codeyam init first.'));
3900
+ console.error(chalk.red('Error: No project slug found. Run `codeyam editor template` to initialize the project.'));
3828
3901
  process.exit(1);
3829
3902
  }
3830
3903
  const connectionOk = await withoutSpinner(() => testEnvironment());
@@ -4008,7 +4081,7 @@ function handleEditorDebug(args) {
4008
4081
  scenarios.push({
4009
4082
  id: 'overview-with-state',
4010
4083
  title: 'Cycle overview (project, with state)',
4011
- render: () => withTempRoot(true, (tempRoot) => captureOutput(() => printCycleOverview(tempRoot, makeState(4, feature)))),
4084
+ render: () => withTempRoot(true, (tempRoot) => captureOutput(() => printCycleOverview(tempRoot, makeState(6, feature)))),
4012
4085
  });
4013
4086
  }
4014
4087
  const stepFns = {
@@ -4028,8 +4101,10 @@ function handleEditorDebug(args) {
4028
4101
  14: printStep14,
4029
4102
  15: printStep15,
4030
4103
  16: printStep16,
4104
+ 17: printStep17,
4105
+ 18: printStep18,
4031
4106
  };
4032
- for (let step = 1; step <= 16; step++) {
4107
+ for (let step = 1; step <= 18; step++) {
4033
4108
  const stepId = `step-${step}`;
4034
4109
  if (!wants(stepId))
4035
4110
  continue;
@@ -4049,7 +4124,7 @@ function handleEditorDebug(args) {
4049
4124
  if (step === 2) {
4050
4125
  scenarios.push({
4051
4126
  id: 'step-2-scaffold',
4052
- title: 'Step 2 (Prototype) — scaffold flow (no project)',
4127
+ title: 'Step 2 (Prepare) — scaffold flow (no project)',
4053
4128
  render: () => withTempRoot(false, (tempRoot) => captureOutput(() => printStep2(tempRoot, feature))),
4054
4129
  });
4055
4130
  }
@@ -4108,8 +4183,8 @@ const editorCommand = {
4108
4183
  describe: 'Editor mode guided workflow',
4109
4184
  builder: (yargs) => {
4110
4185
  const stepDescription = IS_INTERNAL_BUILD
4111
- ? 'Step number (1-16) or subcommand (template, register, isolate, analyze-imports, dependents, audit, scenarios, scenario-coverage, recapture-stale, change, sync, debug, preview, show-results, hide-results, commit, journal, journal-list, journal-update, dev-server, client-errors)'
4112
- : 'Step number (1-16) or subcommand (template, register, isolate, analyze-imports, dependents, audit, scenarios, scenario-coverage, recapture-stale, change, sync, preview, show-results, hide-results, commit, journal, journal-list, journal-update, dev-server, client-errors)';
4186
+ ? 'Step number (1-18) or subcommand (template, register, isolate, analyze-imports, dependents, audit, scenarios, scenario-coverage, recapture-stale, change, sync, debug, preview, show-results, hide-results, commit, journal, journal-list, journal-update, dev-server, client-errors)'
4187
+ : 'Step number (1-18) or subcommand (template, register, isolate, analyze-imports, dependents, audit, scenarios, scenario-coverage, recapture-stale, change, sync, preview, show-results, hide-results, commit, journal, journal-list, journal-update, dev-server, client-errors)';
4113
4188
  let builder = yargs
4114
4189
  .positional('step', {
4115
4190
  type: 'string',
@@ -4145,7 +4220,7 @@ const editorCommand = {
4145
4220
  builder = builder
4146
4221
  .option('target', {
4147
4222
  type: 'string',
4148
- describe: 'Debug target (setup, overview, overview-with-state, step-1..step-16, or comma-separated list)',
4223
+ describe: 'Debug target (setup, overview, overview-with-state, step-1..step-18, or comma-separated list)',
4149
4224
  })
4150
4225
  .option('resume', {
4151
4226
  type: 'boolean',
@@ -4189,6 +4264,12 @@ const editorCommand = {
4189
4264
  console.log(JSON.stringify(result.data, null, 2));
4190
4265
  }
4191
4266
  }
4267
+ // After a successful commit, remind Claude to continue to step 17
4268
+ if (argv.step === 'commit' && result.ok) {
4269
+ console.log();
4270
+ console.log(chalk.green('Commit done. Now run: ') +
4271
+ chalk.bold('codeyam editor 17'));
4272
+ }
4192
4273
  }
4193
4274
  catch (err) {
4194
4275
  console.error(chalk.red('Error: Could not reach the CodeYam server. Is it running?'));
@@ -4296,18 +4377,13 @@ const editorCommand = {
4296
4377
  }
4297
4378
  else {
4298
4379
  const state = readState(root);
4299
- // Clear prompt file when feature is done (step 16) so the hook
4300
- // can capture the next feature request from the user.
4301
- if (state?.step === 16) {
4302
- clearEditorUserPrompt(root);
4303
- }
4304
4380
  printCycleOverview(root, state);
4305
4381
  }
4306
4382
  return;
4307
4383
  }
4308
4384
  const step = argv.step ? parseInt(argv.step, 10) : undefined;
4309
- if (step != null && (isNaN(step) || step < 1 || step > 16)) {
4310
- console.error(chalk.red(`Error: Invalid step "${argv.step}". Must be 1-16.`));
4385
+ if (step != null && (isNaN(step) || step < 1 || step > 18)) {
4386
+ console.error(chalk.red(`Error: Invalid step "${argv.step}". Must be 1-18.`));
4311
4387
  process.exit(1);
4312
4388
  }
4313
4389
  if (step == null) {
@@ -4331,7 +4407,7 @@ const editorCommand = {
4331
4407
  const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
4332
4408
  const { projectSlug } = config;
4333
4409
  if (!projectSlug) {
4334
- errorLog('Missing project slug. Try reinitializing with: codeyam init --force');
4410
+ errorLog('Missing project slug. Try reinitializing with: `codeyam editor template`');
4335
4411
  return;
4336
4412
  }
4337
4413
  const connectionOk = await withoutSpinner(() => testEnvironment());
@@ -4768,14 +4844,16 @@ const editorCommand = {
4768
4844
  case 13:
4769
4845
  case 14:
4770
4846
  case 15:
4771
- case 16: {
4847
+ case 16:
4848
+ case 17:
4849
+ case 18: {
4772
4850
  const feature = argv.feature || state?.feature;
4773
4851
  if (!feature) {
4774
4852
  console.error(chalk.red('Error: No feature in progress. Run codeyam editor 1 first.'));
4775
4853
  process.exit(1);
4776
4854
  }
4777
- // Hard gate: steps 8+ require audit to have passed
4778
- if (step >= 8) {
4855
+ // Hard gate: steps 10+ require audit to have passed
4856
+ if (step >= 10) {
4779
4857
  const auditOk = await checkAuditGate();
4780
4858
  if (!auditOk) {
4781
4859
  // checkAuditGate() already printed specific failure details above
@@ -4799,6 +4877,8 @@ const editorCommand = {
4799
4877
  14: printStep14,
4800
4878
  15: printStep15,
4801
4879
  16: printStep16,
4880
+ 17: printStep17,
4881
+ 18: printStep18,
4802
4882
  };
4803
4883
  stepFns[step](root, feature);
4804
4884
  break;