@codeyam/codeyam-cli 0.1.0-staging.ae0de75 → 0.1.0-staging.b8f4f94

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 (81) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +3 -3
  4. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +13 -7
  5. package/analyzer-template/packages/analyze/src/lib/asts/index.ts +7 -2
  6. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js +196 -0
  7. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js.map +1 -0
  8. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js +114 -0
  9. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js.map +1 -0
  10. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js +149 -0
  11. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js.map +1 -0
  12. package/codeyam-cli/src/commands/default.js +3 -46
  13. package/codeyam-cli/src/commands/default.js.map +1 -1
  14. package/codeyam-cli/src/commands/editor.js +254 -66
  15. package/codeyam-cli/src/commands/editor.js.map +1 -1
  16. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +234 -0
  17. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
  18. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js +12 -1
  19. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js.map +1 -1
  20. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +29 -0
  21. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -1
  22. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +1217 -0
  23. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -0
  24. package/codeyam-cli/src/utils/backgroundServer.js +2 -2
  25. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  26. package/codeyam-cli/src/utils/editorAudit.js +45 -5
  27. package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
  28. package/codeyam-cli/src/utils/editorJournal.js +7 -0
  29. package/codeyam-cli/src/utils/editorJournal.js.map +1 -1
  30. package/codeyam-cli/src/utils/entityChangeStatus.js +255 -0
  31. package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -0
  32. package/codeyam-cli/src/utils/install-skills.js +1 -1
  33. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  34. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +5 -1
  35. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  36. package/codeyam-cli/src/webserver/build/client/assets/Terminal-nZNBALox.js +41 -0
  37. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-diff-l0sNRNKZ.js +1 -0
  38. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-l0sNRNKZ.js +1 -0
  39. package/codeyam-cli/src/webserver/build/client/assets/editor-DTwKl1Xu.js +10 -0
  40. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.dev-D8ILZMR0.js → entity._sha.scenarios._scenarioId.dev-DjACbfdI.js} +1 -1
  41. package/codeyam-cli/src/webserver/build/client/assets/git-CdN8sCqs.js +1 -0
  42. package/codeyam-cli/src/webserver/build/client/assets/globals-h1-1oFYI.css +1 -0
  43. package/codeyam-cli/src/webserver/build/client/assets/index-yHOVb4rc.js +15 -0
  44. package/codeyam-cli/src/webserver/build/client/assets/manifest-9422aeab.js +1 -0
  45. package/codeyam-cli/src/webserver/build/client/assets/{memory-FweZHj5U.js → memory-Dg0mvYrI.js} +4 -1
  46. package/codeyam-cli/src/webserver/build/client/assets/{root-DUKqhFlb.js → root-BzQgN2ff.js} +1 -1
  47. package/codeyam-cli/src/webserver/build/server/assets/{index-BLhjL9Xi.js → index-Bh_pNxNA.js} +1 -1
  48. package/codeyam-cli/src/webserver/build/server/assets/server-build-Bqr22tlO.js +367 -0
  49. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  50. package/codeyam-cli/src/webserver/build-info.json +5 -5
  51. package/codeyam-cli/src/webserver/server.js +32 -6
  52. package/codeyam-cli/src/webserver/server.js.map +1 -1
  53. package/codeyam-cli/src/webserver/terminalServer.js +23 -4
  54. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  55. package/codeyam-cli/templates/editor-step-hook.py +53 -6
  56. package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +10 -5
  57. package/codeyam-cli/templates/skills/codeyam-memory/SKILL.md +10 -10
  58. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.mjs +139 -0
  59. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.mjs +52 -0
  60. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/read-json-field.mjs +61 -0
  61. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/ripgrep-fallback.mjs +155 -0
  62. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.mjs +13 -0
  63. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter-session.mjs +95 -0
  64. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.mjs +160 -0
  65. package/package.json +10 -10
  66. package/packages/analyze/src/lib/ProjectAnalyzer.js +10 -4
  67. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  68. package/packages/analyze/src/lib/asts/index.js +4 -2
  69. package/packages/analyze/src/lib/asts/index.js.map +1 -1
  70. package/scripts/npm-post-install.cjs +22 -0
  71. package/codeyam-cli/src/webserver/build/client/assets/Terminal-wkqC0AQk.js +0 -41
  72. package/codeyam-cli/src/webserver/build/client/assets/editor-CdjF_fX6.js +0 -8
  73. package/codeyam-cli/src/webserver/build/client/assets/git-CFCTYk9I.js +0 -15
  74. package/codeyam-cli/src/webserver/build/client/assets/globals-B17TBSS6.css +0 -1
  75. package/codeyam-cli/src/webserver/build/client/assets/manifest-b8fd6b07.js +0 -1
  76. package/codeyam-cli/src/webserver/build/server/assets/server-build-DyMuI5mU.js +0 -363
  77. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.sh +0 -108
  78. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.sh +0 -69
  79. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.sh +0 -12
  80. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter.jq +0 -45
  81. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.sh +0 -139
