@codeyam/codeyam-cli 0.1.12 → 0.1.13

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 (41) 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 +9 -0
  4. package/codeyam-cli/src/cli.js.map +1 -1
  5. package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js +51 -0
  6. package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js.map +1 -0
  7. package/codeyam-cli/src/commands/editor.js +180 -18
  8. package/codeyam-cli/src/commands/editor.js.map +1 -1
  9. package/codeyam-cli/src/commands/editorIsolateArgs.js +25 -0
  10. package/codeyam-cli/src/commands/editorIsolateArgs.js.map +1 -0
  11. package/codeyam-cli/src/commands/telemetry.js +37 -0
  12. package/codeyam-cli/src/commands/telemetry.js.map +1 -0
  13. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js +70 -0
  14. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js.map +1 -1
  15. package/codeyam-cli/src/utils/__tests__/telemetry.test.js +159 -0
  16. package/codeyam-cli/src/utils/__tests__/telemetry.test.js.map +1 -0
  17. package/codeyam-cli/src/utils/editorEntityChangeStatus.js +13 -7
  18. package/codeyam-cli/src/utils/editorEntityChangeStatus.js.map +1 -1
  19. package/codeyam-cli/src/utils/telemetry.js +106 -0
  20. package/codeyam-cli/src/utils/telemetry.js.map +1 -0
  21. package/codeyam-cli/src/utils/telemetryMiddleware.js +22 -0
  22. package/codeyam-cli/src/utils/telemetryMiddleware.js.map +1 -0
  23. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +28 -0
  24. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -1
  25. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-CjC3_6JI.js +58 -0
  26. package/codeyam-cli/src/webserver/build/client/assets/globals-DRvOjyO3.css +1 -0
  27. package/codeyam-cli/src/webserver/build/client/assets/{manifest-b3f77062.js → manifest-75b1b319.js} +1 -1
  28. package/codeyam-cli/src/webserver/build/client/assets/{root-D5Zi3U2Z.js → root-F-k2uYj5.js} +15 -15
  29. package/codeyam-cli/src/webserver/build/server/assets/{analysisRunner-yTyb36j3.js → analysisRunner-lv2ooewK.js} +1 -1
  30. package/codeyam-cli/src/webserver/build/server/assets/{index-Cr7d_IsG.js → index-Im3Smyei.js} +1 -1
  31. package/codeyam-cli/src/webserver/build/server/assets/{init-M_wqNAfu.js → init-BjuAFKGM.js} +1 -1
  32. package/codeyam-cli/src/webserver/build/server/assets/{server-build-_ybRgrlc.js → server-build-CNjF0B9B.js} +116 -116
  33. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  34. package/codeyam-cli/src/webserver/build-info.json +5 -5
  35. package/codeyam-cli/src/webserver/editorProxy.js +19 -2
  36. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
  37. package/codeyam-cli/src/webserver/server.js +32 -0
  38. package/codeyam-cli/src/webserver/server.js.map +1 -1
  39. package/package.json +2 -1
  40. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DmBK1JBK.js +0 -58
  41. package/codeyam-cli/src/webserver/build/client/assets/globals-CGrDAxj0.css +0 -1
@@ -1,10 +1,10 @@
1
1
  {
2
- "buildTimestamp": "2026-03-17T15:17:00.245Z",
3
- "buildTime": 1773760620245,
4
- "gitCommit": "b282daf6fc6409b6a9facc3666589360a160dc1d",
2
+ "buildTimestamp": "2026-03-17T22:42:54.370Z",
3
+ "buildTime": 1773787374370,
4
+ "gitCommit": "6af1ab46096de2c86af4f0947046703a16ac9786",
5
5
  "nodeVersion": "v20.20.1",
6
6
  "contentHash": "b046e014847d5b02d10d6795839ccd0d5117627cbd0be413260824610596a63d",
7
- "buildNumber": 1071,
8
- "semanticVersion": "0.1.1071",
9
- "version": "0.1.1071 (2026-03-17T15:17+b046e01)"
7
+ "buildNumber": 1087,
8
+ "semanticVersion": "0.1.1087",
9
+ "version": "0.1.1087 (2026-03-17T22:42+b046e01)"
10
10
  }
@@ -1,7 +1,7 @@
1
1
 
