@codeyam/codeyam-cli 0.1.4 → 0.1.6

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 (151) 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 +14 -14
  4. package/analyzer-template/packages/ai/package.json +1 -1
  5. package/analyzer-template/packages/ai/src/lib/completionCall.ts +102 -113
  6. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +232 -5
  7. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/stripNullableMarkers.ts +35 -0
  8. package/analyzer-template/packages/analyze/src/lib/asts/nodes/getNodeType.ts +1 -0
  9. package/analyzer-template/packages/aws/package.json +10 -10
  10. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
  11. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +6 -2
  12. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  13. package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +14 -2
  14. package/analyzer-template/project/constructMockCode.ts +32 -5
  15. package/analyzer-template/project/orchestrateCapture.ts +4 -1
  16. package/analyzer-template/project/writeScenarioComponents.ts +62 -12
  17. package/background/src/lib/virtualized/project/constructMockCode.js +28 -5
  18. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  19. package/background/src/lib/virtualized/project/orchestrateCapture.js +4 -1
  20. package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
  21. package/background/src/lib/virtualized/project/writeScenarioComponents.js +46 -7
  22. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  23. package/codeyam-cli/src/cli.js +30 -25
  24. package/codeyam-cli/src/cli.js.map +1 -1
  25. package/codeyam-cli/src/commands/memory.js +3 -56
  26. package/codeyam-cli/src/commands/memory.js.map +1 -1
  27. package/codeyam-cli/src/utils/__tests__/npmVersionCheck.test.js +6 -0
  28. package/codeyam-cli/src/utils/__tests__/npmVersionCheck.test.js.map +1 -1
  29. package/codeyam-cli/src/utils/install-skills.js +4 -4
  30. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  31. package/codeyam-cli/src/utils/npmVersionCheck.js +2 -2
  32. package/codeyam-cli/src/utils/npmVersionCheck.js.map +1 -1
  33. package/codeyam-cli/src/utils/requireSimulations.js +1 -1
  34. package/codeyam-cli/src/utils/requireSimulations.js.map +1 -1
  35. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +5 -6
  36. package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -1
  37. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +2 -5
  38. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -1
  39. package/codeyam-cli/src/utils/rules/__tests__/parser.test.js +83 -0
  40. package/codeyam-cli/src/utils/rules/__tests__/parser.test.js.map +1 -0
  41. package/codeyam-cli/src/utils/rules/__tests__/pathMatcher.test.js +118 -0
  42. package/codeyam-cli/src/utils/rules/__tests__/pathMatcher.test.js.map +1 -0
  43. package/codeyam-cli/src/utils/rules/__tests__/rulePlacement.test.js +72 -0
  44. package/codeyam-cli/src/utils/rules/__tests__/rulePlacement.test.js.map +1 -0
  45. package/codeyam-cli/src/utils/rules/__tests__/sourceFiles.test.js +76 -0
  46. package/codeyam-cli/src/utils/rules/__tests__/sourceFiles.test.js.map +1 -0
  47. package/codeyam-cli/src/utils/rules/index.js +1 -0
  48. package/codeyam-cli/src/utils/rules/index.js.map +1 -1
  49. package/codeyam-cli/src/utils/rules/parser.js +14 -4
  50. package/codeyam-cli/src/utils/rules/parser.js.map +1 -1
  51. package/codeyam-cli/src/utils/rules/pathMatcher.js +34 -3
  52. package/codeyam-cli/src/utils/rules/pathMatcher.js.map +1 -1
  53. package/codeyam-cli/src/utils/rules/rulePlacement.js +65 -0
  54. package/codeyam-cli/src/utils/rules/rulePlacement.js.map +1 -0
  55. package/codeyam-cli/src/utils/rules/sourceFiles.js +43 -0
  56. package/codeyam-cli/src/utils/rules/sourceFiles.js.map +1 -0
  57. package/codeyam-cli/src/utils/simulationGateMiddleware.js +159 -0
  58. package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -0
  59. package/codeyam-cli/src/utils/syncMocksMiddleware.js +5 -24
  60. package/codeyam-cli/src/utils/syncMocksMiddleware.js.map +1 -1
  61. package/codeyam-cli/src/utils/versionInfo.js +21 -0
  62. package/codeyam-cli/src/utils/versionInfo.js.map +1 -1
  63. package/codeyam-cli/src/webserver/app/routes/api.agent-transcripts.js +486 -0
  64. package/codeyam-cli/src/webserver/app/routes/api.agent-transcripts.js.map +1 -0
  65. package/codeyam-cli/src/webserver/backgroundServer.js +10 -0
  66. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  67. package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-jNYXRRNI.js → CopyButton-CtmbP4Gl.js} +1 -1
  68. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-bwuHPyTa.js → EntityItem-DlMph_Hm.js} +1 -1
  69. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-CvzqMxcu.js → EntityTypeBadge-B-0PjGOU.js} +1 -1
  70. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-BH0XDim7.js → EntityTypeIcon-DN9eiJAO.js} +1 -1
  71. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-EhOseatT.js → InlineSpinner-C1rIyZdV.js} +1 -1
  72. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-yjIHlOGa.js → InteractivePreview-rE_fI2h2.js} +2 -2
  73. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-Cq5o8jL4.js → LibraryFunctionPreview-CnatsCw2.js} +1 -1
  74. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-BvMu2i-g.js → LoadingDots-CSP6DZrh.js} +1 -1
  75. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-kgBTLoJD.js → LogViewer-CMK8Q7yk.js} +1 -1
  76. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-BzPgx-xO.js → ReportIssueModal-TCV_HBjy.js} +1 -1
  77. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-CwZrv-Ok.js → SafeScreenshot-CG2uh31y.js} +1 -1
  78. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-BX2Ny2Qj.js → ScenarioViewer-CU_TDYd8.js} +1 -1
  79. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-CDpEprKa.js → TruncatedFilePath-D7IoaWUW.js} +1 -1
  80. package/codeyam-cli/src/webserver/build/client/assets/{_index-BRx8ZGZo.js → _index-B8z7mjR-.js} +1 -1
  81. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-4S4yPfFw.js → activity.(_tab)-DZu78RI1.js} +1 -1
  82. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DxCa1oBt.js +23 -0
  83. package/codeyam-cli/src/webserver/build/client/assets/api.rule-path-l0sNRNKZ.js +1 -0
  84. package/codeyam-cli/src/webserver/build/client/assets/{book-open-D4IPYH_y.js → book-open-Bp5FLkd4.js} +1 -1
  85. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-CG65viiV.js → chevron-down-DQJA9f4o.js} +1 -1
  86. package/codeyam-cli/src/webserver/build/client/assets/{chunk-JZWAC4HX-DB3aFuEO.js → chunk-JZWAC4HX-7VptmeIr.js} +1 -1
  87. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-igfMr5DY.js → circle-check-B6C4LY9o.js} +1 -1
  88. package/codeyam-cli/src/webserver/build/client/assets/{copy-Coc4o_8c.js → copy-6nzYCu0G.js} +1 -1
  89. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-D1zB-pYc.js → createLucideIcon-D-QUFOwe.js} +1 -1
  90. package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-JTAjQ54M.js → dev.empty-DmzSmblj.js} +1 -1
  91. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-B0h9AqE6.js → entity._sha._--zvFJ4OH.js} +1 -1
  92. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-DjLxr2JB.js → entity._sha.scenarios._scenarioId.fullscreen-DVTcUnur.js} +1 -1
  93. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-CtYowLOt.js → entity._sha_.create-scenario-BVgNO76F.js} +1 -1
  94. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-PePWg17F.js → entity._sha_.edit._scenarioId-C7ysA4Jq.js} +1 -1
  95. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-I-Wo99C_.js → entry.client-CU6EUArK.js} +1 -1
  96. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-9sMMAiWJ.js → fileTableUtils-EWpfFU4X.js} +1 -1
  97. package/codeyam-cli/src/webserver/build/client/assets/{files-Co65J0s3.js → files-CrxAoWIL.js} +1 -1
  98. package/codeyam-cli/src/webserver/build/client/assets/{git-BdHOxVfg.js → git-BldHtKeW.js} +1 -1
  99. package/codeyam-cli/src/webserver/build/client/assets/globals-B4MPiL7S.css +1 -0
  100. package/codeyam-cli/src/webserver/build/client/assets/{index-CUM5iXwc.js → index-7-1FmlHo.js} +1 -1
  101. package/codeyam-cli/src/webserver/build/client/assets/{index-_417gcQW.js → index-DuYcwYp_.js} +1 -1
  102. package/codeyam-cli/src/webserver/build/client/assets/labs-CPPVOSWB.js +1 -0
  103. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-TzRHMVog.js → loader-circle-BnDcD54R.js} +1 -1
  104. package/codeyam-cli/src/webserver/build/client/assets/manifest-c1fc3656.js +1 -0
  105. package/codeyam-cli/src/webserver/build/client/assets/{memory-UIDVz141.js → memory-CfpYxpNu.js} +23 -22
  106. package/codeyam-cli/src/webserver/build/client/assets/{pause-hjzB7t2z.js → pause-DhQX2g22.js} +1 -1
  107. package/codeyam-cli/src/webserver/build/client/assets/root-CAAbm4U5.js +62 -0
  108. package/codeyam-cli/src/webserver/build/client/assets/{search-DcAwD_Ln.js → search-DborVoKD.js} +1 -1
  109. package/codeyam-cli/src/webserver/build/client/assets/{settings-CclxrcPK.js → settings-BpLDWmGh.js} +1 -1
  110. package/codeyam-cli/src/webserver/build/client/assets/{simulations-DVNJVQgD.js → simulations-BtrtCYJg.js} +1 -1
  111. package/codeyam-cli/src/webserver/build/client/assets/{terminal-DbEAHMbA.js → terminal-Bs4NC-VZ.js} +1 -1
  112. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-CAD5b1o_.js → triangle-alert-DTf3Jojp.js} +1 -1
  113. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-BqgrAzs3.js → useCustomSizes-D_bDZyDU.js} +1 -1
  114. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-DAFqfEDH.js → useLastLogLine-DZp6rrQD.js} +1 -1
  115. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-DZlYx2c4.js → useReportContext-BsQb6rFd.js} +1 -1
  116. package/codeyam-cli/src/webserver/build/client/assets/{useToast-ihdMtlf6.js → useToast-BOur3mUv.js} +1 -1
  117. package/codeyam-cli/src/webserver/build/server/assets/{index-B3dE0r28.js → index-B8A_aaGG.js} +1 -1
  118. package/codeyam-cli/src/webserver/build/server/assets/server-build-69rRZnZo.js +286 -0
  119. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  120. package/codeyam-cli/src/webserver/build-info.json +5 -5
  121. package/codeyam-cli/templates/codeyam-new-rule.md +0 -2
  122. package/codeyam-cli/templates/hooks/staleness-check.sh +43 -0
  123. package/codeyam-cli/templates/prompts/conversation-guidance.txt +32 -0
  124. package/codeyam-cli/templates/prompts/conversation-prompt.txt +28 -0
  125. package/codeyam-cli/templates/prompts/interruption-prompt.txt +31 -0
  126. package/codeyam-cli/templates/prompts/stale-rules-prompt.txt +24 -0
  127. package/codeyam-cli/templates/rules-instructions.md +33 -88
  128. package/package.json +5 -5
  129. package/packages/ai/src/lib/completionCall.js +0 -5
  130. package/packages/ai/src/lib/completionCall.js.map +1 -1
  131. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +213 -3
  132. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  133. package/packages/analyze/src/lib/asts/nodes/getNodeType.js +1 -0
  134. package/packages/analyze/src/lib/asts/nodes/getNodeType.js.map +1 -1
  135. package/packages/utils/src/lib/fs/rsyncCopy.js +6 -2
  136. package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  137. package/codeyam-cli/src/commands/detect-universal-mocks.js +0 -120
  138. package/codeyam-cli/src/commands/detect-universal-mocks.js.map +0 -1
  139. package/codeyam-cli/src/commands/list.js +0 -31
  140. package/codeyam-cli/src/commands/list.js.map +0 -1
  141. package/codeyam-cli/src/commands/webapp-info.js +0 -146
  142. package/codeyam-cli/src/commands/webapp-info.js.map +0 -1
  143. package/codeyam-cli/src/utils/universal-mocks.js +0 -152
  144. package/codeyam-cli/src/utils/universal-mocks.js.map +0 -1
  145. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DHKuQSmR.js +0 -17
  146. package/codeyam-cli/src/webserver/build/client/assets/globals-BSZfYCkU.css +0 -1
  147. package/codeyam-cli/src/webserver/build/client/assets/labs-BK0C1H1T.js +0 -1
  148. package/codeyam-cli/src/webserver/build/client/assets/manifest-040dab1c.js +0 -1
  149. package/codeyam-cli/src/webserver/build/client/assets/root-D1WadSdf.js +0 -62
  150. package/codeyam-cli/src/webserver/build/server/assets/server-build-DYbfdxa3.js +0 -273
  151. package/codeyam-cli/templates/codeyam-stop-hook.sh +0 -284