@@ -8,6 +8,15 @@ import { ProgressReporter } from "../utils/progress.js";
8
8
  import { initializeEnvironment } from "../utils/database.js";
9
9
  import { loadEntities, loadAnalyses } from "../../../packages/database/index.js";
10
10
  import { IS_INTERNAL_BUILD } from "../utils/buildFlags.js";
11
+ import { startBackgroundServer } from "../utils/backgroundServer.js";
12
+ import { installClaudeCodeSkills } from "../utils/install-skills.js";
13
+ import { setupClaudeCodeSettings } from "../utils/setupClaudeCodeSettings.js";
14
+ import { isAnalyzerFinalized, getAnalyzerTemplatePath, } from "../utils/analyzer.js";
15
+ import { updateProjectMetadata } from "../../../packages/database/index.js";
16
+ import { requireBranchAndProject, testEnvironment } from "../utils/database.js";
17
+ import { getProjectRoot as getStateProjectRoot } from "../state.js";
18
+ import { withoutSpinner, error as errorLog } from "../utils/progress.js";
19
+ import initCommand from "./init.js";
11
20
  const __filename = fileURLToPath(import.meta.url);
12
21
  const __dirname = path.dirname(__filename);
13
22
  const STEP_LABELS = {
@@ -23,6 +32,7 @@ const STEP_LABELS = {
23
32
  10: 'Verify',
24
33
  11: 'Journal',
25
34
  12: 'Review',
35
+ 13: 'Present',
26
36
  };
27
37
  /**
28
38
  * Append a JSONL log entry to .codeyam/logs/editor-log.jsonl
@@ -122,13 +132,13 @@ function stepHeader(step, title, feature) {
122
132
  console.log();
123
133
  }
124
134
  /**
125
- * Print a colored progress tracker showing all 11 steps.
135
+ * Print a colored progress tracker showing all 13 steps.
126
136
  * Steps before `current` are green ✓, `current` is bold cyan →, future steps are dim ○.
127
137
  */
128
138
  function printProgressTracker(current) {
129
139
  console.log();
130
140
  console.log(chalk.dim('┌─────────────────────────────────────┐'));
131
- for (let i = 1; i <= 12; i++) {
141
+ for (let i = 1; i <= 13; i++) {
132
142
  const label = STEP_LABELS[i];
133
143
  const num = i < 10 ? ` ${i}` : `${i}`;
134
144
  const content = `${num}. ${label.padEnd(28)}`;
@@ -166,7 +176,7 @@ function stopGate(current, opts) {
166
176
  console.log(chalk.yellow('For the CURRENT step (→), show each checklist item with ✓ (done) or ✗ (skipped + reason).'));
167
177
  console.log(chalk.yellow('If any items are ✗, explain why and ask if the user wants to address them.'));
168
178
  console.log();
169
- if (current < 12) {
179
+ if (current < 13) {
170
180
  console.log(chalk.green('When done, run: ') +
171
181
  chalk.bold(`codeyam editor ${current + 1}`));
172
182
  }
@@ -210,7 +220,8 @@ function printResumptionHeader(step) {
210
220
  `Check if a journal entry already exists for this feature:\n \`curl -s http://localhost:${port}/api/editor-journal\``,
211
221
  'If an entry exists, use PATCH to update it — do NOT create a new one',
212
222
  ],
213
- 12: ['Check if commit already made:\n `git log --oneline -3`'],
223
+ 12: ['Re-verify is safe to repeat just re-run the checks'],
224
+ 13: ['Check if commit already made:\n `git log --oneline -3`'],
214
225
  };
215
226
  const label = STEP_LABELS[step] || 'Unknown';
216
227
  console.log(chalk.bold.yellow(`━━━ RESUMING Step ${step}: ${label} ━━━`));
@@ -315,7 +326,7 @@ function parseDebugTargets(target) {
315
326
  }
316
327
  if (entry.startsWith('step-')) {
317
328
  const num = parseInt(entry.replace('step-', ''), 10);
318
- if (!isNaN(num) && num >= 1 && num <= 12) {
329
+ if (!isNaN(num) && num >= 1 && num <= 13) {
319
330
  valid.add(`step-${num}`);
320
331
  continue;
321
332
  }
@@ -428,7 +439,7 @@ function printCycleOverview(root, state) {
428
439
  chalk.dim(' to start a new feature'));
429
440
  }
430
441
  else {
431
- console.log('Each feature follows 12 steps. You MUST run each command in order:');
442
+ console.log('Each feature follows 13 steps. You MUST run each command in order:');
432
443
  console.log();
433
444
  console.log(` ${chalk.bold.yellow(' 1')} ${chalk.bold('Plan')} — Plan the feature, confirm with user`);
434
445
  console.log(` ${chalk.bold.yellow(' 2')} ${chalk.bold('Prototype')} — Build a working prototype fast`);
@@ -441,7 +452,8 @@ function printCycleOverview(root, state) {
441
452
  console.log(` ${chalk.bold.yellow(' 9')} ${chalk.bold('User Scenarios')} — Create user-persona scenarios`);
442
453
  console.log(` ${chalk.bold.yellow('10')} ${chalk.bold('Verify')} — Review screenshots, check for errors`);
443
454
  console.log(` ${chalk.bold.yellow('11')} ${chalk.bold('Journal')} — Create/update journal entry`);
444
- console.log(` ${chalk.bold.yellow('12')} ${chalk.bold('Review')} — Present summary, get approval`);
455
+ console.log(` ${chalk.bold.yellow('12')} ${chalk.bold('Review')} — Verify screenshots and audit`);
456
+ console.log(` ${chalk.bold.yellow('13')} ${chalk.bold('Present')} — Present summary, get approval`);
445
457
  console.log();
446
458
  console.log(chalk.green('Start now: ') + chalk.bold('codeyam editor 1'));
447
459
  }
@@ -582,7 +594,8 @@ function printStep2(root, feature) {
582
594
  console.log(chalk.dim(' Should look like: "startCommand": { "command": "sh", "args": ["-c", "npm run dev -- --port $PORT"] }'));
583
595
  console.log(chalk.dim(' If missing, add it manually. $PORT is replaced at runtime by the analyzer.'));
584
596
  console.log();
585
- checkbox(`Notify CodeYam: \`curl -s -X POST http://localhost:${port}/api/editor-refresh\``);
597
+ checkbox(`Detect the new project: \`curl -s -X POST http://localhost:${port}/api/editor-refresh\``);
598
+ console.log(chalk.dim(' This re-detects webapps and auto-starts the dev server.'));
586
599
  console.log();
587
600
  console.log(chalk.bold('Build the feature:'));
588
601
  }
@@ -601,7 +614,7 @@ function printStep2(root, feature) {
601
614
  console.log(chalk.yellow(' Verify everything works before presenting the prototype to the user.'));
602
615
  checkbox('Verify the page loads: curl the dev server URL and confirm HTTP 200 (not an error page)');
603
616
  checkbox('Verify API routes return valid JSON: curl each route and confirm no error responses');
604
- checkbox('Check for broken images: look at any <img> src attributes and verify the assets exist');
617
+ checkbox('Check for broken images: extract <img> src URLs from the HTML, then `curl -I <url>` each one and confirm HTTP 200 (not 404/403)');
605
618
  checkbox('Check the dev server terminal output for runtime errors (missing modules, failed imports)');
606
619
  console.log(chalk.dim(' If any check fails, fix the issue and re-verify before proceeding.'));
607
620
  console.log();
@@ -629,19 +642,16 @@ function printStep3(root, feature) {
629
642
  console.log('Summarize what was built and get user confirmation.');
630
643
  console.log();
631
644
  console.log(chalk.bold('Before presenting — verify everything works:'));
632
- checkbox(`Refresh the preview: \`curl -s -X POST http://localhost:${port}/api/editor-refresh\``);
633
- checkbox(`Refresh and check for SSR errors: \`curl -s -X POST http://localhost:${port}/api/dev-mode-preview\` — look at the \`preview\` field for \`healthy: false\``);
645
+ checkbox(`Refresh the preview: \`curl -s -X POST http://localhost:${port}/api/dev-mode-preview\` — check the \`preview\` field for \`healthy: false\``);
634
646
  checkbox('Verify API routes return valid data (curl each route)');
635
- checkbox(`Navigate to each page and check health: \`curl -s -X POST http://localhost:${port}/api/dev-mode-preview -H 'Content-Type: application/json' -d '{"path":"/your-route"}'\``);
636
647
  console.log();
637
- console.log(chalk.bold(' Check for broken images on each page:'));
638
- checkbox('Get the dev server URL from `curl -s http://localhost:' +
648
+ console.log(chalk.bold.red(' Verify EVERY image loads (this is the #1 source of broken prototypes):'));
649
+ checkbox('Get the dev server URL: `curl -s http://localhost:' +
639
650
  port +
640
- '/api/editor-dev-server` (the `url` field)');
641
- checkbox('For each page: `curl -s <dev-server-url>/your-route` and inspect `<img>` src attributes');
642
- checkbox('Verify every image src is a valid path (not a missing file, placeholder URL, or broken reference)');
643
- checkbox('If any images are broken: fix the src (use real assets, placeholders from a CDN, or remove the image)');
644
- console.log(chalk.yellow(' Do not present to the user until all checks pass. Fix issues first.'));
651
+ '/api/editor-dev-server` → use the `url` field');
652
+ checkbox("Curl each page's HTML and extract every `<img>` src URL");
653
+ checkbox('HTTP-fetch EVERY image URL: `curl -s -o /dev/null -w "%{http_code}" <url>` each must return 200');
654
+ checkbox('Fix or remove any image that returns non-200 before continuing');
645
655
  console.log();
646
656
  console.log(chalk.bold('Then present to the user:'));
647
657
  checkbox('Summarize what was built (routes, components, data)');
@@ -952,13 +962,13 @@ function printStep10(root, feature) {
952
962
  console.log(chalk.dim(` codeyam editor register '{"name":"ComponentName - Scenario",...}'`));
953
963
  console.log();
954
964
  console.log(chalk.bold('Editor scenarios (App tab) — visual + error check:'));
955
- checkbox(`Refresh the preview: \`curl -s -X POST http://localhost:${port}/api/editor-refresh\``);
965
+ checkbox(`Refresh the preview: \`curl -s -X POST http://localhost:${port}/api/dev-mode-preview\``);
956
966
  checkbox('Click through each app-level and user-persona scenario in the preview');
957
967
  checkbox(`Check for client-side errors: \`curl -s http://localhost:${port}/api/editor-client-errors\``);
958
968
  console.log(chalk.yellow(' If `hasErrors` is true: list each scenario with errors, fix the source code,'));
959
969
  console.log(chalk.yellow(' re-register the affected scenarios, and re-check until hasErrors is false'));
960
970
  console.log(chalk.dim(' Common errors: React errors, failed fetches, undefined references, hydration mismatches'));
961
- checkbox('Verify no broken images in any scenario screenshots');
971
+ checkbox('Verify no broken images: extract <img> src URLs from each page, `curl -s -o /dev/null -w "%{http_code}" <url>` each one — must return 200');
962
972
  console.log();
963
973
  console.log(chalk.bold('Library functions — test check:'));
964
974
  checkbox('Re-run all test files from step 5 to confirm they still pass');
@@ -995,12 +1005,13 @@ function printStep11(root, feature) {
995
1005
  console.log(chalk.dim(` -H 'Content-Type: application/json' \\`));
996
1006
  console.log(chalk.dim(` -d '{"title":"...","type":"feature","description":"...","includeSessionScenarios":true}'`));
997
1007
  console.log(chalk.dim(' includeSessionScenarios auto-discovers component + app + user persona screenshots'));
998
- checkbox(`Returning after changes — update the existing journal entry:`);
1008
+ checkbox(`Returning to step 11 (before commit) — update the existing journal entry:`);
999
1009
  console.log(chalk.dim(` curl -s -X PATCH http://localhost:${port}/api/editor-journal-update \\`));
1000
1010
  console.log(chalk.dim(` -H 'Content-Type: application/json' \\`));
1001
1011
  console.log(chalk.dim(` -d '{"time":"<journal entry time>","description":"<updated>","includeSessionScenarios":true}'`));
1012
+ console.log(chalk.dim(' Note: PATCH only works before the entry is committed. After commit, use POST to create a new entry.'));
1002
1013
  console.log();
1003
- console.log(chalk.dim('Focus on creating or updating the journal entry. Summary and review happen in step 12.'));
1014
+ console.log(chalk.dim('Focus on creating or updating the journal entry. Summary and presentation happen in step 13.'));
1004
1015
  stopGate(11);
1005
1016
  }
1006
1017
  // ─── Step 12: Review ──────────────────────────────────────────────────
@@ -1021,9 +1032,9 @@ function printStep12(root, feature) {
1021
1032
  if (isResuming) {
1022
1033
  printResumptionHeader(12);
1023
1034
  }
1024
- console.log('Verify everything, then present the scenario table to the user.');
1035
+ console.log('Verify all screenshots and checks pass before presenting to the user.');
1025
1036
  console.log();
1026
- console.log(chalk.bold('Phase 1 — Verify (do all of this silently):'));
1037
+ console.log(chalk.bold('Checklist (do all of this silently):'));
1027
1038
  checkbox(`Refresh the preview: \`curl -s -X POST http://localhost:${port}/api/dev-mode-preview\``);
1028
1039
  checkbox('Verify each component has screenshots in the App tab (grouped under Components)');
1029
1040
  checkbox('If any are missing, re-register them using `codeyam editor register`');
@@ -1031,42 +1042,62 @@ function printStep12(root, feature) {
1031
1042
  checkbox('If `hasErrors` is true, fix them and re-capture affected scenarios');
1032
1043
  checkbox('Run `codeyam editor audit` to verify completeness of scenarios and tests');
1033
1044
  checkbox('Do not proceed until all checks pass');
1045
+ stopGate(12);
1046
+ }
1047
+ // ─── Step 13: Present ─────────────────────────────────────────────────
1048
+ function printStep13(root, feature) {
1049
+ const port = getServerPort();
1050
+ const prevState = readState(root);
1051
+ const isResuming = prevState?.step === 13;
1052
+ const now = new Date().toISOString();
1053
+ writeState(root, {
1054
+ feature,
1055
+ step: 13,
1056
+ label: STEP_LABELS[13],
1057
+ startedAt: isResuming ? prevState.startedAt : now,
1058
+ featureStartedAt: prevState?.featureStartedAt || now,
1059
+ });
1060
+ logEvent(root, 'step', { step: 13, label: 'Present', feature });
1061
+ stepHeader(13, 'Present', feature);
1062
+ if (isResuming) {
1063
+ printResumptionHeader(13);
1064
+ }
1065
+ console.log('Present the results to the user and get their approval.');
1034
1066
  console.log();
1035
- console.log(chalk.bold('Phase 2 — Present to the user:'));
1036
- checkbox('Write a 1-2 sentence summary of what was built');
1037
- checkbox('Report test count and audit status (one line)');
1038
- checkbox('Switch the active scenario to the best demo state for the feature:');
1067
+ console.log(chalk.bold('Checklist:'));
1068
+ checkbox(`Fetch all scenarios: \`curl -s http://localhost:${port}/api/editor-scenarios\``);
1069
+ checkbox('Pick the scenario that best showcases the feature (happy path, most visually complete)');
1070
+ checkbox('Switch the preview to that scenario using its `id`:');
1039
1071
  console.log(chalk.dim(` curl -s -X POST http://localhost:${port}/api/dev-mode-preview \\`));
1040
- console.log(chalk.dim(` -H 'Content-Type: application/json' -d '{"scenarioSlug":"...","scenarioId":"..."}'`));
1072
+ console.log(chalk.dim(` -H 'Content-Type: application/json' -d '{"scenarioId":"<id>"}'`));
1041
1073
  checkbox(`Show the results panel: \`curl -s -X POST http://localhost:${port}/api/editor-show-results\``);
1042
1074
  console.log(chalk.dim(' This opens a visual panel below the terminal showing all scenarios with screenshots.'));
1043
1075
  console.log(chalk.dim(' The user can click scenarios to switch the live preview.'));
1076
+ checkbox('Write a 1-2 sentence summary of what was built');
1077
+ checkbox('Report test count and audit status (one line)');
1044
1078
  console.log();
1045
- console.log(chalk.bold('Phase 3 — Present a selection menu to the user (use AskUserQuestion):'));
1079
+ console.log(chalk.bold('Present a selection menu to the user (use AskUserQuestion):'));
1046
1080
  console.log(chalk.green(' "Save & commit"') +
1047
1081
  chalk.dim(' — git commit all changes and record in journal'));
1048
1082
  console.log(chalk.yellow(' "I\'d like to make some changes"') +
1049
1083
  chalk.dim(' — describe changes, then re-verify'));
1050
1084
  console.log();
1051
1085
  console.log(chalk.bold('If the user chooses "Save & commit":'));
1086
+ checkbox(`Hide the results panel first: \`curl -s -X POST http://localhost:${port}/api/editor-hide-results\``);
1052
1087
  checkbox(`Git commit using the journal description: \`curl -s -X POST http://localhost:${port}/api/editor-commit -H 'Content-Type: application/json' -d '{"message":"feat: <title>\\n\\n<journal description>"}'\``);
1053
1088
  console.log(chalk.dim(' The commit message body MUST match the journal description exactly'));
1054
1089
  checkbox(`Update journal with commit SHA: \`curl -s -X PATCH http://localhost:${port}/api/editor-journal-update -H 'Content-Type: application/json' -d '{"time":"<journal entry time>","commitSha":"<sha>","commitMessage":"feat: <title>"}'\``);
1055
1090
  console.log(chalk.green(' Then run: ') +
1056
- chalk.bold('codeyam editor 1') +
1091
+ chalk.bold('codeyam editor steps') +
1057
1092
  chalk.green(' to start the next feature'));
1058
1093
  console.log();
1059
- console.log(chalk.bold('If the user chooses "Make changes":'));
1060
- checkbox('Ask what changes the user wants');
1061
- checkbox('Make the requested changes');
1062
- console.log(chalk.yellow(' Then run: ') +
1063
- chalk.bold(`codeyam editor change "${feature}"`) +
1064
- chalk.yellow(' this prints a post-change checklist to re-register scenarios,'));
1065
- console.log(chalk.yellow(' re-run tests, update journal screenshots, and loop back to this review step.'));
1066
- console.log(chalk.red.bold(' IMPORTANT: You MUST run the change command. Do not skip this or try to re-verify manually.'));
1067
- console.log();
1068
- console.log(chalk.dim('Complete all phases in order: summary, screenshot verification, user menu.'));
1069
- stopGate(12, { confirm: true });
1094
+ console.log(chalk.bold('If the user chooses "Make changes" (or asks for ANY change, even as a question):'));
1095
+ checkbox(`Hide the results panel: \`curl -s -X POST http://localhost:${port}/api/editor-hide-results\``);
1096
+ checkbox('Ask what changes the user wants (if not already clear)');
1097
+ checkbox(`Run: \`codeyam editor change "${feature}"\` — this gives you the change checklist`);
1098
+ checkbox('THEN make the requested changes and follow the checklist');
1099
+ console.log(chalk.red.bold(' IMPORTANT: Always run the change command BEFORE writing any code.'));
1100
+ stopGate(13, { confirm: true });
1070
1101
  }
1071
1102
  // ─── Command definition ───────────────────────────────────────────────
1072
1103
  // ─── Analyze-imports subcommand ────────────────────────────────────────
@@ -1334,7 +1365,7 @@ async function handleDependents(entityName) {
1334
1365
  * Prints a condensed post-change checklist that guides Claude through
1335
1366
  * re-verifying after user-requested modifications. This is the "change
1336
1367
  * loop" — it replaces the freeform "make changes" path with structured
1337
- * instructions that always loop back to step 12 review.
1368
+ * instructions that always loop back to step 13 present.
1338
1369
  */
1339
1370
  function handleChange(feature) {
1340
1371
  const root = getProjectRoot();
@@ -1357,6 +1388,9 @@ function handleChange(feature) {
1357
1388
  console.log();
1358
1389
  console.log('The user has requested changes. Follow this checklist after making them.');
1359
1390
  console.log();
1391
+ console.log(chalk.bold('0. Close the results panel:'));
1392
+ checkbox(`Hide results: \`curl -s -X POST http://localhost:${port}/api/editor-hide-results\``);
1393
+ console.log();
1360
1394
  console.log(chalk.bold('1. Re-register affected component scenarios:'));
1361
1395
  checkbox('For each component you modified, re-register ALL its scenarios');
1362
1396
  console.log(chalk.dim(` codeyam editor register '{"name":"ComponentName - ScenarioName","description":"...","componentName":"ComponentName","componentPath":"app/components/ComponentName.tsx"}'`));
@@ -1378,13 +1412,13 @@ function handleChange(feature) {
1378
1412
  checkbox(`Check for client-side errors: \`curl -s http://localhost:${port}/api/editor-client-errors\``);
1379
1413
  checkbox('Fix any errors, then re-register affected scenarios');
1380
1414
  console.log();
1381
- console.log(chalk.bold('5. Update the journal:'));
1382
- checkbox(`Update journal entry with new screenshots: \`curl -s -X PATCH http://localhost:${port}/api/editor-journal-update -H 'Content-Type: application/json' -d '{"time":"<journal entry time>","description":"<updated>","includeSessionScenarios":true}'\``);
1383
- console.log(chalk.dim(' includeSessionScenarios refreshes ALL screenshots to reflect the changes'));
1415
+ console.log(chalk.bold('5. Create a new journal entry for this change:'));
1416
+ checkbox(`Create journal entry: \`curl -s -X POST http://localhost:${port}/api/editor-journal-entry -H 'Content-Type: application/json' -d '{"title":"...","type":"feature","description":"<describe what changed>","includeSessionScenarios":true}'\``);
1417
+ console.log(chalk.dim(' Do NOT PATCH the previous entry it is frozen after commit. Always POST a new one.'));
1384
1418
  console.log();
1385
1419
  console.log(chalk.bold.green('When all checks pass, run: ') +
1386
- chalk.bold(`codeyam editor 12`));
1387
- console.log(chalk.dim(' This re-enters the review step to present the updated summary to the user.'));
1420
+ chalk.bold(`codeyam editor 13`));
1421
+ console.log(chalk.dim(' This enters the present step to show the updated results to the user.'));
1388
1422
  console.log();
1389
1423
  }
1390
1424
  // ─── Audit subcommand ────────────────────────────────────────────────
@@ -1433,11 +1467,24 @@ async function handleAudit() {
1433
1467
  console.log(chalk.bold('Functions (test files):'));
1434
1468
  for (const f of functions) {
1435
1469
  const icon = f.status === 'ok' ? chalk.green('✓') : chalk.red('✗');
1436
- const detail = f.status === 'ok'
1437
- ? chalk.dim(` (${f.testFile})`)
1438
- : f.testFile
1439
- ? chalk.red(` — test file missing: ${f.testFile}`)
1440
- : chalk.red(' — no test file specified');
1470
+ let detail;
1471
+ switch (f.status) {
1472
+ case 'ok':
1473
+ detail = chalk.dim(` (${f.testFile})`);
1474
+ break;
1475
+ case 'failing':
1476
+ detail = chalk.red(` — tests failing: ${f.testFile}`);
1477
+ break;
1478
+ case 'name_mismatch':
1479
+ detail = chalk.red(` — tests pass but missing top-level describe("${f.name}", ...) — tests won't display in UI`);
1480
+ break;
1481
+ case 'missing':
1482
+ default:
1483
+ detail = f.testFile
1484
+ ? chalk.red(` — test file missing: ${f.testFile}`)
1485
+ : chalk.red(' — no test file specified');
1486
+ break;
1487
+ }
1441
1488
  console.log(` ${icon} ${f.name}${detail}`);
1442
1489
  }
1443
1490
  console.log();
@@ -1456,6 +1503,12 @@ async function handleAudit() {
1456
1503
  if (summary.functionsMissing > 0) {
1457
1504
  parts.push(`${summary.functionsMissing} function${summary.functionsMissing !== 1 ? 's' : ''} missing tests`);
1458
1505
  }
1506
+ if (summary.functionsFailing > 0) {
1507
+ parts.push(`${summary.functionsFailing} function${summary.functionsFailing !== 1 ? 's' : ''} with failing tests`);
1508
+ }
1509
+ if (summary.functionsNameMismatch > 0) {
1510
+ parts.push(`${summary.functionsNameMismatch} function${summary.functionsNameMismatch !== 1 ? 's' : ''} with test name mismatch (missing top-level describe)`);
1511
+ }
1459
1512
  console.log(chalk.red.bold('Audit failed: ') + parts.join(', '));
1460
1513
  }
1461
1514
  console.log();
@@ -1611,8 +1664,9 @@ function handleEditorDebug(args) {
1611
1664
  10: printStep10,
1612
1665
  11: printStep11,
1613
1666
  12: printStep12,
1667
+ 13: printStep13,
1614
1668
  };
1615
- for (let step = 1; step <= 12; step++) {
1669
+ for (let step = 1; step <= 13; step++) {
1616
1670
  const stepId = `step-${step}`;
1617
1671
  if (!wants(stepId))
1618
1672
  continue;
@@ -1691,8 +1745,8 @@ const editorCommand = {
1691
1745
  describe: 'Editor mode guided workflow',
1692
1746
  builder: (yargs) => {
1693
1747
  const stepDescription = IS_INTERNAL_BUILD
1694
- ? 'Step number (1-12) or subcommand (register, analyze-imports, dependents, audit, scenarios, change, debug)'
1695
- : 'Step number (1-12) or subcommand (register, analyze-imports, dependents, audit, scenarios, change)';
1748
+ ? 'Step number (1-13) or subcommand (register, analyze-imports, dependents, audit, scenarios, change, debug)'
1749
+ : 'Step number (1-13) or subcommand (register, analyze-imports, dependents, audit, scenarios, change)';
1696
1750
  let builder = yargs
1697
1751
  .positional('step', {
1698
1752
  type: 'string',
@@ -1705,12 +1759,18 @@ const editorCommand = {
1705
1759
  .option('feature', {
1706
1760
  type: 'string',
1707
1761
  describe: 'Feature name (required for step 2)',
1762
+ })
1763
+ .option('port', {
1764
+ type: 'number',
1765
+ alias: 'p',
1766
+ describe: 'Port to run the web server on',
1767
+ default: 3111,
1708
1768
  });
1709
1769
  if (IS_INTERNAL_BUILD) {
1710
1770
  builder = builder
1711
1771
  .option('target', {
1712
1772
  type: 'string',
1713
- describe: 'Debug target (setup, overview, overview-with-state, step-1..step-12, or comma-separated list)',
1773
+ describe: 'Debug target (setup, overview, overview-with-state, step-1..step-13, or comma-separated list)',
1714
1774
  })
1715
1775
  .option('resume', {
1716
1776
  type: 'boolean',
@@ -1769,13 +1829,8 @@ const editorCommand = {
1769
1829
  await handleEditorDebug(argv);
1770
1830
  return;
1771
1831
  }
1772
- const step = argv.step ? parseInt(argv.step, 10) : undefined;
1773
- if (step != null && (isNaN(step) || step < 1 || step > 12)) {
1774
- console.error(chalk.red(`Error: Invalid step "${argv.step}". Must be 1-12.`));
1775
- process.exit(1);
1776
- }
1777
- if (step == null) {
1778
- // No step specified: setup or overview
1832
+ // Subcommand: codeyam editor steps show setup or cycle overview
1833
+ if (argv.step === 'steps') {
1779
1834
  if (!hasProject(root)) {
1780
1835
  printSetup(root);
1781
1836
  }
@@ -1785,6 +1840,137 @@ const editorCommand = {
1785
1840
  }
1786
1841
  return;
1787
1842
  }
1843
+ const step = argv.step ? parseInt(argv.step, 10) : undefined;
1844
+ if (step != null && (isNaN(step) || step < 1 || step > 13)) {
1845
+ console.error(chalk.red(`Error: Invalid step "${argv.step}". Must be 1-13.`));
1846
+ process.exit(1);
1847
+ }
1848
+ if (step == null) {
1849
+ // No step specified: launch editor server + open browser
1850
+ // Auto-init if needed
1851
+ let projectRoot = getStateProjectRoot();
1852
+ if (!projectRoot) {
1853
+ await initCommand.handler({
1854
+ force: false,
1855
+ autoInit: true,
1856
+ $0: '',
1857
+ _: [],
1858
+ });
1859
+ projectRoot = getStateProjectRoot();
1860
+ if (!projectRoot) {
1861
+ return;
1862
+ }
1863
+ }
1864
+ const configPath = path.join(projectRoot, '.codeyam', 'config.json');
1865
+ try {
1866
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
1867
+ const { projectSlug } = config;
1868
+ if (!projectSlug) {
1869
+ errorLog('Missing project slug. Try reinitializing with: codeyam init --force');
1870
+ return;
1871
+ }
1872
+ const connectionOk = await withoutSpinner(() => testEnvironment());
1873
+ if (!connectionOk) {
1874
+ errorLog('Environment validation failed');
1875
+ return;
1876
+ }
1877
+ const { project, branch } = await requireBranchAndProject(projectSlug);
1878
+ // `codeyam editor` (no step) always implies editor mode.
1879
+ // The empty-folder heuristic is no longer needed here — running this
1880
+ // command IS the signal. We still detect empty folders so that
1881
+ // the very first `codeyam editor` in a bare directory works before
1882
+ // metadata has been persisted.
1883
+ const editorMode = true;
1884
+ if (editorMode && !project.metadata?.labs?.simulations) {
1885
+ try {
1886
+ await updateProjectMetadata({
1887
+ projectSlug,
1888
+ metadataUpdate: {
1889
+ editorMode: true,
1890
+ labs: { simulations: true },
1891
+ },
1892
+ });
1893
+ const refreshed = await requireBranchAndProject(projectSlug);
1894
+ Object.assign(project, refreshed.project);
1895
+ }
1896
+ catch {
1897
+ // Non-fatal
1898
+ }
1899
+ }
1900
+ // Install skills/hooks
1901
+ const simulationsEnabled = project.metadata?.labs?.simulations ?? false;
1902
+ const skillMode = simulationsEnabled
1903
+ ? 'full'
1904
+ : editorMode
1905
+ ? 'editor'
1906
+ : 'memory';
1907
+ await installClaudeCodeSkills(projectRoot, {
1908
+ mode: skillMode,
1909
+ editorMode,
1910
+ });
1911
+ setupClaudeCodeSettings(projectRoot, {
1912
+ mode: skillMode,
1913
+ editorMode,
1914
+ });
1915
+ // Auto-finalize analyzer so codeyam analyze works
1916
+ if (editorMode && !isAnalyzerFinalized()) {
1917
+ try {
1918
+ const { execSync } = await import('child_process');
1919
+ const templatePath = getAnalyzerTemplatePath();
1920
+ if (fs.existsSync(templatePath)) {
1921
+ console.log(' Setting up simulations (first time only)...');
1922
+ execSync('npm install --include=dev', {
1923
+ cwd: templatePath,
1924
+ stdio: 'pipe',
1925
+ });
1926
+ execSync('npx playwright install chromium', {
1927
+ cwd: templatePath,
1928
+ stdio: 'pipe',
1929
+ });
1930
+ execSync('npm run build', {
1931
+ cwd: templatePath,
1932
+ stdio: 'pipe',
1933
+ });
1934
+ fs.writeFileSync(path.join(templatePath, '.finalized'), new Date().toISOString());
1935
+ }
1936
+ }
1937
+ catch {
1938
+ // Non-fatal
1939
+ }
1940
+ }
1941
+ // Start background server
1942
+ const { url } = await startBackgroundServer({
1943
+ port: argv.port || 3111,
1944
+ rootPath: projectRoot,
1945
+ project,
1946
+ branch,
1947
+ });
1948
+ console.log();
1949
+ console.log(` Dashboard: ${url}`);
1950
+ console.log(' Run "codeyam --help" for all commands');
1951
+ console.log(chalk.bold(' Run "codeyam editor" to launch the editor at any time'));
1952
+ console.log();
1953
+ // Open browser to /editor
1954
+ try {
1955
+ const { execSync } = await import('child_process');
1956
+ const openCommand = process.platform === 'darwin'
1957
+ ? 'open'
1958
+ : process.platform === 'win32'
1959
+ ? 'start ""'
1960
+ : 'xdg-open';
1961
+ execSync(`${openCommand} "${url}/editor"`, { stdio: 'ignore' });
1962
+ }
1963
+ catch {
1964
+ // Silently fail if open command doesn't work
1965
+ }
1966
+ }
1967
+ catch (err) {
1968
+ errorLog('Failed to start CodeYam editor server');
1969
+ errorLog(err);
1970
+ process.exit(1);
1971
+ }
1972
+ return;
1973
+ }
1788
1974
  const state = readState(root);
1789
1975
  switch (step) {
1790
1976
  case 1: {
@@ -1811,7 +1997,8 @@ const editorCommand = {
1811
1997
  case 9:
1812
1998
  case 10:
1813
1999
  case 11:
1814
- case 12: {
2000
+ case 12:
2001
+ case 13: {
1815
2002
  const feature = argv.feature || state?.feature;
1816
2003
  if (!feature) {
1817
2004
  console.error(chalk.red('Error: No feature in progress. Run codeyam editor 1 first.'));
@@ -1828,6 +2015,7 @@ const editorCommand = {
1828
2015
  10: printStep10,
1829
2016
  11: printStep11,
1830
2017
  12: printStep12,
2018
+ 13: printStep13,
1831
2019
  };
1832
2020
  stepFns[step](root, feature);
1833
2021
  break;