2
- [3/17/2026, 3:17:00 PM] > codeyam-combo@1.0.0 mergeDependencies
3
- [3/17/2026, 3:17:00 PM] > node ./scripts/mergePackageJsonFiles.cjs
2
+ [3/17/2026, 10:42:54 PM] > codeyam-combo@1.0.0 mergeDependencies
3
+ [3/17/2026, 10:42:54 PM] > node ./scripts/mergePackageJsonFiles.cjs
4
4
 
5
5
 
6
- [3/17/2026, 3:17:00 PM] Merged dependencies into root package.json
6
+ [3/17/2026, 10:42:54 PM] Merged dependencies into root package.json
7
7
 
@@ -27,8 +27,11 @@ import memoryCommand from "./commands/memory.js";
27
27
  import editorCommand from "./commands/editor.js";
28
28
  import setupSimulationsCommand from "./commands/setup-simulations.js";
29
29
  import { syncMocksMiddleware } from "./utils/syncMocksMiddleware.js";
30
+ import { telemetryMiddleware } from "./utils/telemetryMiddleware.js";
31
+ import { captureEvent } from "./utils/telemetry.js";
30
32
  import { getDisplayVersion } from "./utils/versionInfo.js";
31
33
  import { simulationGateMiddleware, buildSimulationEpilogue, } from "./utils/simulationGateMiddleware.js";
34
+ import telemetryCommand from "./commands/telemetry.js";
32
35
  // Install global signal handlers for automatic process cleanup
33
36
  // This ensures all child processes (analyzer, capture, etc.) are cleaned up on:
34
37
  // - Ctrl+C (SIGINT)
@@ -49,11 +52,13 @@ yargs(hideBin(process.argv))
49
52
  .usage('CodeYam local development CLI')
50
53
  .middleware(simulationGateMiddleware)
51
54
  .middleware(syncMocksMiddleware)
55
+ .middleware(telemetryMiddleware)
52
56
  // Core commands (always visible in help)
53
57
  .command(defaultCommand)
54
58
  .command(startCommand)
55
59
  .command(stopCommand)
56
60
  .command(memoryCommand)
61
+ .command(telemetryCommand)
57
62
  // Hidden commands (shown in epilogue when simulations are enabled)
58
63
  .command(withoutDescribe(initCommand))
59
64
  .command(withoutDescribe(updateConfigCommand))
@@ -81,6 +86,10 @@ yargs(hideBin(process.argv))
81
86
  .strict()
82
87
  .parseAsync()
83
88
  .catch((error) => {
89
+ captureEvent('cli_error', {
90
+ command: process.argv[2] ?? 'unknown',
91
+ error_type: error?.constructor?.name ?? 'Error',
92
+ });
84
93
  console.error('CLI Error:', error.message);
85
94
  process.exit(1);
86
95
  });
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Tests that `codeyam editor isolate` correctly parses multiple component
3
+ * names whether passed as separate args or a single quoted string.
4
+ *
5
+ * Bug: `codeyam editor isolate A B C` failed because yargs .strict()
6
+ * rejected extra positionals beyond the two declared (step, json).
7
+ * Claude would then try one at a time, wasting time and tokens.
8
+ */
9
+ import { parseIsolateArgs } from "../editorIsolateArgs.js";
10
+ describe('parseIsolateArgs', () => {
11
+ it('should parse a single component name from json arg', () => {
12
+ expect(parseIsolateArgs('LogoMark', [])).toEqual(['LogoMark']);
13
+ });
14
+ it('should parse space-separated names from a single quoted json arg', () => {
15
+ // codeyam editor isolate "LogoMark AppHeader Button"
16
+ expect(parseIsolateArgs('LogoMark AppHeader Button', [])).toEqual([
17
+ 'LogoMark',
18
+ 'AppHeader',
19
+ 'Button',
20
+ ]);
21
+ });
22
+ it('should parse comma-separated names from json arg', () => {
23
+ expect(parseIsolateArgs('LogoMark,AppHeader,Button', [])).toEqual([
24
+ 'LogoMark',
25
+ 'AppHeader',
26
+ 'Button',
27
+ ]);
28
+ });
29
+ it('should collect extra positional args from argv._', () => {
30
+ // codeyam editor isolate LogoMark AppHeader Button
31
+ // yargs: json="LogoMark", argv._=["editor", "AppHeader", "Button"]
32
+ expect(parseIsolateArgs('LogoMark', ['editor', 'AppHeader', 'Button'])).toEqual(['LogoMark', 'AppHeader', 'Button']);
33
+ });
34
+ it('should deduplicate names from json and extras', () => {
35
+ expect(parseIsolateArgs('LogoMark', ['editor', 'LogoMark', 'AppHeader'])).toEqual(['LogoMark', 'AppHeader']);
36
+ });
37
+ it('should filter out empty strings', () => {
38
+ expect(parseIsolateArgs('LogoMark AppHeader', [])).toEqual([
39
+ 'LogoMark',
40
+ 'AppHeader',
41
+ ]);
42
+ });
43
+ it('should return empty array when no names provided', () => {
44
+ expect(parseIsolateArgs(undefined, [])).toEqual([]);
45
+ expect(parseIsolateArgs('', [])).toEqual([]);
46
+ });
47
+ it('should filter out "editor" from argv._', () => {
48
+ expect(parseIsolateArgs(undefined, ['editor', 'LogoMark', 'AppHeader'])).toEqual(['LogoMark', 'AppHeader']);
49
+ });
50
+ });
51
+ //# sourceMappingURL=editor.isolateArgs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.isolateArgs.test.js","sourceRoot":"","sources":["../../../../../src/commands/__tests__/editor.isolateArgs.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,qDAAqD;QACrD,MAAM,CAAC,gBAAgB,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAChE,UAAU;YACV,WAAW;YACX,QAAQ;SACT,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,gBAAgB,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAChE,UAAU;YACV,WAAW;YACX,QAAQ;SACT,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,mDAAmD;QACnD,mEAAmE;QACnE,MAAM,CACJ,gBAAgB,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAChE,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CACJ,gBAAgB,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAClE,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAC1D,UAAU;YACV,WAAW;SACZ,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CACJ,gBAAgB,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CACjE,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -939,13 +939,29 @@ function printStep2(root, feature) {
939
939
  console.log();
