@codeyam/codeyam-cli 0.1.20 → 0.1.22

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 (130) 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 +1 -1
  4. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +36 -9
  5. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.ts +10 -3
  6. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +16 -6
  7. package/analyzer-template/packages/analyze/index.ts +4 -1
  8. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +28 -2
  9. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +5 -36
  10. package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +1 -0
  11. package/analyzer-template/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.ts +21 -0
  12. package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +82 -10
  13. package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +4 -0
  14. package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +4 -0
  15. package/analyzer-template/packages/analyze/src/lib/files/analyzeNextRoute.ts +8 -3
  16. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +235 -58
  17. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +170 -26
  18. package/analyzer-template/packages/aws/package.json +1 -1
  19. package/analyzer-template/packages/database/src/lib/loadEntity.ts +11 -4
  20. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.d.ts +4 -1
  21. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.d.ts.map +1 -1
  22. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.js +4 -4
  23. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.js.map +1 -1
  24. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts +3 -1
  25. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
  26. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +22 -1
  27. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  28. package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +27 -0
  29. package/codeyam-cli/src/commands/__tests__/editor.auditNoAutoAnalysis.test.js +63 -0
  30. package/codeyam-cli/src/commands/__tests__/editor.auditNoAutoAnalysis.test.js.map +1 -0
  31. package/codeyam-cli/src/commands/editor.js +553 -93
  32. package/codeyam-cli/src/commands/editor.js.map +1 -1
  33. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +991 -31
  34. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
  35. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js +11 -3
  36. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js.map +1 -1
  37. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +33 -1
  38. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -1
  39. package/codeyam-cli/src/utils/__tests__/manualEntityAnalysis.test.js +302 -0
  40. package/codeyam-cli/src/utils/__tests__/manualEntityAnalysis.test.js.map +1 -0
  41. package/codeyam-cli/src/utils/__tests__/registerScenarioResult.test.js +127 -0
  42. package/codeyam-cli/src/utils/__tests__/registerScenarioResult.test.js.map +1 -0
  43. package/codeyam-cli/src/utils/__tests__/testRunner.test.js +217 -0
  44. package/codeyam-cli/src/utils/__tests__/testRunner.test.js.map +1 -0
  45. package/codeyam-cli/src/utils/analysisRunner.js +28 -1
  46. package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
  47. package/codeyam-cli/src/utils/analyzer.js +11 -1
  48. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  49. package/codeyam-cli/src/utils/editorAudit.js +210 -14
  50. package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
  51. package/codeyam-cli/src/utils/editorPreview.js +5 -3
  52. package/codeyam-cli/src/utils/editorPreview.js.map +1 -1
  53. package/codeyam-cli/src/utils/entityChangeStatus.server.js +16 -0
  54. package/codeyam-cli/src/utils/entityChangeStatus.server.js.map +1 -1
  55. package/codeyam-cli/src/utils/manualEntityAnalysis.js +196 -0
  56. package/codeyam-cli/src/utils/manualEntityAnalysis.js.map +1 -0
  57. package/codeyam-cli/src/utils/queue/job.js +20 -2
  58. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  59. package/codeyam-cli/src/utils/registerScenarioResult.js +52 -0
  60. package/codeyam-cli/src/utils/registerScenarioResult.js.map +1 -0
  61. package/codeyam-cli/src/utils/testRunner.js +199 -1
  62. package/codeyam-cli/src/utils/testRunner.js.map +1 -1
  63. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js +35 -0
  64. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js.map +1 -1
  65. package/codeyam-cli/src/webserver/app/lib/clientErrors.js +3 -0
  66. package/codeyam-cli/src/webserver/app/lib/clientErrors.js.map +1 -1
  67. package/codeyam-cli/src/webserver/build/client/assets/MiniClaudeChat-CQENLSrF.js +36 -0
  68. package/codeyam-cli/src/webserver/build/client/assets/api.editor-save-scenario-data-l0sNRNKZ.js +1 -0
  69. package/codeyam-cli/src/webserver/build/client/assets/api.editor-schema-l0sNRNKZ.js +1 -0
  70. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-Coe5NhbS.js +1 -0
  71. package/codeyam-cli/src/webserver/build/client/assets/{cy-logo-cli-CCKUIm0S.svg → cy-logo-cli-DoA97ML3.svg} +2 -2
  72. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-aIHKLB-m.js +96 -0
  73. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-CluPkvXJ.js +41 -0
  74. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-Blfy9UlN.js → entity._sha._-ByHz6rAQ.js} +13 -12
  75. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.dev-KTQuL0aj.js → entity._sha.scenarios._scenarioId.dev-CmLO432x.js} +1 -1
  76. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-C6eeL24i.js → entity._sha.scenarios._scenarioId.fullscreen-Bz9sCUF_.js} +1 -1
  77. package/codeyam-cli/src/webserver/build/client/assets/globals-oyPmV37k.css +1 -0
  78. package/codeyam-cli/src/webserver/build/client/assets/manifest-bcbb3d49.js +1 -0
  79. package/codeyam-cli/src/webserver/build/client/assets/{root-BxUQigda.js → root-D2_tktnk.js} +26 -13
  80. package/codeyam-cli/src/webserver/build/server/assets/analysisRunner-DjF-soOH.js +16 -0
  81. package/codeyam-cli/src/webserver/build/server/assets/{index-CjLhfz6Z.js → index-nAvHGWbz.js} +1 -1
  82. package/codeyam-cli/src/webserver/build/server/assets/{init-BEqlbI84.js → init-XhpIt-OT.js} +1 -1
  83. package/codeyam-cli/src/webserver/build/server/assets/server-build-DVwiibFu.js +644 -0
  84. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  85. package/codeyam-cli/src/webserver/build-info.json +5 -5
  86. package/codeyam-cli/src/webserver/idleDetector.js +15 -0
  87. package/codeyam-cli/src/webserver/idleDetector.js.map +1 -1
  88. package/codeyam-cli/src/webserver/terminalServer.js +18 -5
  89. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  90. package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +2 -2
  91. package/package.json +1 -1
  92. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +27 -10
  93. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  94. package/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.js +9 -2
  95. package/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.js.map +1 -1
  96. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +14 -4
  97. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  98. package/packages/analyze/index.js +1 -1
  99. package/packages/analyze/index.js.map +1 -1
  100. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +16 -2
  101. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  102. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +6 -26
  103. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  104. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +1 -0
  105. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
  106. package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js +14 -0
  107. package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js.map +1 -1
  108. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +44 -11
  109. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
  110. package/packages/analyze/src/lib/files/analyzeChange.js +1 -0
  111. package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
  112. package/packages/analyze/src/lib/files/analyzeInitial.js +1 -0
  113. package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
  114. package/packages/analyze/src/lib/files/analyzeNextRoute.js +5 -1
  115. package/packages/analyze/src/lib/files/analyzeNextRoute.js.map +1 -1
  116. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +116 -28
  117. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  118. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +139 -24
  119. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  120. package/packages/database/src/lib/loadEntity.js +4 -4
  121. package/packages/database/src/lib/loadEntity.js.map +1 -1
  122. package/packages/utils/src/lib/fs/rsyncCopy.js +22 -1
  123. package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  124. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-DcX-ZS3p.js +0 -1
  125. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DII1pg_z.js +0 -58
  126. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-oepecPae.js +0 -41
  127. package/codeyam-cli/src/webserver/build/client/assets/globals-Yn9W3zp3.css +0 -1
  128. package/codeyam-cli/src/webserver/build/client/assets/manifest-cdf2c0a7.js +0 -1
  129. package/codeyam-cli/src/webserver/build/server/assets/analysisRunner-B_PsTAb1.js +0 -13
  130. package/codeyam-cli/src/webserver/build/server/assets/server-build-YI63xTu4.js +0 -553
