@codeyam/codeyam-cli 0.1.25 → 0.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/analyzer-template/.build-info.json +6 -6
- package/analyzer-template/log.txt +3 -3
- package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js +55 -0
- package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js.map +1 -0
- package/codeyam-cli/src/commands/editor.js +61 -8
- package/codeyam-cli/src/commands/editor.js.map +1 -1
- package/codeyam-cli/src/data/techStacks.js +1 -1
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +10 -0
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js +120 -0
- package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js +84 -0
- package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/testRunner.test.js +0 -1
- package/codeyam-cli/src/utils/__tests__/testRunner.test.js.map +1 -1
- package/codeyam-cli/src/utils/editorAudit.js +22 -5
- package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
- package/codeyam-cli/src/utils/editorScenarioSwitch.js +27 -12
- package/codeyam-cli/src/utils/editorScenarioSwitch.js.map +1 -1
- package/codeyam-cli/src/utils/editorSeedAdapter.js +27 -14
- package/codeyam-cli/src/utils/editorSeedAdapter.js.map +1 -1
- package/codeyam-cli/src/utils/testRunner.js +1 -7
- package/codeyam-cli/src/utils/testRunner.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-CRxPi2BB.js +96 -0
- package/codeyam-cli/src/webserver/build/client/assets/globals-BsGHu8WX.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{manifest-7e749098.js → manifest-9032538f.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{root-DGtly3mb.js → root-dKFRTYcy.js} +5 -5
- package/codeyam-cli/src/webserver/build/server/assets/{analysisRunner-CO8xocj3.js → analysisRunner-OLsM110H.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{index-QKPqlUgg.js → index-WHdB6WTN.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{init-DlspChIk.js → init-DbSiZoE6.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{server-build-ChzicV-B.js → server-build-DZbLY6O_.js} +135 -134
- package/codeyam-cli/src/webserver/build/server/index.js +1 -1
- package/codeyam-cli/src/webserver/build-info.json +5 -5
- package/codeyam-cli/templates/expo-react-native/MOBILE_SETUP.md +54 -5
- package/codeyam-cli/templates/expo-react-native/app/_layout.tsx +4 -2
- package/codeyam-cli/templates/expo-react-native/app/index.tsx +36 -0
- package/codeyam-cli/templates/expo-react-native/babel.config.js +1 -0
- package/codeyam-cli/templates/expo-react-native/gitignore +2 -0
- package/codeyam-cli/templates/expo-react-native/package.json +23 -18
- package/codeyam-cli/templates/expo-react-native/patches/expo-modules-autolinking+3.0.24.patch +29 -0
- package/codeyam-cli/templates/seed-adapters/supabase.ts +91 -8
- package/package.json +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DLM1-ZMt.js +0 -96
- package/codeyam-cli/src/webserver/build/client/assets/globals-9EkC9j9I.css +0 -1
- package/codeyam-cli/templates/expo-react-native/app/(tabs)/_layout.tsx +0 -33
- package/codeyam-cli/templates/expo-react-native/app/(tabs)/index.tsx +0 -12
- package/codeyam-cli/templates/expo-react-native/app/(tabs)/settings.tsx +0 -12
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"buildTimestamp": "2026-03-
|
|
3
|
-
"buildTime":
|
|
4
|
-
"gitCommit": "
|
|
2
|
+
"buildTimestamp": "2026-03-28T18:03:51.730Z",
|
|
3
|
+
"buildTime": 1774721031730,
|
|
4
|
+
"gitCommit": "3d7e1f0d118b714119562b24234d8e7ae6832002",
|
|
5
5
|
"nodeVersion": "v20.20.1",
|
|
6
6
|
"contentHash": "c92230c027acb71cab56d2a696876a6a52206bfadd59fbc31a512b00a7ee8826",
|
|
7
|
-
"buildNumber":
|
|
8
|
-
"semanticVersion": "0.1.
|
|
9
|
-
"version": "0.1.
|
|
7
|
+
"buildNumber": 1271,
|
|
8
|
+
"semanticVersion": "0.1.1271",
|
|
9
|
+
"version": "0.1.1271 (2026-03-28T18:03+c92230c)"
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
[3/
|
|
3
|
-
[3/
|
|
2
|
+
[3/28/2026, 6:03:51 PM] > codeyam-combo@1.0.0 mergeDependencies
|
|
3
|
+
[3/28/2026, 6:03:51 PM] > node ./scripts/mergePackageJsonFiles.cjs
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
[3/
|
|
6
|
+
[3/28/2026, 6:03:51 PM] Merged dependencies into root package.json
|
|
7
7
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Structural test: every writeState() call in editor.ts must preserve
|
|
5
|
+
* `techStackId` and `appFormats` from the previous state.
|
|
6
|
+
*
|
|
7
|
+
* Bug: Steps 4-18 dropped techStackId from writeState calls, causing
|
|
8
|
+
* getTechStackContext() to fall back to Next.js defaults. This broke
|
|
9
|
+
* `codeyam editor isolate` for Expo projects — it created Next.js-style
|
|
10
|
+
* subdirectories instead of Expo flat files.
|
|
11
|
+
*/
|
|
12
|
+
describe('editor state persistence', () => {
|
|
13
|
+
const editorSource = fs.readFileSync(path.join(__dirname, '..', 'editor.ts'), 'utf8');
|
|
14
|
+
// Find all writeState blocks in the source.
|
|
15
|
+
// Each writeState call spans multiple lines like:
|
|
16
|
+
// writeState(root, {
|
|
17
|
+
// feature,
|
|
18
|
+
// step: N,
|
|
19
|
+
// ...
|
|
20
|
+
// });
|
|
21
|
+
const writeStateBlocks = [];
|
|
22
|
+
const lines = editorSource.split('\n');
|
|
23
|
+
for (let i = 0; i < lines.length; i++) {
|
|
24
|
+
if (lines[i].includes('writeState(root,')) {
|
|
25
|
+
// Collect lines until we find the closing `});`
|
|
26
|
+
let block = '';
|
|
27
|
+
for (let j = i; j < lines.length; j++) {
|
|
28
|
+
block += lines[j] + '\n';
|
|
29
|
+
if (lines[j].match(/^\s*\}\);/))
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
writeStateBlocks.push({ lineNumber: i + 1, block });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
it('should find writeState calls in editor.ts', () => {
|
|
36
|
+
expect(writeStateBlocks.length).toBeGreaterThan(10);
|
|
37
|
+
});
|
|
38
|
+
// Filter to only writeState blocks that set a step number (printStep functions).
|
|
39
|
+
// Exclude the handleTemplate/migration-survey writeState that sets step: 0.
|
|
40
|
+
const stepWriteStates = writeStateBlocks.filter(({ block }) => block.match(/step:\s*\d+/) && !block.match(/step:\s*0/));
|
|
41
|
+
it('should find step writeState calls', () => {
|
|
42
|
+
expect(stepWriteStates.length).toBeGreaterThanOrEqual(18);
|
|
43
|
+
});
|
|
44
|
+
for (const { lineNumber, block } of stepWriteStates) {
|
|
45
|
+
const stepMatch = block.match(/step:\s*(\d+)/);
|
|
46
|
+
const stepNum = stepMatch ? stepMatch[1] : '?';
|
|
47
|
+
it(`step ${stepNum} writeState (line ${lineNumber}) should preserve techStackId`, () => {
|
|
48
|
+
expect(block).toContain('techStackId');
|
|
49
|
+
});
|
|
50
|
+
it(`step ${stepNum} writeState (line ${lineNumber}) should preserve appFormats`, () => {
|
|
51
|
+
expect(block).toContain('appFormats');
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=editor.statePersistence.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.statePersistence.test.js","sourceRoot":"","sources":["../../../../../src/commands/__tests__/editor.statePersistence.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;;;;;GAQG;AACH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAClC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,EACvC,MAAM,CACP,CAAC;IAEF,4CAA4C;IAC5C,kDAAkD;IAClD,uBAAuB;IACvB,eAAe;IACf,eAAe;IACf,UAAU;IACV,QAAQ;IACR,MAAM,gBAAgB,GAA4C,EAAE,CAAC;IACrE,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC1C,gDAAgD;YAChD,IAAI,KAAK,GAAG,EAAE,CAAC;YACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;gBACzB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;oBAAE,MAAM;YACzC,CAAC;YACD,gBAAgB,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,iFAAiF;IACjF,4EAA4E;IAC5E,MAAM,eAAe,GAAG,gBAAgB,CAAC,MAAM,CAC7C,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CACvE,CAAC;IAEF,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,KAAK,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,eAAe,EAAE,CAAC;QACpD,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAE/C,EAAE,CAAC,QAAQ,OAAO,qBAAqB,UAAU,+BAA+B,EAAE,GAAG,EAAE;YACrF,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,QAAQ,OAAO,qBAAqB,UAAU,8BAA8B,EAAE,GAAG,EAAE;YACpF,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -305,6 +305,10 @@ function printAppScenarioInstructions(pageName, route) {
|
|
|
305
305
|
console.log(chalk.dim(' Example: "Page - Full Data", "Page - Empty State", "Page - Error State"'));
|
|
306
306
|
}
|
|
307
307
|
console.log();
|
|
308
|
+
checkbox('Ensure every page file used in app scenarios has a glossary entry with its filePath:');
|
|
309
|
+
console.log(chalk.dim(' The register command validates pageFilePath against the glossary — add missing pages now.'));
|
|
310
|
+
console.log(chalk.dim(' Example: {"name":"CounterScreen","filePath":"app/(tabs)/index.tsx","type":"page","description":"Main counter page"}'));
|
|
311
|
+
console.log();
|
|
308
312
|
checkbox('Register each scenario with type "application", the real page URL, and pageFilePath:');
|
|
309
313
|
console.log(chalk.dim(` codeyam editor register '{"name":"${pageName || 'Page'} - Full Data",`));
|
|
310
314
|
console.log(chalk.dim(` "type":"application","url":"${route || '/'}","pageFilePath":"src/path/to/Page.tsx",...}'`));
|
|
@@ -402,9 +406,15 @@ function printExtractionPlanInstructions() {
|
|
|
402
406
|
function printComponentCaptureInstructions(root) {
|
|
403
407
|
const ctx = root ? getTechStackContext(root) : undefined;
|
|
404
408
|
const isExpo = ctx?.isExpo ?? false;
|
|
405
|
-
checkbox('
|
|
406
|
-
|
|
407
|
-
|
|
409
|
+
checkbox('Set up isolation routes: `codeyam editor isolate ComponentA ComponentB ...`');
|
|
410
|
+
if (isExpo) {
|
|
411
|
+
console.log(chalk.dim(' This creates app/isolated-components/_layout.tsx (with __DEV__ guard).'));
|
|
412
|
+
console.log(chalk.dim(' You then create a flat .tsx file per component (NOT subdirectories — Expo Router uses flat files).'));
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
console.log(chalk.dim(` This creates app/isolated-components/layout.tsx (with notFound() guard) and`));
|
|
416
|
+
console.log(chalk.dim(' a directory per component. List ALL components that need isolation routes.'));
|
|
417
|
+
}
|
|
408
418
|
checkbox('For each visual component:');
|
|
409
419
|
console.log(chalk.dim(' 1. Read the source AND find where it is used in the app to understand:'));
|
|
410
420
|
console.log(chalk.dim(' — Props/interface'));
|
|
@@ -805,8 +815,8 @@ function printSetup(root) {
|
|
|
805
815
|
console.log(chalk.bold('Tech Stack Selection:'));
|
|
806
816
|
console.log(chalk.dim(' Based on the selected formats, present ONLY the matching tech stacks.'));
|
|
807
817
|
console.log(chalk.dim(' A stack matches if ANY of the user\'s selected formats appears in its "Supports" list.'));
|
|
808
|
-
console.log(chalk.dim('
|
|
809
|
-
console.log(chalk.dim('
|
|
818
|
+
console.log(chalk.dim(' If only ONE stack matches, confirm it directly (e.g. "Expo + React Native is the only stack for mobile apps — using that.").'));
|
|
819
|
+
console.log(chalk.dim(' If MULTIPLE stacks match, use AskUserQuestion to let the user pick one.'));
|
|
810
820
|
console.log();
|
|
811
821
|
console.log(chalk.bold(' Available Tech Stacks:'));
|
|
812
822
|
for (const stack of TECH_STACKS) {
|
|
@@ -1249,6 +1259,8 @@ function printStep4(root, feature) {
|
|
|
1249
1259
|
label: STEP_LABELS[4],
|
|
1250
1260
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1251
1261
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1262
|
+
appFormats: prevState?.appFormats,
|
|
1263
|
+
techStackId: prevState?.techStackId,
|
|
1252
1264
|
});
|
|
1253
1265
|
logEvent(root, 'step', { step: 4, label: 'Verify Prototype', feature });
|
|
1254
1266
|
stepHeader(4, 'Verify Prototype', feature);
|
|
@@ -1305,6 +1317,8 @@ function printStep5(root, feature) {
|
|
|
1305
1317
|
label: STEP_LABELS[5],
|
|
1306
1318
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1307
1319
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1320
|
+
appFormats: prevState?.appFormats,
|
|
1321
|
+
techStackId: prevState?.techStackId,
|
|
1308
1322
|
});
|
|
1309
1323
|
logEvent(root, 'step', { step: 5, label: 'Confirm', feature });
|
|
1310
1324
|
stepHeader(5, 'Confirm', feature);
|
|
@@ -1364,6 +1378,8 @@ function printStep6(root, feature) {
|
|
|
1364
1378
|
label: STEP_LABELS[6],
|
|
1365
1379
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1366
1380
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1381
|
+
appFormats: prevState?.appFormats,
|
|
1382
|
+
techStackId: prevState?.techStackId,
|
|
1367
1383
|
});
|
|
1368
1384
|
logEvent(root, 'step', { step: 6, label: 'Deconstruct', feature });
|
|
1369
1385
|
stepHeader(6, 'Deconstruct', feature);
|
|
@@ -1389,6 +1405,8 @@ function printStep7(root, feature) {
|
|
|
1389
1405
|
label: STEP_LABELS[7],
|
|
1390
1406
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1391
1407
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1408
|
+
appFormats: prevState?.appFormats,
|
|
1409
|
+
techStackId: prevState?.techStackId,
|
|
1392
1410
|
});
|
|
1393
1411
|
logEvent(root, 'step', { step: 7, label: 'Extract', feature });
|
|
1394
1412
|
stepHeader(7, 'Extract', feature);
|
|
@@ -1409,6 +1427,7 @@ function printStep7(root, feature) {
|
|
|
1409
1427
|
console.log(chalk.dim(' Cover: typical inputs, edge cases, empty/null inputs, error conditions'));
|
|
1410
1428
|
console.log(chalk.dim(' Aim for 3-8 test cases per function depending on complexity'));
|
|
1411
1429
|
console.log(chalk.dim(' Hooks count as functions — useDrinks, useAuth, etc. all need test files'));
|
|
1430
|
+
console.log(chalk.dim(' Wrap all tests in a describe("FunctionName", ...) block — the audit matches on this name'));
|
|
1412
1431
|
if (ctx.isExpo) {
|
|
1413
1432
|
checkbox('Place test files next to source but OUTSIDE `app/` (Expo Router treats all files in app/ as routes): `lib/storage.ts` → `lib/storage.test.ts`, `app/hooks/useCounter.ts` → `__tests__/hooks/useCounter.test.ts`');
|
|
1414
1433
|
}
|
|
@@ -1446,6 +1465,8 @@ function printStep8(root, feature) {
|
|
|
1446
1465
|
label: STEP_LABELS[8],
|
|
1447
1466
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1448
1467
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1468
|
+
appFormats: prevState?.appFormats,
|
|
1469
|
+
techStackId: prevState?.techStackId,
|
|
1449
1470
|
});
|
|
1450
1471
|
logEvent(root, 'step', { step: 8, label: 'Glossary', feature });
|
|
1451
1472
|
stepHeader(8, 'Glossary', feature);
|
|
@@ -1472,6 +1493,8 @@ function printStep9(root, feature) {
|
|
|
1472
1493
|
label: STEP_LABELS[9],
|
|
1473
1494
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1474
1495
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1496
|
+
appFormats: prevState?.appFormats,
|
|
1497
|
+
techStackId: prevState?.techStackId,
|
|
1475
1498
|
});
|
|
1476
1499
|
logEvent(root, 'step', { step: 9, label: 'Analyze', feature });
|
|
1477
1500
|
stepHeader(9, 'Analyze and Verify', feature);
|
|
@@ -1522,6 +1545,8 @@ function printStep10(root, feature) {
|
|
|
1522
1545
|
label: STEP_LABELS[10],
|
|
1523
1546
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1524
1547
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1548
|
+
appFormats: prevState?.appFormats,
|
|
1549
|
+
techStackId: prevState?.techStackId,
|
|
1525
1550
|
});
|
|
1526
1551
|
logEvent(root, 'step', { step: 10, label: 'App Scenarios', feature });
|
|
1527
1552
|
stepHeader(10, 'App Scenarios', feature);
|
|
@@ -1586,6 +1611,8 @@ function printStep11(root, feature) {
|
|
|
1586
1611
|
label: STEP_LABELS[11],
|
|
1587
1612
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1588
1613
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1614
|
+
appFormats: prevState?.appFormats,
|
|
1615
|
+
techStackId: prevState?.techStackId,
|
|
1589
1616
|
});
|
|
1590
1617
|
logEvent(root, 'step', { step: 11, label: 'User Scenarios', feature });
|
|
1591
1618
|
stepHeader(11, 'User Scenarios', feature);
|
|
@@ -1632,6 +1659,8 @@ function printStep12(root, feature) {
|
|
|
1632
1659
|
label: STEP_LABELS[12],
|
|
1633
1660
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1634
1661
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1662
|
+
appFormats: prevState?.appFormats,
|
|
1663
|
+
techStackId: prevState?.techStackId,
|
|
1635
1664
|
});
|
|
1636
1665
|
logEvent(root, 'step', { step: 12, label: 'Verify', feature });
|
|
1637
1666
|
stepHeader(12, 'Verify', feature);
|
|
@@ -1678,6 +1707,8 @@ function printStep13(root, feature) {
|
|
|
1678
1707
|
label: STEP_LABELS[13],
|
|
1679
1708
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1680
1709
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1710
|
+
appFormats: prevState?.appFormats,
|
|
1711
|
+
techStackId: prevState?.techStackId,
|
|
1681
1712
|
});
|
|
1682
1713
|
logEvent(root, 'step', { step: 13, label: 'Journal', feature });
|
|
1683
1714
|
stepHeader(13, 'Journal', feature);
|
|
@@ -1711,6 +1742,8 @@ function printStep14(root, feature) {
|
|
|
1711
1742
|
label: STEP_LABELS[14],
|
|
1712
1743
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1713
1744
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1745
|
+
appFormats: prevState?.appFormats,
|
|
1746
|
+
techStackId: prevState?.techStackId,
|
|
1714
1747
|
});
|
|
1715
1748
|
logEvent(root, 'step', { step: 14, label: 'Review', feature });
|
|
1716
1749
|
stepHeader(14, 'Review', feature);
|
|
@@ -1744,6 +1777,8 @@ function printStep15(root, feature) {
|
|
|
1744
1777
|
label: STEP_LABELS[15],
|
|
1745
1778
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
1746
1779
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
1780
|
+
appFormats: prevState?.appFormats,
|
|
1781
|
+
techStackId: prevState?.techStackId,
|
|
1747
1782
|
});
|
|
1748
1783
|
logEvent(root, 'step', { step: 15, label: 'Present', feature });
|
|
1749
1784
|
stepHeader(15, 'Present', feature);
|
|
@@ -2393,6 +2428,8 @@ function printStep16(root, feature) {
|
|
|
2393
2428
|
label: STEP_LABELS[16],
|
|
2394
2429
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
2395
2430
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
2431
|
+
appFormats: prevState?.appFormats,
|
|
2432
|
+
techStackId: prevState?.techStackId,
|
|
2396
2433
|
});
|
|
2397
2434
|
logEvent(root, 'step', { step: 16, label: 'Commit', feature });
|
|
2398
2435
|
stepHeader(16, 'Commit', feature);
|
|
@@ -2419,6 +2456,8 @@ function printStep17(root, feature) {
|
|
|
2419
2456
|
label: STEP_LABELS[17],
|
|
2420
2457
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
2421
2458
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
2459
|
+
appFormats: prevState?.appFormats,
|
|
2460
|
+
techStackId: prevState?.techStackId,
|
|
2422
2461
|
});
|
|
2423
2462
|
logEvent(root, 'step', { step: 17, label: 'Finalize', feature });
|
|
2424
2463
|
stepHeader(17, 'Finalize', feature);
|
|
@@ -2444,6 +2483,8 @@ function printStep18(root, feature) {
|
|
|
2444
2483
|
label: STEP_LABELS[18],
|
|
2445
2484
|
startedAt: isResuming ? prevState.startedAt : now,
|
|
2446
2485
|
featureStartedAt: prevState?.featureStartedAt || now,
|
|
2486
|
+
appFormats: prevState?.appFormats,
|
|
2487
|
+
techStackId: prevState?.techStackId,
|
|
2447
2488
|
});
|
|
2448
2489
|
logEvent(root, 'step', { step: 18, label: 'Push', feature });
|
|
2449
2490
|
stepHeader(18, 'Push', feature);
|
|
@@ -2884,8 +2925,13 @@ function handleIsolate(componentNames) {
|
|
|
2884
2925
|
process.exit(1);
|
|
2885
2926
|
}
|
|
2886
2927
|
const isolateDir = path.join(root, 'app', 'isolated-components');
|
|
2887
|
-
// Create
|
|
2928
|
+
// Create the framework-appropriate layout guard if missing.
|
|
2929
|
+
// Clean up wrong-framework layout from a previous CLI version.
|
|
2888
2930
|
const layoutPath = path.join(isolateDir, ctx.isExpo ? '_layout.tsx' : 'layout.tsx');
|
|
2931
|
+
const wrongLayoutPath = path.join(isolateDir, ctx.isExpo ? 'layout.tsx' : '_layout.tsx');
|
|
2932
|
+
if (fs.existsSync(wrongLayoutPath)) {
|
|
2933
|
+
fs.unlinkSync(wrongLayoutPath);
|
|
2934
|
+
}
|
|
2889
2935
|
if (!fs.existsSync(layoutPath)) {
|
|
2890
2936
|
fs.mkdirSync(isolateDir, { recursive: true });
|
|
2891
2937
|
if (ctx.isExpo) {
|
|
@@ -2938,7 +2984,13 @@ function handleIsolate(componentNames) {
|
|
|
2938
2984
|
}
|
|
2939
2985
|
}
|
|
2940
2986
|
if (created.length > 0) {
|
|
2941
|
-
|
|
2987
|
+
if (ctx.isExpo) {
|
|
2988
|
+
console.log(chalk.green(`Ready for ${created.length} isolation route(s): ${created.map((n) => `app/isolated-components/${n}.tsx`).join(', ')}`));
|
|
2989
|
+
console.log(chalk.dim(' Create each file with useLocalSearchParams, a scenarios map, and nativeID="codeyam-capture"'));
|
|
2990
|
+
}
|
|
2991
|
+
else {
|
|
2992
|
+
console.log(chalk.green(`Created ${created.length} isolation route dir(s): ${created.join(', ')}`));
|
|
2993
|
+
}
|
|
2942
2994
|
}
|
|
2943
2995
|
if (existed.length > 0) {
|
|
2944
2996
|
console.log(chalk.dim(`Already existed: ${existed.join(', ')}`));
|
|
@@ -3954,7 +4006,8 @@ async function handleAudit(options) {
|
|
|
3954
4006
|
if (f.errorMessage) {
|
|
3955
4007
|
detail += `\n ${chalk.red(f.errorMessage)}`;
|
|
3956
4008
|
detail += `\n ${chalk.yellow('Note: This is NOT a test failure — the test runner itself could not execute.')}`;
|
|
3957
|
-
|
|
4009
|
+
const ctx = getTechStackContext(process.cwd());
|
|
4010
|
+
detail += `\n ${chalk.yellow('Try running the test manually: ' + ctx.testRunCommand + ' ' + f.testFile)}`;
|
|
3958
4011
|
}
|
|
3959
4012
|
break;
|
|
3960
4013
|
case 'failing':
|