940
940
  console.log(chalk.bold('Build the feature:'));
941
941
  }
942
+ else {
943
+ console.log(chalk.bold('Prepare the database for this feature:'));
944
+ checkbox('List existing scenarios: `codeyam editor scenarios`');
945
+ console.log(chalk.dim(' Review existing scenarios to find seed data that best demonstrates the feature.'));
946
+ console.log(chalk.dim(" Don't create throwaway seed data — use what's already been curated."));
947
+ checkbox('Pick the scenario with seed data most relevant to this feature');
948
+ console.log(chalk.dim(" Think: which existing data state best exercises the feature you're building?"));
949
+ console.log(chalk.dim(' A scenario with diverse, realistic data is usually the best starting point.'));
950
+ checkbox('Load that scenario to seed the database and preview it:');
951
+ console.log(chalk.dim(` codeyam editor preview '{"scenarioId":"<id>","dimension":"${dim}"}'`));
952
+ console.log(chalk.dim(' This switches the active scenario, runs the seed adapter, and refreshes the preview.'));
953
+ console.log(chalk.dim(' If no existing scenario fits, use the default seed: npm run db:seed'));
954
+ console.log();
955
+ }
942
956
  console.log(chalk.bold('Checklist:'));
943
957
  checkbox('Create API routes that read from the database via Prisma');
944
- checkbox('Seed the database with demo data');
945
- checkbox('Create `.codeyam/seed-adapter.ts` so CodeYam can seed the database for scenarios');
946
- console.log(chalk.dim(' The seed adapter reads a JSON file (path passed as CLI arg), wipes tables, inserts rows.'));
947
- console.log(chalk.dim(" Use the project's own ORM (Prisma, Drizzle, etc.). See template for example."));
948
- console.log(chalk.dim(' Run with: npx tsx .codeyam/seed-adapter.ts <path-to-seed-data.json>'));
958
+ if (!projectExists) {
959
+ checkbox('Seed the database with demo data');
960
+ checkbox('Create `.codeyam/seed-adapter.ts` so CodeYam can seed the database for scenarios');
961
+ console.log(chalk.dim(' The seed adapter reads a JSON file (path passed as CLI arg), wipes tables, inserts rows.'));
962
+ console.log(chalk.dim(" Use the project's own ORM (Prisma, Drizzle, etc.). See template for example."));
963
+ console.log(chalk.dim(' Run with: npx tsx .codeyam/seed-adapter.ts <path-to-seed-data.json>'));
964
+ }
949
965
  checkbox('Verify the dev server shows the changes');
950
966
  checkbox('If the feature involves auth, email, payments, or other common patterns: read FEATURE_PATTERNS.md');
951
967
  // Responsive design guidance when building a mobile-responsive web app
@@ -2955,10 +2971,67 @@ async function checkAuditGate() {
2955
2971
  }