@@ -1,10 +1,10 @@
1
1
  {
2
- "buildTimestamp": "2026-02-14T14:55:04.828Z",
3
- "buildTime": 1771080904828,
4
- "gitCommit": "363c3939b0b49bd96be6efd33c0b232b395dcb10",
2
+ "buildTimestamp": "2026-02-24T16:49:42.311Z",
3
+ "buildTime": 1771951782311,
4
+ "gitCommit": "fb5c6c43d47cae2bdd39cf0e2bfc7eb7f6a9c77e",
5
5
  "nodeVersion": "v20.20.0",
6
- "contentHash": "7f2a19190511996b687bdd764ab6297993590ece837b6bbdec8bda87b904ab50",
7
- "buildNumber": 629,
8
- "semanticVersion": "0.1.629",
9
- "version": "0.1.629 (2026-02-14T14:55+7f2a191)"
6
+ "contentHash": "4a186f37ec4532e5a53e13c6fe2b2ce95a580cd45c739dc01a9ed7688ff1f99a",
7
+ "buildNumber": 674,
8
+ "semanticVersion": "0.1.674",
9
+ "version": "0.1.674 (2026-02-24T16:49+4a186f3)"
10
10
  }
@@ -1,7 +1,7 @@
1
1
 
2
- [2/14/2026, 2:55:04 PM] > codeyam-combo@1.0.0 mergeDependencies
3
- [2/14/2026, 2:55:04 PM] > node ./scripts/mergePackageJsonFiles.cjs
2
+ [2/24/2026, 4:49:42 PM] > codeyam-combo@1.0.0 mergeDependencies
3
+ [2/24/2026, 4:49:42 PM] > node ./scripts/mergePackageJsonFiles.cjs
4
4
 