@@ -11,8 +11,10 @@ import {
11
11
  clearAttributesFromMapping,
12
12
  mergeJsonTypeDefinitions,
13
13
  } from '~codeyam/ai';
14
- import mergeInDependentDataStructure from './mergeInDependentDataStructure';
15
- import { awsLog } from '~codeyam/utils';
14
+ import mergeInDependentDataStructure, {
15
+ DataStructureTimeoutError,
16
+ } from './mergeInDependentDataStructure';
17
+ import { awsLog, awsLogDebugLevel } from '~codeyam/utils';
16
18
  import gatherDataForMocks from './gatherDataForMocks';
17
19
  import enrichArrayTypesFromChildSignatures from './enrichArrayTypesFromChildSignatures';
18
20
  import enrichUnknownTypesFromSourceEquivalencies from './enrichUnknownTypesFromSourceEquivalencies';
@@ -328,12 +330,23 @@ export default function generateDataStructure({
328
330
 
329
331
  // Recursive function to traverse the dependency tree
330
332
  const processedAnalyses = new Set<string>();
333
+ const traverseStart = Date.now();
334
+ const TRAVERSE_TIMEOUT_MS = 2_000;
335
+ let traverseCount = 0;
331
336
  const traverseDependencyTree = (analyses: ReadonlyAnalysisMap) => {
332
337
  for (const filePath in analyses) {
333
338
  for (const name in analyses[filePath]) {
334
339
  const analysisKey = `${filePath}:${name}`;
335
340
  if (processedAnalyses.has(analysisKey)) continue;
336
341
  processedAnalyses.add(analysisKey);
342
+ traverseCount++;
343
+
344
+ if (Date.now() - traverseStart > TRAVERSE_TIMEOUT_MS) {
345
+ throw new DataStructureTimeoutError(
346
+ entity.name,
347
+ Date.now() - traverseStart,
348
+ );
349
+ }
337
350
 
338
351
  const childAnalysis = analyses[filePath][name];
339
352
  const childEntity = childAnalysis?.entity;
@@ -443,6 +456,25 @@ export default function generateDataStructure({
443
456
  // Start traversal from direct non-mocked children
444
457
  traverseDependencyTree(nonMockedDependentAnalyses);
445
458
 
459
+ const traverseElapsed = Date.now() - traverseStart;
460
+ const childSchemaKeyCount = Object.values(childDependencySchemas).reduce(
461
+ (sum, fileMap) =>
462
+ sum +
463
+ Object.values(fileMap).reduce(
464
+ (s, schema) =>
465
+ s +
466
+ Object.keys(schema.signatureSchema || {}).length +
467
+ Object.keys(schema.returnValueSchema || {}).length,
468
+ 0,
469
+ ),
470
+ 0,
471
+ );
472
+ awsLogDebugLevel(
473
+ 1,
474
+ `Dependency tree traversal for ${entity.name}: ${traverseCount} analyses, ` +
475
+ `${childSchemaKeyCount} child schema keys, ${allImportedExports.length} imports, ${traverseElapsed}ms`,
476
+ );
477
+
446
478
  // console.info(
447
479
  // 'CODEYAM DEBUG: start merge',
448
480
  // JSON.stringify(
@@ -484,6 +516,14 @@ export default function generateDataStructure({
484
516
  dependencySchemas: isolatedDataStructure.dependencySchemas,
485
517
  });
486
518
 
519
+ const mergeStart = Date.now();
520
+ // Shared deadline for all phases from merge onward
521
+ const genDeadline = mergeStart + 5_000; // 5s total budget for all phases
522
+ awsLogDebugLevel(
523
+ 1,
524
+ `Starting mergeInDependentDataStructure for ${entity.name}...`,
525
+ );
526
+
487
527
  const mergedDataStructure = mergeInDependentDataStructure({
488
528
  importedExports: allImportedExports,
489
529
  dependentAnalyses: nonMockedDependentAnalyses,
@@ -498,6 +538,13 @@ export default function generateDataStructure({
498
538
  dependencySchemas: isolatedDataStructure?.dependencySchemas || {},
499
539
  });
500
540
 
541
+ awsLogDebugLevel(
542
+ 1,
543
+ `mergeInDependentDataStructure complete for ${entity.name}: ` +
544
+ `${Object.keys(mergedDataStructure.signatureSchema).length} sig, ` +
545
+ `${Object.keys(mergedDataStructure.returnValueSchema).length} ret, ${Date.now() - mergeStart}ms`,
546
+ );
547
+
501
548
  mergedDataStructure.environmentVariables =
502
549
  isolatedDataStructure.environmentVariables || [];
503
550
 
@@ -511,6 +558,7 @@ export default function generateDataStructure({
511
558
  // Merge collected child dependency schemas into mergedDataStructure.
512
559
  // This ensures that when gatherDataForMocks looks up schemas for child imports,
513
560
  // the child's schemas are available.
561
+ const childMergeStart = Date.now();
514
562
  for (const schemaFilePath in childDependencySchemas) {
515
563
  for (const schemaName in childDependencySchemas[schemaFilePath]) {
516
564
  mergedDataStructure.dependencySchemas[schemaFilePath] ||= {};
@@ -561,7 +609,13 @@ export default function generateDataStructure({
561
609
  }
562
610
  }
563
611
 
612
+ awsLogDebugLevel(
613
+ 1,
614
+ `Child schema merge for ${entity.name}: ${Date.now() - childMergeStart}ms`,
615
+ );
616
+
564
617
  // Transformation tracing: capture after child schemas merged
618
+ const snapshotStart = Date.now();
565
619
  transformationTracer.snapshot(entity.name, 'childSchemasMerged', {
566
620
  signatureSchema: mergedDataStructure.signatureSchema,
567
621
  returnValueSchema: mergedDataStructure.returnValueSchema,
@@ -588,71 +642,134 @@ export default function generateDataStructure({
588
642
  // ),
589
643
  // );
590
644
 
645
+ awsLogDebugLevel(
646
+ 1,
647
+ `Transformation snapshot for ${entity.name}: ${Date.now() - snapshotStart}ms`,
648
+ );
649
+
591
650
  // Deduplicate function schemas in the merged data structure
592
651
  // The merge process might introduce duplicates even if individual schemas were clean
593
- // Trace deduplication of signatureSchema
594
- const sigBefore = { ...mergedDataStructure.signatureSchema };
595
- mergedDataStructure.signatureSchema = deduplicateFunctionSchemas(
596
- mergedDataStructure.signatureSchema,
597
- );
598
- transformationTracer.traceSchemaTransformResult(
599
- entity.name,
600
- 'deduplicateFunctionSchemas',
601
- sigBefore,
602
- mergedDataStructure.signatureSchema,
603
- { schemaType: 'signature' },
604
- );
652
+ const dedupStart = Date.now();
605
653
 
606
- // Trace deduplication of returnValueSchema
607
- const rvBefore = { ...mergedDataStructure.returnValueSchema };
608
- mergedDataStructure.returnValueSchema = deduplicateFunctionSchemas(
654
+ const sigKeyCount = Object.keys(mergedDataStructure.signatureSchema).length;
655
+ const retKeyCount = Object.keys(
609
656
  mergedDataStructure.returnValueSchema,
610
- );
611
- transformationTracer.traceSchemaTransformResult(
612
- entity.name,
613
- 'deduplicateFunctionSchemas',
614
- rvBefore,
615
- mergedDataStructure.returnValueSchema,
616
- { schemaType: 'returnValue' },
657
+ ).length;
658
+
659
+ // Skip dedup on very large schemas — the O(keys × variants × keyLength) cost
660
+ // is not worth it for schemas with 10K+ keys where function dedup rarely matters.
661
+ const DEDUP_KEY_THRESHOLD = 10_000;
662
+
663
+ if (sigKeyCount < DEDUP_KEY_THRESHOLD) {
664
+ const sigBefore = { ...mergedDataStructure.signatureSchema };
665
+ mergedDataStructure.signatureSchema = deduplicateFunctionSchemas(
666
+ mergedDataStructure.signatureSchema,
667
+ );
668
+ transformationTracer.traceSchemaTransformResult(
669
+ entity.name,
670
+ 'deduplicateFunctionSchemas',
671
+ sigBefore,
672
+ mergedDataStructure.signatureSchema,
673
+ { schemaType: 'signature' },
674
+ );
675
+ } else {
676
+ awsLogDebugLevel(
677
+ 2,
678
+ `${entity.name}: skipping sig dedup (${sigKeyCount} keys > ${DEDUP_KEY_THRESHOLD})`,
679
+ );
680
+ }
681
+
682
+ if (retKeyCount < DEDUP_KEY_THRESHOLD) {
683
+ const rvBefore = { ...mergedDataStructure.returnValueSchema };
684
+ mergedDataStructure.returnValueSchema = deduplicateFunctionSchemas(
685
+ mergedDataStructure.returnValueSchema,
686
+ );
687
+ transformationTracer.traceSchemaTransformResult(
688
+ entity.name,
689
+ 'deduplicateFunctionSchemas',
690
+ rvBefore,
691
+ mergedDataStructure.returnValueSchema,
692
+ { schemaType: 'returnValue' },
693
+ );
694
+ } else {
695
+ awsLogDebugLevel(
696
+ 2,
697
+ `${entity.name}: skipping ret dedup (${retKeyCount} keys > ${DEDUP_KEY_THRESHOLD})`,
698
+ );
699
+ }
700
+
701
+ awsLogDebugLevel(
702
+ 1,
703
+ `${entity.name}: root schema dedup ${Date.now() - dedupStart}ms (sig=${sigKeyCount}, ret=${retKeyCount})`,
617
704
  );
618
705
 
619
706
  // Also deduplicate dependency schemas and clear known attributes
707
+ let depProcessed = 0;
708
+ const depStart = Date.now();
620
709
  for (const filePath in mergedDataStructure.dependencySchemas) {
621
710
  for (const depEntityName in mergedDataStructure.dependencySchemas[
622
711
  filePath
623
712
  ]) {
713
+ if (Date.now() > genDeadline) {
714
+ throw new DataStructureTimeoutError(
715
+ entity.name,
716
+ Date.now() - mergeStart,
717
+ );
718
+ }
719
+
624
720
  const depSchema =
625
721
  mergedDataStructure.dependencySchemas[filePath][depEntityName];
722
+ const depSigKeys = Object.keys(depSchema.signatureSchema || {}).length;
723
+ const depRetKeys = Object.keys(
724
+ depSchema.returnValueSchema || {},
725
+ ).length;
626
726
 
627
- // Trace deduplication of dependency signatureSchema
628
- const depSigBefore = { ...depSchema.signatureSchema };
629
- depSchema.signatureSchema = deduplicateFunctionSchemas(
630
- depSchema.signatureSchema,
631
- );
632
- transformationTracer.traceSchemaTransformResult(
633
- entity.name,
634
- 'deduplicateFunctionSchemas',
635
- depSigBefore,
636
- depSchema.signatureSchema,
637
- { filePath, dependencyName: depEntityName, schemaType: 'signature' },
638
- );
727
+ const depOpStart = Date.now();
639
728
 
640
- // Trace deduplication of dependency returnValueSchema
641
- const depRvBefore = { ...depSchema.returnValueSchema };
642
- depSchema.returnValueSchema = deduplicateFunctionSchemas(
643
- depSchema.returnValueSchema,
644
- );
645
- transformationTracer.traceSchemaTransformResult(
646
- entity.name,
647
- 'deduplicateFunctionSchemas',
648
- depRvBefore,
649
- depSchema.returnValueSchema,
650
- {
651
- filePath,
652
- dependencyName: depEntityName,
653
- schemaType: 'returnValue',
654
- },
655
- );
729
+ if (depSigKeys < DEDUP_KEY_THRESHOLD) {
730
+ const depSigBefore = { ...depSchema.signatureSchema };
731
+ depSchema.signatureSchema = deduplicateFunctionSchemas(
732
+ depSchema.signatureSchema,
733
+ );
734
+ transformationTracer.traceSchemaTransformResult(
735
+ entity.name,
736
+ 'deduplicateFunctionSchemas',
737
+ depSigBefore,
738
+ depSchema.signatureSchema,
739
+ {
740
+ filePath,
741
+ dependencyName: depEntityName,
742
+ schemaType: 'signature',
743
+ },
744
+ );
745
+ }
746
+
747
+ if (depRetKeys < DEDUP_KEY_THRESHOLD) {
748
+ const depRvBefore = { ...depSchema.returnValueSchema };
749
+ depSchema.returnValueSchema = deduplicateFunctionSchemas(
750
+ depSchema.returnValueSchema,
751
+ );
752
+ transformationTracer.traceSchemaTransformResult(
753
+ entity.name,
754
+ 'deduplicateFunctionSchemas',
755
+ depRvBefore,
756
+ depSchema.returnValueSchema,
757
+ {
758
+ filePath,
759
+ dependencyName: depEntityName,
760
+ schemaType: 'returnValue',
761
+ },
762
+ );
763
+ }
764
+
765
+ const depOpElapsed = Date.now() - depOpStart;
766
+ if (depOpElapsed > 1000) {
767
+ awsLogDebugLevel(
768
+ 2,
769
+ `${entity.name}: slow dep dedup ${depEntityName} sig=${depSigKeys} ret=${depRetKeys} ${depOpElapsed}ms`,
770
+ );
771
+ }
772
+ depProcessed++;
656
773
 
657
774
  // Infer function types from child component usage BEFORE fillInSchemaGapsAndUnknowns.
658
775
  // When a hook returns a property with type 'unknown' that is passed to a child
@@ -729,13 +846,33 @@ export default function generateDataStructure({
729
846
  // Fill in type gaps BEFORE clearing attributes, so evidence like .includes()
730
847
  // is used for type inference before being deleted
731
848
 
732
- depSchema.signatureSchema = fillInDirectSchemaGapsAndUnknowns({
733
- schema: depSchema.signatureSchema,
734
- });
849
+ const FILL_IN_KEY_THRESHOLD = 5_000;
850
+ const fillStart = Date.now();
735
851
 
736
- depSchema.returnValueSchema = fillInDirectSchemaGapsAndUnknowns({
737
- schema: depSchema.returnValueSchema,
738
- });
852
+ if (depSigKeys < FILL_IN_KEY_THRESHOLD) {
853
+ depSchema.signatureSchema = fillInDirectSchemaGapsAndUnknowns({
854
+ schema: depSchema.signatureSchema,
855
+ });
856
+ }
857
+
858
+ if (depRetKeys < FILL_IN_KEY_THRESHOLD) {
859
+ depSchema.returnValueSchema = fillInDirectSchemaGapsAndUnknowns({
860
+ schema: depSchema.returnValueSchema,
861
+ });
862
+ } else {
863
+ awsLogDebugLevel(
864
+ 2,
865
+ `${entity.name}: skipping fillInGaps for ${depEntityName} ret (${depRetKeys} keys > ${FILL_IN_KEY_THRESHOLD})`,
866
+ );
867
+ }
868
+
869
+ const fillElapsed = Date.now() - fillStart;
870
+ if (fillElapsed > 1000) {
871
+ awsLogDebugLevel(
872
+ 2,
873
+ `${entity.name}: slow fillInGaps ${depEntityName} sig=${depSigKeys} ret=${depRetKeys} ${fillElapsed}ms`,
874
+ );
875
+ }
739
876
 
740
877
  // Trace clearAttributesFromMapping on dependency schemas
741
878
  transformationTracer.traceSchemaTransform(
@@ -760,16 +897,44 @@ export default function generateDataStructure({
760
897
  }
761
898
  }
762
899
 
900
+ awsLogDebugLevel(
901
+ 1,
902
+ `${entity.name}: dep schema processing: ${depProcessed} deps in ${Date.now() - depStart}ms`,
903
+ );
904
+ awsLogDebugLevel(
905
+ 1,
906
+ `Dedup + dep schema processing for ${entity.name}: ${Date.now() - dedupStart}ms`,
907
+ );
908
+
763
909
  // Transformation tracing: capture after deduplication
910
+ const dedupSnapshotStart = Date.now();
764
911
  transformationTracer.snapshot(entity.name, 'deduplicated', {
765
912
  signatureSchema: mergedDataStructure.signatureSchema,
766
913
  returnValueSchema: mergedDataStructure.returnValueSchema,
767
914
  dependencySchemas: mergedDataStructure.dependencySchemas,
768
915
  });
769
916
 
917
+ awsLogDebugLevel(
918
+ 1,
919
+ `Dedup snapshot for ${entity.name}: ${Date.now() - dedupSnapshotStart}ms`,
920
+ );
921
+
770
922
  analysis.metadata ||= {};
771
923
  analysis.metadata.mergedDataStructure = mergedDataStructure;
772
924
 
925
+ const checkGenDeadline = (phase: string) => {
926
+ if (Date.now() > genDeadline) {
927
+ throw new DataStructureTimeoutError(
928
+ entity.name,
929
+ Date.now() - mergeStart,
930
+ );
931
+ }
932
+ awsLogDebugLevel(
933
+ 1,
934
+ `${entity.name}: ${phase} complete (${Date.now() - mergeStart}ms total)`,
935
+ );
936
+ };
937
+
773
938
  // Enrich mocked dependency array types with fields from child component signatures
774
939
  // This ensures that when getSurveysAction returns { data: array }, and SurveyCard
775
940
  // expects survey.updatedAt, the array element type includes updatedAt.
@@ -787,6 +952,8 @@ export default function generateDataStructure({
787
952
  ),
788
953
  );
789
954
 
955
+ checkGenDeadline('enrichArrayTypes');
956
+
790
957
  // Transformation tracing: capture after array types enriched
791
958
  transformationTracer.snapshot(entity.name, 'arrayTypesEnriched', {
792
959
  signatureSchema: mergedDataStructure.signatureSchema,
@@ -811,6 +978,8 @@ export default function generateDataStructure({
811
978
  ),
812
979
  );
813
980
 
981
+ checkGenDeadline('enrichUnknownTypes');
982
+
814
983
  // Transformation tracing: capture after unknown types enriched
815
984
  transformationTracer.snapshot(entity.name, 'unknownTypesEnriched', {
816
985
  signatureSchema: mergedDataStructure.signatureSchema,
@@ -831,6 +1000,8 @@ export default function generateDataStructure({
831
1000
  { entityName: entity.name },
832
1001
  );
833
1002
 
1003
+ checkGenDeadline('gatherDataForMocks');
1004
+
834
1005
  // Transformation tracing: capture after dataForMocks gathered
835
1006
  transformationTracer.snapshot(entity.name, 'dataForMocksGathered', {
836
1007
  signatureSchema: mergedDataStructure.signatureSchema,
@@ -860,6 +1031,8 @@ export default function generateDataStructure({
860
1031
  }
861
1032
  }
862
1033
 
1034
+ checkGenDeadline('mergeChildDataForMocks');
1035
+
863
1036
  const finalizedArgumentsSchema = { ...mergedDataStructure.signatureSchema };
864
1037
 
865
1038
  // Trace fillInDirectSchemaGapsAndUnknowns
@@ -880,9 +1053,13 @@ export default function generateDataStructure({
880
1053
  { stage: 'finalization' },
881
1054
  );
882
1055
 
1056
+ checkGenDeadline('fillInGaps+clearAttributes');
1057
+
883
1058
  const argumentsSchema = convertDotNotation(finalizedArgumentsSchema)
884
1059
  .signature as JsonTypeDefinition[];
885
1060
 
1061
+ checkGenDeadline('convertDotNotation');
1062
+
886
1063
  analysis.metadata.scenariosDataStructure = {
887
1064
  arguments: argumentsSchema,
888
1065
  dataForMocks,