2956
2972
  // Re-check after fix
2957
2973
  const retry = await fetchAuditResult();
2958
- return retry?.summary?.allPassing === true;
2974
+ if (retry?.summary?.allPassing === true)
2975
+ return true;
2959
2976
  }
2977
+ // Print specific failures so Claude knows what to fix without running audit separately
2978
+ printAuditGateFailures(data);
2960
2979
  return false;
2961
2980
  }
2981
+ /**
2982
+ * Print a concise summary of audit failures for the gate block message.
2983
+ * This gives Claude immediate context about what to fix without needing
2984
+ * to run `codeyam editor audit` as a separate step.
2985
+ */
2986
+ function printAuditGateFailures(data) {
2987
+ const s = data.summary;
2988
+ if (!s)
2989
+ return;
2990
+ const issues = [];
2991
+ if (s.componentsMissing > 0)
2992
+ issues.push(`${s.componentsMissing} component(s) missing scenarios`);
2993
+ if (s.componentsWithErrors > 0)
2994
+ issues.push(`${s.componentsWithErrors} component(s) with client errors (browser API or runtime errors in captured scenarios)`);
2995
+ if (s.functionsMissing > 0)
2996
+ issues.push(`${s.functionsMissing} function(s) missing test files`);
2997
+ if (s.functionsFailing > 0)
2998
+ issues.push(`${s.functionsFailing} function(s) with failing tests`);
2999
+ if (s.functionsNameMismatch > 0)
3000
+ issues.push(`${s.functionsNameMismatch} function(s) with test name mismatch`);
3001
+ if (s.missingFromGlossary > 0)
3002
+ issues.push(`${s.missingFromGlossary} file(s) with scenarios not in glossary`);
3003
+ if (s.incompleteEntities > 0)
3004
+ issues.push(`${s.incompleteEntities} entity/entities need import analysis`);
3005
+ if (s.miscategorizedScenarios > 0)
3006
+ issues.push(`${s.miscategorizedScenarios} component(s) using page URLs instead of isolation routes`);
3007
+ if (issues.length > 0) {
3008
+ console.error(chalk.yellow('\nAudit failures:'));
3009
+ for (const issue of issues) {
3010
+ console.error(chalk.yellow(` • ${issue}`));
3011
+ }
3012
+ }
3013
+ // Surface client error details inline — these are the most common cause of
3014
+ // Claude looping because the errors require code fixes, not audit re-runs.
3015
+ if (data.components) {
3016
+ const withErrors = data.components.filter((c) => c.status === 'has_errors' && c.clientErrors?.length > 0);
3017
+ if (withErrors.length > 0) {
3018
+ console.error(chalk.yellow('\nClient errors found:'));
3019
+ for (const c of withErrors) {
3020
+ console.error(chalk.red(` ${c.name}:`));
3021
+ for (const err of c.clientErrors.slice(0, 3)) {
3022
+ console.error(chalk.red(` → ${err}`));
3023
+ }
3024
+ if (c.clientErrors.length > 3) {
3025
+ console.error(chalk.dim(` … and ${c.clientErrors.length - 3} more`));
3026
+ }
3027
+ }
3028
+ console.error(chalk.yellow('\nFix: Fix the code errors above, then re-capture the affected scenarios.'));
3029
+ console.error(chalk.yellow('If errors reference browser APIs (localStorage, sessionStorage, window, document),'));
3030
+ console.error(chalk.yellow('create a universal mock: codeyam detect-universal-mocks'));
3031
+ }
3032
+ }
3033
+ console.error(chalk.dim('\nRun `codeyam editor audit` for full details.\n'));
3034
+ }
2962
3035
  // ─── Audit subcommand ────────────────────────────────────────────────