5
5
 
6
- [2/14/2026, 2:55:04 PM] Merged dependencies into root package.json
6
+ [2/24/2026, 4:49:42 PM] Merged dependencies into root package.json
7
7
 
@@ -7,17 +7,17 @@
7
7
  "build": "tsc && node ./scripts/postbuild.cjs"
8
8
  },
9
9
  "dependencies": {
10
- "@aws-sdk/client-cloudwatch-logs": "^3.980.0",
11
- "@aws-sdk/client-cloudfront": "^3.985.0",
12
- "@aws-sdk/client-codebuild": "^3.948.0",
13
- "@aws-sdk/client-dynamodb": "^3.956.0",
14
- "@aws-sdk/client-ec2": "^3.899.0",
15
- "@aws-sdk/client-ecr": "^3.948.0",
16
- "@aws-sdk/client-ecs": "^3.956.0",
17
- "@aws-sdk/client-s3": "^3.940.0",
18
- "@aws-sdk/client-sqs": "^3.956.0",
19
- "@aws-sdk/lib-storage": "^3.975.0",
20
- "@aws-sdk/util-dynamodb": "^3.971.0",
10
+ "@aws-sdk/client-cloudwatch-logs": "^3.990.0",
11
+ "@aws-sdk/client-cloudfront": "^3.990.0",
12
+ "@aws-sdk/client-codebuild": "^3.995.0",
13
+ "@aws-sdk/client-dynamodb": "^3.990.0",
14
+ "@aws-sdk/client-ec2": "^3.990.0",
15
+ "@aws-sdk/client-ecr": "^3.990.0",
16
+ "@aws-sdk/client-ecs": "^3.990.0",
17
+ "@aws-sdk/client-s3": "^3.990.0",
18
+ "@aws-sdk/client-sqs": "^3.990.0",
19
+ "@aws-sdk/lib-storage": "^3.990.0",
20
+ "@aws-sdk/util-dynamodb": "^3.990.0",
21
21
  "@octokit/auth-app": "^8.1.0",
22
22
  "@octokit/rest": "^22.0.0",
23
23
  "@sendgrid/mail": "^8.1.4",
@@ -26,13 +26,13 @@
26
26
  "dotenv": "^17.2.3",
27
27
  "express": "^5.2.1",
28
28
  "get-port": "^7.1.0",
29
- "htmlparser2": "^10.0.0",
29
+ "htmlparser2": "^10.1.0",
30
30
  "jest": "^30.2.0",
31
31
  "jsdom": "^27.4.0",
32
32
  "jsonc-parser": "^3.2.1",
33
33
  "lru-cache": "^11.2.5",
34
34
  "openai": "^6.16.0",
35
- "p-queue": "^8.1.0",
35
+ "p-queue": "^9.1.0",
36
36
  "p-retry": "^7.1.1",
37
37
  "piscina": "^5.1.4",
38
38
  "pixelmatch": "^5.3.0",
@@ -45,7 +45,7 @@
45
45
  "yargs": "^18.0.0",
46
46
  "json5": "^2.2.3",
47
47
  "@anthropic-ai/sdk": "^0.74.0",
48
- "@aws-sdk/s3-request-presigner": "^3.940.0",
48
+ "@aws-sdk/s3-request-presigner": "^3.990.0",
49
49
  "better-sqlite3": "^12.4.1",
50
50
  "fetch-retry": "^6.0.0",
51
51
  "kysely": "^0.28.11",
@@ -11,7 +11,7 @@
11
11
  "dependencies": {
12
12
  "@anthropic-ai/sdk": "^0.74.0",
13
13
  "jsdom": "^27.4.0",
14
- "p-queue": "^8.1.0",
14
+ "p-queue": "^9.1.0",
15
15
  "p-retry": "^7.1.1",
16
16
  "piscina": "^5.1.4",
17
17
  "lru-cache": "^11.2.5"
@@ -36,7 +36,6 @@ interface CompletionCallProps {
36
36
  const queue = new PQueue({
37
37
  concurrency: 100,
38
38
  timeout: 20 * 60 * 1000, // 20 minutes
39
- throwOnTimeout: true,
40
39
  autoStart: true,
41
40
  });
42
41
 
@@ -135,62 +134,57 @@ export default async function completionCall({
135
134
  };
136
135
  const params = lib.openai.chatRequestToOpenAIChatParams(chatRequest);
137
136
 
138
- const chatCompletion = await queue.add(
139
- () => {
140
- queueEndTime = Date.now();
141
- return PRetry(
142
- async () => {
143
- const callStartTime = Date.now();
144
- const waitingMessages = [
145
- 'Waiting for LLM response',
146
- 'Still waiting for LLM response',
147
- 'LLM call in progress',
148
- 'Processing LLM request',
149
- 'Awaiting LLM completion',
150
- ];
151
-
152
- const logInterval = setInterval(() => {
153
- const elapsedSeconds = Math.floor(
154
- (Date.now() - callStartTime) / 1000,
155
- );
156
- const messageIndex =
157
- Math.floor(elapsedSeconds / 10) % waitingMessages.length;
158
- awsLogDebugLevel(
159
- 1,
160
- `${waitingMessages[messageIndex]} [type=${type}, model=${model}, elapsed=${elapsedSeconds}s]`,
161
- );
162
- }, 10000);
137
+ const chatCompletion = await queue.add(() => {
138
+ queueEndTime = Date.now();
139
+ return PRetry(
140
+ async () => {
141
+ const callStartTime = Date.now();
142
+ const waitingMessages = [
143
+ 'Waiting for LLM response',
144
+ 'Still waiting for LLM response',
145
+ 'LLM call in progress',
146
+ 'Processing LLM request',
147
+ 'Awaiting LLM completion',
148
+ ];
149
+
150
+ const logInterval = setInterval(() => {
151
+ const elapsedSeconds = Math.floor(
152
+ (Date.now() - callStartTime) / 1000,
153
+ );
154
+ const messageIndex =
155
+ Math.floor(elapsedSeconds / 10) % waitingMessages.length;
156
+ awsLogDebugLevel(
157
+ 1,
158
+ `${waitingMessages[messageIndex]} [type=${type}, model=${model}, elapsed=${elapsedSeconds}s]`,
159
+ );
160
+ }, 10000);
163
161
 
164
- try {
165
- return await openai.chat.completions.create(params, {
166
- timeout: 5 * 60 * 1000, // 5 minute timeout
167
- });
168
- } finally {
169
- clearInterval(logInterval);
170
- }
171
- },
172
- {
173
- ...defaultRetryOptions,
174
- onFailedAttempt: (error) => {
175
- retryCount++;
176
- console.log(
177
- `CodeYam Error: Completion call failed [model=${model}]`,
178
- {
179
- error,
180
- prompt,
181
- systemMessage,
182
- attempts,
183
- retryCount,
184
- },
185
- );
186
- },
162
+ try {
163
+ return await openai.chat.completions.create(params, {
164
+ timeout: 5 * 60 * 1000, // 5 minute timeout
165
+ });
166
+ } finally {
167
+ clearInterval(logInterval);
168
+ }
169
+ },
170
+ {
171
+ ...defaultRetryOptions,
172
+ onFailedAttempt: (error) => {
173
+ retryCount++;
174
+ console.log(
175
+ `CodeYam Error: Completion call failed [model=${model}]`,
176
+ {
177
+ error,
178
+ prompt,
179
+ systemMessage,
180
+ attempts,
181
+ retryCount,
182
+ },
183
+ );
187
184
  },
188
- );
189
- },
190
- {
191
- throwOnTimeout: true,
192
- },
193
- );
185
+ },
186
+ );
187
+ });
194
188
  const endTime = Date.now();
195
189
 
196
190
  const llmCallStats = getLLMCallStats({
@@ -310,65 +304,60 @@ ${completion}
310
304
 
311
305
  Please provide a corrected version with valid JSON only. Do not include any explanatory text, just the valid JSON object.`;
312
306
 
313
- const correctionChatCompletion = await queue.add(
314
- () => {
315
- return PRetry(
316
- async () => {
317
- const correctionStartTime = Date.now();
318
- const waitingMessages = [
319
- 'Waiting for LLM correction response',
320
- 'Still waiting for LLM correction',
321
- 'LLM correction in progress',
322
- 'Processing LLM correction request',
323
- 'Awaiting LLM correction completion',
324
- ];
325
-
326
- const logInterval = setInterval(() => {
327
- const elapsedSeconds = Math.floor(
328
- (Date.now() - correctionStartTime) / 1000,
329
- );
330
- const messageIndex =
331
- Math.floor(elapsedSeconds / 10) % waitingMessages.length;
332
- awsLogDebugLevel(
333
- 1,
334
- `${waitingMessages[messageIndex]} [type=${type}, model=${model}, elapsed=${elapsedSeconds}s]`,
335
- );
336
- }, 10000);
337
-
338
- try {
339
- return await openai.chat.completions.create(
340
- {
341
- ...params,
342
- messages: [
343
- { role: 'system', content: systemMessage },
344
- { role: 'user', content: prompt },
345
- { role: 'assistant', content: completion },
346
- { role: 'user', content: correctionPrompt },
347
- ],
348
- },
349
- {
350
- timeout: 5 * 60 * 1000,
351
- },
352
- );
353
- } finally {
354
- clearInterval(logInterval);
355
- }
356
- },
357
- {
358
- ...defaultRetryOptions,
359
- onFailedAttempt: (error) => {
360
- console.log('CodeYam Error: Correction call failed', {
361
- error,
362
- attempts,
363
- });
364
- },
307
+ const correctionChatCompletion = await queue.add(() => {
308
+ return PRetry(
309
+ async () => {
310
+ const correctionStartTime = Date.now();
311
+ const waitingMessages = [
312
+ 'Waiting for LLM correction response',
313
+ 'Still waiting for LLM correction',
314
+ 'LLM correction in progress',
315
+ 'Processing LLM correction request',
316
+ 'Awaiting LLM correction completion',
317
+ ];
318
+
319
+ const logInterval = setInterval(() => {
320
+ const elapsedSeconds = Math.floor(
321
+ (Date.now() - correctionStartTime) / 1000,
322
+ );
323
+ const messageIndex =
324
+ Math.floor(elapsedSeconds / 10) % waitingMessages.length;
325
+ awsLogDebugLevel(
326
+ 1,
327
+ `${waitingMessages[messageIndex]} [type=${type}, model=${model}, elapsed=${elapsedSeconds}s]`,
328
+ );
329
+ }, 10000);
330
+
331
+ try {
332
+ return await openai.chat.completions.create(
333
+ {
334
+ ...params,
335
+ messages: [
336
+ { role: 'system', content: systemMessage },
337
+ { role: 'user', content: prompt },
338
+ { role: 'assistant', content: completion },
339
+ { role: 'user', content: correctionPrompt },
340
+ ],
341
+ },
342
+ {
343
+ timeout: 5 * 60 * 1000,
344
+ },
345
+ );
346
+ } finally {
347
+ clearInterval(logInterval);
348
+ }
349
+ },
350
+ {
351
+ ...defaultRetryOptions,
352
+ onFailedAttempt: (error) => {
353
+ console.log('CodeYam Error: Correction call failed', {
354
+ error,
355
+ attempts,
356
+ });
365
357
  },
366
- );
367
- },
368
- {
369
- throwOnTimeout: true,
370
- },
371
- );
358
+ },
359
+ );
360
+ });
372
361
 
373
362
  const correctedRawCompletion =
374
363
  correctionChatCompletion.choices?.[0]?.message?.content;
@@ -3360,6 +3360,22 @@ export class ScopeDataStructure {
3360
3360
  * ensure all sub-paths of that variable are reflected under signature[N].
3361
3361
  */
3362
3362
  private propagateParameterToSignaturePaths(scopeNode: ScopeNode) {
3363
+ // Helper: check if a type is a concrete scalar that cannot have sub-properties.
3364
+ const SCALAR_TYPES = new Set([
3365
+ 'string',
3366
+ 'number',
3367
+ 'boolean',
3368
+ 'bigint',
3369
+ 'symbol',
3370
+ 'void',
3371
+ 'never',
3372
+ ]);
3373
+ const isDefinitelyScalar = (type: string): boolean => {
3374
+ const parts = type.split('|').map((s) => s.trim());
3375
+ const base = parts.filter((s) => s !== 'undefined' && s !== 'null');
3376
+ return base.length > 0 && base.every((b) => SCALAR_TYPES.has(b));
3377
+ };
3378
+
3363
3379
  // Find variable → signature[N] equivalencies
3364
3380
  for (const [varName, equivalencies] of Object.entries(
3365
3381
  scopeNode.equivalencies,
@@ -3390,7 +3406,38 @@ export class ScopeDataStructure {
3390
3406
 
3391
3407
  // Only add if the signature path doesn't already exist
3392
3408
  if (!scopeNode.schema[sigKey]) {
3393
- scopeNode.schema[sigKey] = scopeNode.schema[key];
3409
+ // Check if this path represents variable conflation:
3410
+ // When a standalone variable (e.g., showWorkoutForm from useState)
3411
+ // appears as a sub-property of a scalar-typed ancestor (e.g.,
3412
+ // activity_type = "string"), it's from scope conflation, not real
3413
+ // property access. Block these while allowing legitimate built-in
3414
+ // accesses like string.length or string.slice.
3415
+ let isConflatedPath = false;
3416
+ let checkPos = signaturePath.length;
3417
+ while (true) {
3418
+ checkPos = sigKey.indexOf('.', checkPos + 1);
3419
+ if (checkPos === -1) break;
3420
+ const ancestorPath = sigKey.substring(0, checkPos);
3421
+ const ancestorType = scopeNode.schema[ancestorPath];
3422
+ if (ancestorType && isDefinitelyScalar(ancestorType)) {
3423
+ // Ancestor is scalar — check if the immediate sub-property
3424
+ // is also a standalone variable (indicating conflation)
3425
+ const afterDot = sigKey.substring(checkPos + 1);
3426
+ const nextSep = afterDot.search(/[.\[]/);
3427
+ const subPropName =
3428
+ nextSep === -1
3429
+ ? afterDot
3430
+ : afterDot.substring(0, nextSep);
3431
+ if (scopeNode.schema[subPropName] !== undefined) {
3432
+ isConflatedPath = true;
3433
+ break;
3434
+ }
3435
+ }
3436
+ }
3437
+
3438
+ if (!isConflatedPath) {
3439
+ scopeNode.schema[sigKey] = scopeNode.schema[key];
3440
+ }
3394
3441
  }
3395
3442
  }
3396
3443
  }
@@ -4165,6 +4212,24 @@ export class ScopeDataStructure {
4165
4212
  }
4166
4213
  }
4167
4214
 
4215
+ // Helper: check if a type is a concrete scalar that cannot have sub-properties.
4216
+ // e.g., "string", "number | undefined", "boolean | null" are scalar.
4217
+ // "object", "array", "function", "unknown", "Workout", etc. are NOT scalar.
4218
+ const SCALAR_TYPES = new Set([
4219
+ 'string',
4220
+ 'number',
4221
+ 'boolean',
4222
+ 'bigint',
4223
+ 'symbol',
4224
+ 'void',
4225
+ 'never',
4226
+ ]);
4227
+ const isDefinitelyScalarType = (type: string): boolean => {
4228
+ const parts = type.split('|').map((s) => s.trim());
4229
+ const base = parts.filter((s) => s !== 'undefined' && s !== 'null');
4230
+ return base.length > 0 && base.every((b) => SCALAR_TYPES.has(b));
4231
+ };
4232
+
4168
4233
  // Propagate nested paths from variables to their signature equivalents
4169
4234
  // e.g., if workouts = signature[0].workouts, then workouts[].title becomes
4170
4235
  // signature[0].workouts[].title
@@ -4189,7 +4254,69 @@ export class ScopeDataStructure {
4189
4254
 
4190
4255
  // Add to schema if not already present
4191
4256
  if (!tempScopeNode.schema[signatureKey]) {
4192
- tempScopeNode.schema[signatureKey] = schema[schemaKey];
4257
+ // Check if this path represents variable conflation:
4258
+ // When a standalone variable (e.g., showWorkoutForm from useState)
4259
+ // appears as a sub-property of a scalar-typed ancestor (e.g.,
4260
+ // activity_type = "string"), it's from scope conflation, not real
4261
+ // property access. Block these while allowing legitimate built-in
4262
+ // accesses like string.length or string.slice.
4263
+ let isConflatedPath = false;
4264
+ let checkPos = signaturePath.length;
4265
+ while (true) {
4266
+ checkPos = signatureKey.indexOf('.', checkPos + 1);
4267
+ if (checkPos === -1) break;
4268
+ const ancestorPath = signatureKey.substring(0, checkPos);
4269
+ const ancestorType = tempScopeNode.schema[ancestorPath];
4270
+ if (ancestorType && isDefinitelyScalarType(ancestorType)) {
4271
+ // Ancestor is scalar — check if the immediate sub-property
4272
+ // is also a standalone variable (indicating conflation)
4273
+ const afterDot = signatureKey.substring(checkPos + 1);
4274
+ const nextSep = afterDot.search(/[.\[]/);
4275
+ const subPropName =
4276
+ nextSep === -1 ? afterDot : afterDot.substring(0, nextSep);
4277
+ if (schema[subPropName] !== undefined) {
4278
+ isConflatedPath = true;
4279
+ break;
4280
+ }
4281
+ }
4282
+ }
4283
+
4284
+ if (!isConflatedPath) {
4285
+ tempScopeNode.schema[signatureKey] = schema[schemaKey];
4286
+ }
4287
+ }
4288
+ }
4289
+ }
4290
+ }
4291
+
4292
+ // Post-process: filter out conflated signature paths.
4293
+ // During phase 2 scope analysis, useState(false) conflation can create
4294
+ // bad paths like signature[0].mockWorkouts[].activity_type.showWorkoutForm
4295
+ // directly in scopeNode.schema. These flow through signatureInSchema into
4296
+ // tempScopeNode.schema without any guard. Filter them out here by checking:
4297
+ // 1. An ancestor in the path has a concrete scalar type (string, number, boolean, etc.)
4298
+ // 2. The immediate sub-property of that scalar ancestor is also a standalone
4299
+ // variable in the schema (indicating conflation, not a real property access)
4300
+ for (const key of Object.keys(tempScopeNode.schema)) {
4301
+ if (!key.startsWith('signature[')) continue;
4302
+
4303
+ // Walk through the path looking for scalar-typed ancestors
4304
+ let pos = 0;
4305
+ while (true) {
4306
+ pos = key.indexOf('.', pos + 1);
4307
+ if (pos === -1) break;
4308
+ const ancestorPath = key.substring(0, pos);
4309
+ const ancestorType = tempScopeNode.schema[ancestorPath];
4310
+ if (ancestorType && isDefinitelyScalarType(ancestorType)) {
4311
+ // Found a scalar ancestor — check if the sub-property name
4312
+ // is a standalone variable in the getSchema() result
4313
+ const afterDot = key.substring(pos + 1);
4314
+ const nextSep = afterDot.search(/[.\[]/);
4315
+ const subPropName =
4316
+ nextSep === -1 ? afterDot : afterDot.substring(0, nextSep);
4317
+ if (schema[subPropName] !== undefined) {
4318
+ delete tempScopeNode.schema[key];
4319
+ break;
4193
4320
  }
4194
4321
  }
4195
4322
  }
@@ -4929,9 +5056,109 @@ export class ScopeDataStructure {
4929
5056
  // Replace cyScope placeholders in all external function call data
4930
5057
  // This ensures call signatures and schema paths use actual callback text
4931
5058
  // instead of internal cyScope names, preventing mock data merge conflicts.
4932
- return this.externalFunctionCalls.map((efc) =>
4933
- this.cleanCyScopeFromFunctionCallInfo(efc),
4934
- );
5059
+ const rootScopeName = this.scopeTreeManager.getRootName();
5060
+ const rootSchema = this.scopeNodes[rootScopeName]?.schema ?? {};
5061
+
5062
+ return this.externalFunctionCalls.map((efc) => {
5063
+ const cleaned = this.cleanCyScopeFromFunctionCallInfo(efc);
5064
+ return this.filterConflatedExternalPaths(cleaned, rootSchema);
5065
+ });
5066
+ }
5067
+
5068
+ /**
5069
+ * Filters out conflated paths from external function call schemas.
5070
+ *
5071
+ * When multiple useState(false) calls create equivalency conflation during
5072
+ * Phase 1 analysis, standalone boolean state variables (like showWorkoutForm,
5073
+ * showGoalForm) can bleed into external function call schemas as sub-properties
5074
+ * of unrelated data fields (like data[].activity_type.showWorkoutForm).
5075
+ *
5076
+ * Detection: group sub-properties by parent path. If 2+ sub-properties of
5077
+ * the same parent all match standalone root scope variable names, treat them
5078
+ * as conflation artifacts and remove them.
5079
+ */
5080
+ private filterConflatedExternalPaths(
5081
+ efc: FunctionCallInfo,
5082
+ rootSchema: Record<string, string>,
5083
+ ): FunctionCallInfo {
5084
+ // Build a set of top-level root scope variable names (simple names, no dots/brackets)
5085
+ const topLevelRootVars = new Set<string>();
5086
+ for (const key of Object.keys(rootSchema)) {
5087
+ if (!key.includes('.') && !key.includes('[')) {
5088
+ topLevelRootVars.add(key);
5089
+ }
5090
+ }
5091
+
5092
+ if (topLevelRootVars.size === 0) return efc;
5093
+
5094
+ // Group sub-property matches by their parent path.
5095
+ // For a path like "...data[].activity_type.showWorkoutForm",
5096
+ // parent = "...data[].activity_type", child = "showWorkoutForm"
5097
+ const parentToConflatedKeys = new Map<string, string[]>();
5098
+
5099
+ for (const key of Object.keys(efc.schema)) {
5100
+ const lastDot = key.lastIndexOf('.');
5101
+ if (lastDot === -1) continue;
5102
+
5103
+ const parent = key.substring(0, lastDot);
5104
+ const child = key.substring(lastDot + 1);
5105
+
5106
+ // Skip array access or function call patterns
5107
+ if (child.includes('[') || child.includes('(')) continue;
5108
+
5109
+ // Only consider paths inside array element chains (contains []).
5110
+ // Direct children of functionCallReturnValue are legitimate destructured
5111
+ // return values, not conflation. Conflation happens deeper in the chain
5112
+ // when array element fields get corrupted sub-properties.
5113
+ if (!parent.includes('[')) continue;
5114
+
5115
+ if (topLevelRootVars.has(child)) {
5116
+ if (!parentToConflatedKeys.has(parent)) {
5117
+ parentToConflatedKeys.set(parent, []);
5118
+ }
5119
+ parentToConflatedKeys.get(parent)!.push(key);
5120
+ }
5121
+ }
5122
+
5123
+ // Only filter when 2+ sub-properties of the same parent match root scope vars.
5124
+ // This threshold avoids false positives from coincidental name matches.
5125
+ const keysToRemove = new Set<string>();
5126
+ const parentsToRestore = new Set<string>();
5127
+
5128
+ for (const [parent, conflatedKeys] of parentToConflatedKeys) {
5129
+ if (conflatedKeys.length >= 2) {
5130
+ for (const key of conflatedKeys) {
5131
+ keysToRemove.add(key);
5132
+ }
5133
+ parentsToRestore.add(parent);
5134
+ }
5135
+ }
5136
+
5137
+ if (keysToRemove.size === 0) return efc;
5138
+
5139
+ // Create a new schema without the conflated paths
5140
+ const newSchema: Record<string, string> = {};
5141
+ for (const [key, value] of Object.entries(efc.schema)) {
5142
+ if (keysToRemove.has(key)) continue;
5143
+
5144
+ // Restore parent type: if it was changed to "object" because of conflated
5145
+ // sub-properties, and now all those sub-properties are removed, change it
5146
+ // back to "unknown" (we don't know the original type)
5147
+ if (parentsToRestore.has(key) && value === 'object') {
5148
+ // Check if there are any remaining sub-properties
5149
+ const hasRemainingSubProps = Object.keys(efc.schema).some(
5150
+ (k) =>
5151
+ !keysToRemove.has(k) &&
5152
+ k !== key &&
5153
+ (k.startsWith(key + '.') || k.startsWith(key + '[')),
5154
+ );
5155
+ newSchema[key] = hasRemainingSubProps ? value : 'unknown';
5156
+ } else {
5157
+ newSchema[key] = value;
5158
+ }
5159
+ }
5160
+
5161
+ return { ...efc, schema: newSchema };
4935
5162
  }
4936
5163
 
4937
5164
  /**
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Recursively strips `_nullable` keys from LLM-generated mock data.
3
+ *
4
+ * The `_nullable` marker is an internal CodeYam concept used in type definitions
5
+ * to indicate that a field can be null/undefined. The LLM sometimes includes
6
+ * these markers in its generated scenario data, which causes runtime errors
7
+ * when code iterates over object keys (e.g., `Object.keys(importedBy)` picks
8
+ * up `_nullable` as a key alongside real data).
9
+ *
10
+ * This function mutates the input object in-place, consistent with other
11
+ * post-processing helpers like `convertNullToUndefinedBySchema`.
12
+ */
13
+ export default function stripNullableMarkers(
14
+ data: Record<string, unknown>,
15
+ ): void {
16
+ if (data == null || typeof data !== 'object') return;
17
+
18
+ // Delete _nullable from this level
19
+ if ('_nullable' in data) {
20
+ delete data._nullable;
21
+ }
22
+
23
+ // Recurse into nested objects and arrays
24
+ for (const value of Object.values(data)) {
25
+ if (Array.isArray(value)) {
26
+ for (const item of value) {
27
+ if (item !== null && typeof item === 'object' && !Array.isArray(item)) {
28
+ stripNullableMarkers(item as Record<string, unknown>);
29
+ }
30
+ }
31
+ } else if (value !== null && typeof value === 'object') {
32
+ stripNullableMarkers(value as Record<string, unknown>);
33
+ }
34
+ }
35
+ }
@@ -39,6 +39,7 @@ export function getNodeType(node: ts.Node, sourceFile: ts.SourceFile) {
39
39
  case 'StringLiteral':
40
40
  case 'NumericLiteral':
41
41
  case 'ObjectLiteralExpression':
42
+ case 'ArrayLiteralExpression':
42
43
  nodeType = 'data';
43
44
  break;
44
45
  case 'TypeAliasDeclaration':