2963
3036
  /**
2964
3037
  * `codeyam editor audit`
@@ -3027,6 +3100,14 @@ async function handleAudit() {
3027
3100
  if (c.clientErrors.length > 3) {
3028
3101
  console.log(chalk.dim(` … and ${c.clientErrors.length - 3} more`));
3029
3102
  }
3103
+ // Detect browser API errors and provide actionable guidance
3104
+ const browserApiPattern = /\b(localStorage|sessionStorage|window\.|document\.|navigator\.|indexedDB|matchMedia|ResizeObserver|IntersectionObserver|MutationObserver)\b/;
3105
+ const hasBrowserApiErrors = c.clientErrors.some((err) => browserApiPattern.test(err));
3106
+ if (hasBrowserApiErrors) {
3107
+ console.log(chalk.yellow(` ⚠ These errors are caused by browser APIs that don't exist during server-side analysis.`));
3108
+ console.log(chalk.yellow(` Fix: Create a universal mock to stub the missing API. Run: codeyam detect-universal-mocks`));
3109
+ console.log(chalk.yellow(` DO NOT re-run the audit or analyze-imports — the error will persist until a mock is created.`));
3110
+ }
3030
3111
  }
3031
3112
  }
3032
3113
  console.log();
@@ -3077,9 +3158,13 @@ async function handleAudit() {
3077
3158
  }
3078
3159
  if (autoRemediationFailed) {
3079
3160
  console.log(chalk.red(' analyze-imports was run automatically but these entities are STILL incomplete.'));
3080
- console.log(chalk.red(' This usually means the analysis had errorscheck the output above for details.'));
3081
- console.log(chalk.yellow(' Common causes: stale entity references from refactoring, missing source files.'));
3082
- console.log(chalk.yellow(' Try: run `codeyam editor analyze-imports` manually to see the full error output.'));
3161
+ console.log(chalk.red(' DO NOT re-run analyze-imports or the audit in a loop — the result will be the same.'));
3162
+ console.log(chalk.yellow(' This means the analysis failed for these entities. Common causes:'));
3163
+ console.log(chalk.yellow(' Entity code uses browser APIs (localStorage, window, document) create a universal mock'));
3164
+ console.log(chalk.yellow(' • Source file was renamed/deleted but glossary still references the old path'));
3165
+ console.log(chalk.yellow(' • Entity has import errors that prevent analysis'));
3166
+ console.log(chalk.yellow(' To investigate: run `codeyam editor analyze-imports` (without --silent) to see the full error.'));
3167
+ console.log(chalk.yellow(' To fix browser API issues: run `codeyam detect-universal-mocks`'));
3083
3168
  }
3084
3169
  else {
3085
3170
  console.log(chalk.yellow(' Run `codeyam editor analyze-imports` to analyze these entities'));
@@ -3812,7 +3897,9 @@ const editorCommand = {
3812
3897
  describe: 'Debug: output directory for the bundle',
3813
3898
  });
3814
3899
  }
3815
- return builder;
3900
+ // Allow extra positional args for subcommands like `isolate A B C`
3901
+ // without yargs rejecting them as unknown.
3902
+ return builder.strict(false);
3816
3903
  },
3817
3904
  handler: async (argv) => {
3818
3905
  const root = getProjectRoot();
@@ -3897,13 +3984,10 @@ const editorCommand = {
3897
3984
  return;
3898
3985
  }
3899
3986
  // Subcommand: codeyam editor isolate "StarRating CategoryBadge DrinkCard"
3987
+ // Also supports: codeyam editor isolate StarRating CategoryBadge DrinkCard
3900
3988
  if (argv.step === 'isolate') {
3901
- const names = [];
3902
- if (argv.json)
3903
- names.push(...argv.json.split(/[\s,]+/).filter(Boolean));
3904
- // Collect any extra positional args (yargs puts them in argv._)
3905
- const extras = argv._.filter((a) => typeof a === 'string' && a !== 'editor');
3906
- names.push(...extras);
3989
+ const { parseIsolateArgs } = await import('./editorIsolateArgs.js');
3990
+ const names = parseIsolateArgs(argv.json, argv._);
3907
3991
  handleIsolate(names);
3908
3992
  return;
3909
3993
  }
@@ -4091,6 +4175,41 @@ const editorCommand = {
4091
4175
  catch {
4092
4176
  // Non-fatal — migration failure shouldn't block editor startup
4093
4177
  }
4178
+ // Auto-seed on fresh clone: if no scenario has ever been activated
4179
+ // (active-scenario.json doesn't exist), seed the application database
4180
+ // with the first application scenario that has seed data.
4181
+ const activeScenarioPath = path.join(projectRoot, '.codeyam', 'active-scenario.json');
4182
+ if (!fs.existsSync(activeScenarioPath)) {
4183
+ try {
4184
+ const { getDatabase: getDb } = await import('../../../packages/database/index.js');
4185
+ const seedDb = getDb();
4186
+ const appScenario = await seedDb
4187
+ .selectFrom('editor_scenarios')
4188
+ .select(['id', 'name', 'type'])
4189
+ .where('project_id', '=', project.id)
4190
+ .where('type', '=', 'application')
4191
+ .orderBy('created_at', 'asc')
4192
+ .executeTakeFirst();
4193
+ if (appScenario) {
4194
+ const seedFile = path.join(projectRoot, '.codeyam', 'editor-scenarios', `${appScenario.id}.seed.json`);
4195
+ if (fs.existsSync(seedFile)) {
4196
+ const { switchActiveScenario } = await import('../utils/editorScenarioSwitch.js');
4197
+ const seedResult = await switchActiveScenario({
4198
+ scenarioId: appScenario.id,
4199
+ scenarioName: appScenario.name || undefined,
4200
+ scenarioType: appScenario.type || undefined,
4201
+ projectRoot,
4202
+ });
4203
+ if (seedResult.seedResult?.success) {
4204
+ console.log(chalk.green(` Auto-seeded database with scenario: ${appScenario.name || appScenario.id}`));
4205
+ }
4206
+ }
4207
+ }
4208
+ }
4209
+ catch {
4210
+ // Non-fatal — auto-seed is best-effort
4211
+ }
4212
+ }
4094
4213
  // `codeyam editor` (no step) always implies editor mode.
4095
4214
  // The empty-folder heuristic is no longer needed here — running this
4096
4215
  // command IS the signal. We still detect empty folders so that
@@ -4235,6 +4354,48 @@ const editorCommand = {
4235
4354
  }
4236
4355
  }
4237
4356
  }
4357
+ // Backfill page_file_path for application scenarios that have a URL but
4358
+ // no page_file_path. This resolves the file from the URL using Next.js
4359
+ // routing conventions, enabling syncScenarioEntityShas to link them to
4360
+ // entities. Covers fresh clones where JSON files lack pageFilePath.
4361
+ try {
4362
+ const { getDatabase: getDb } = await import('../../../packages/database/index.js');
4363
+ const pfpDb = getDb();
4364
+ const unresolved = await pfpDb
4365
+ .selectFrom('editor_scenarios')
4366
+ .select(['id', 'url'])
4367
+ .where('project_id', '=', project.id)
4368
+ .where('component_name', 'is', null)
4369
+ .where('page_file_path', 'is', null)
4370
+ .where('url', 'is not', null)
4371
+ .execute();
4372
+ if (unresolved.length > 0) {
4373
+ const { scanPageFilePaths: scanPfp } = await import('../utils/entityChangeStatus.server.js');
4374
+ const { matchUrlToPageFile } = await import('../utils/routePatternMatching');
4375
+ const { allFiles: pfpFiles } = scanPfp(projectRoot);
4376
+ let pfpResolved = 0;
4377
+ for (const row of unresolved) {
4378
+ const r = row;
4379
+ if (!r.url)
4380
+ continue;
4381
+ const matched = matchUrlToPageFile(r.url, pfpFiles);
4382
+ if (matched) {
4383
+ await pfpDb
4384
+ .updateTable('editor_scenarios')
4385
+ .set({ page_file_path: matched })
4386
+ .where('id', '=', r.id)
4387
+ .execute();
4388
+ pfpResolved++;
4389
+ }
4390
+ }
4391
+ if (pfpResolved > 0) {
4392
+ console.log(chalk.green(` Resolved page_file_path for ${pfpResolved} scenario(s) from URL`));
4393
+ }
4394
+ }
4395
+ }
4396
+ catch {
4397
+ /* Non-fatal — page_file_path backfill from URL */
4398
+ }
4238
4399
  // Backfill entity_sha on scenarios that were synced before entities existed.
4239
4400
  // This runs independently of analyze-imports so fresh clones and file-synced
4240
4401
  // scenarios get linked to their entities even when auto-analyze doesn't trigger.
@@ -4341,8 +4502,9 @@ const editorCommand = {
4341
4502
  if (step >= 8) {
4342
4503
  const auditOk = await checkAuditGate();
4343
4504
  if (!auditOk) {
4344
- console.error(chalk.red.bold('BLOCKED: The audit has not passed. Run `codeyam editor audit` and fix all issues before proceeding.'));
4345
- console.error(chalk.yellow('Every function and hook must have a test file. Every component must have scenarios.'));
4505
+ // checkAuditGate() already printed specific failure details above
4506
+ console.error(chalk.red.bold('BLOCKED: The audit has not passed. Fix the issues listed above before proceeding.'));
4507
+ console.error(chalk.yellow('DO NOT re-run the audit in a loop — fix the underlying issues first.'));
4346
4508
  process.exit(1);
4347
4509
  }
4348
4510
  }