@codeyam/codeyam-cli 0.1.0-staging.323686 → 0.1.0-staging.4813bf3
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 +7 -7
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +5 -5
- package/analyzer-template/packages/ai/index.ts +7 -1
- package/analyzer-template/packages/ai/package.json +2 -2
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +62 -18
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +67 -9
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +409 -50
- package/analyzer-template/packages/ai/src/lib/astScopes/sharedPatterns.ts +28 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +21 -6
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +992 -249
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +5 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +16 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +6 -4
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +31 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +37 -15
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.ts +70 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +126 -11
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.ts +179 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.ts +40 -30
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +367 -96
- package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +33 -15
- package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +58 -3
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +315 -6
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +9 -5
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +49 -5
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +649 -142
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +51 -3
- package/analyzer-template/packages/ai/src/lib/mergeJsonTypeDefinitions.ts +5 -0
- package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +90 -96
- package/analyzer-template/packages/ai/src/lib/promptGenerators/collapseNullableObjects.ts +118 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +10 -7
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +24 -4
- package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +25 -13
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +4 -3
- package/analyzer-template/packages/analyze/index.ts +2 -0
- package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +65 -59
- package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +113 -26
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.ts +19 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.ts +19 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExports.ts +11 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.ts +8 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.ts +49 -1
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +89 -9
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +19 -4
- package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +4 -2
- package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +0 -3
- package/analyzer-template/packages/analyze/src/lib/files/analyzeRemixRoute.ts +4 -5
- package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +14 -12
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +61 -13
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +37 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +229 -19
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +117 -9
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +459 -39
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/propagateArrayItemSchemas.ts +474 -0
- package/analyzer-template/packages/analyze/src/lib/files/setImportedExports.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
- package/analyzer-template/packages/analyze/src/lib/utils/getFileByPath.ts +19 -0
- package/analyzer-template/packages/aws/package.json +1 -1
- package/analyzer-template/packages/database/package.json +1 -1
- package/analyzer-template/packages/database/src/lib/analysisBranchToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/analysisToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/branchToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/commitBranchToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/commitToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/fileToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/kysely/db.ts +6 -0
- package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +1 -1
- package/analyzer-template/packages/database/src/lib/kysely/tables/labsRequestsTable.ts +52 -0
- package/analyzer-template/packages/database/src/lib/projectToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/saveFiles.ts +1 -1
- package/analyzer-template/packages/database/src/lib/scenarioToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/userScenarioToDb.ts +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +3 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts +23 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
- package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +7 -0
- package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/package.json +1 -1
- package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +7 -0
- package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +6 -5
- package/analyzer-template/packages/types/src/types/ScopeAnalysis.ts +6 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +7 -0
- package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
- package/analyzer-template/project/constructMockCode.ts +90 -10
- package/analyzer-template/project/writeMockDataTsx.ts +181 -8
- package/analyzer-template/project/writeScenarioComponents.ts +60 -12
- package/analyzer-template/project/writeSimpleRoot.ts +21 -11
- package/background/src/lib/local/createLocalAnalyzer.js +1 -1
- package/background/src/lib/local/createLocalAnalyzer.js.map +1 -1
- package/background/src/lib/virtualized/project/constructMockCode.js +75 -4
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +162 -4
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +60 -15
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeSimpleRoot.js +21 -11
- package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
- package/codeyam-cli/scripts/apply-setup.js +180 -0
- package/codeyam-cli/scripts/apply-setup.js.map +1 -1
- package/codeyam-cli/src/cli.js +2 -0
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/codeyam-cli.js +18 -2
- package/codeyam-cli/src/codeyam-cli.js.map +1 -1
- package/codeyam-cli/src/commands/analyze.js +4 -2
- package/codeyam-cli/src/commands/analyze.js.map +1 -1
- package/codeyam-cli/src/commands/baseline.js +2 -0
- package/codeyam-cli/src/commands/baseline.js.map +1 -1
- package/codeyam-cli/src/commands/debug.js +9 -5
- package/codeyam-cli/src/commands/debug.js.map +1 -1
- package/codeyam-cli/src/commands/default.js +31 -20
- package/codeyam-cli/src/commands/default.js.map +1 -1
- package/codeyam-cli/src/commands/detect-universal-mocks.js +2 -0
- package/codeyam-cli/src/commands/detect-universal-mocks.js.map +1 -1
- package/codeyam-cli/src/commands/init.js +49 -257
- package/codeyam-cli/src/commands/init.js.map +1 -1
- package/codeyam-cli/src/commands/memory.js +17 -26
- package/codeyam-cli/src/commands/memory.js.map +1 -1
- package/codeyam-cli/src/commands/recapture.js +2 -0
- package/codeyam-cli/src/commands/recapture.js.map +1 -1
- package/codeyam-cli/src/commands/setup-sandbox.js +2 -0
- package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -1
- package/codeyam-cli/src/commands/setup-simulations.js +284 -0
- package/codeyam-cli/src/commands/setup-simulations.js.map +1 -0
- package/codeyam-cli/src/commands/test-startup.js +2 -0
- package/codeyam-cli/src/commands/test-startup.js.map +1 -1
- package/codeyam-cli/src/commands/verify.js +14 -2
- package/codeyam-cli/src/commands/verify.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +128 -86
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
- package/codeyam-cli/src/utils/analyzer.js +7 -0
- package/codeyam-cli/src/utils/analyzer.js.map +1 -1
- package/codeyam-cli/src/utils/backgroundServer.js +5 -0
- package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/utils/generateReport.js +2 -2
- package/codeyam-cli/src/utils/install-skills.js +70 -45
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/labsAutoCheck.js +19 -0
- package/codeyam-cli/src/utils/labsAutoCheck.js.map +1 -0
- package/codeyam-cli/src/utils/progress.js +7 -0
- package/codeyam-cli/src/utils/progress.js.map +1 -1
- package/codeyam-cli/src/utils/queue/job.js +4 -0
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/requireSimulations.js +10 -0
- package/codeyam-cli/src/utils/requireSimulations.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +230 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +378 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +115 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
- package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +116 -0
- package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
- package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +44 -0
- package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
- package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
- package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
- package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
- package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
- package/codeyam-cli/src/utils/rules/index.js +1 -0
- package/codeyam-cli/src/utils/rules/index.js.map +1 -1
- package/codeyam-cli/src/utils/rules/parser.js +2 -25
- package/codeyam-cli/src/utils/rules/parser.js.map +1 -1
- package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
- package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
- package/codeyam-cli/src/utils/rules/staleness.js +16 -11
- package/codeyam-cli/src/utils/rules/staleness.js.map +1 -1
- package/codeyam-cli/src/utils/serverState.js +37 -10
- package/codeyam-cli/src/utils/serverState.js.map +1 -1
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +21 -44
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js +15 -3
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/backgroundServer.js +24 -0
- package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/CopyButton-CA3JxPb7.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-DsN1wKrm.js → EntityItem-B86KKU7e.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DLqD3qNt.js → EntityTypeBadge-B5ctlSYt.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-Ba2JVPzP.js → EntityTypeIcon-BqY8gDAW.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-C8lyxW9k.js → InlineSpinner-ClaLpuOo.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-aht4aafF.js → InteractivePreview-BDhPilK7.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CVtiBnY5.js → LibraryFunctionPreview-VeqEBv9v.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-B0GLXMsr.js → LoadingDots-Bs7Nn1Jr.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-xgeCVgSM.js → LogViewer-Bm3PmcCz.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-OApQuNyq.js → ReportIssueModal-CgMEzchJ.js} +3 -8
- package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DuDvi0jm.js → SafeScreenshot-Gq3Ocjo6.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DzccYyI8.js → ScenarioViewer-CBui0id_.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-DyFZkK0l.js → TruncatedFilePath-CiwXDxLh.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{_index-BwqWJOgH.js → _index-B3TDXxnk.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BwavGCpm.js → activity.(_tab)-BtBFH820.js} +6 -11
- package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-CN61MOMa.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.agent-transcripts-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.labs-unlock-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/book-open-PttOB2SF.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-Cx24_aWc.js → chevron-down-TJp6ofnp.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{chunk-EPOLDU6W-CXRTFQ3F.js → chunk-JZWAC4HX-JE9ZIoBl.js} +12 -12
- package/codeyam-cli/src/webserver/build/client/assets/{circle-check-BOARzkeR.js → circle-check-CXhHQYrI.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/copy-6y9ALfGT.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-BdhJEx6B.js → createLucideIcon-Ca9fAY46.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-BBnGWYga.js → dev.empty-C0epRiVn.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BJUiQqZF.js → entity._sha._-BVnB8a9L.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-DavjRmOY.js → entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-D1T4TGjf.js → entity._sha_.create-scenario-DGgZjdFg.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CTBG2mmz.js → entity._sha_.edit._scenarioId-38yPijoD.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CS2cb_eZ.js → entry.client-BSHEfydn.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DMJ7zii9.js → fileTableUtils-DCPhhSMo.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{files-CJ6lTdTA.js → files-0N0YJQv7.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{git-CPTZZ-JZ.js → git-DXnyr8uP.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-CKT08Djd.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-lzqtyFU8.js → index-CcsFv748.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-B1h680n5.js → index-ChN9-fAY.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/labs-BLJ7HxOC.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-B7B9V-bu.js → loader-circle-CTqLEAGU.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-b171b9d3.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/memory-CCQd4aZA.js +78 -0
- package/codeyam-cli/src/webserver/build/client/assets/pause-D6vreykR.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-CHhiHoo_.js +62 -0
- package/codeyam-cli/src/webserver/build/client/assets/{search-CxXUmBSd.js → search-B8VUL8nl.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-BejnUJ6R.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{simulations-DwFIBT09.js → simulations-CPoAg7Zo.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/terminal-BrCP7uQo.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-B6LgvRJg.js → triangle-alert-BZz2NjYa.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-C1v1PQzo.js → useCustomSizes-DNwUduNu.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-aSv48UbS.js → useLastLogLine-COky1GVF.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-DYxHZQuP.js → useReportContext-CpZgwliL.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-mBRpZPiu.js → useToast-Bv9JFvUO.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{index-DVzYx8PN.js → index-8Fv-lH1-.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-Akn3iYFP.js +257 -0
- 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/{codeyam:debug.md → codeyam-debug.md} +1 -1
- package/codeyam-cli/templates/codeyam-diagnose.md +481 -0
- package/codeyam-cli/templates/codeyam-memory-hook.sh +19 -20
- package/codeyam-cli/templates/codeyam-memory.md +392 -0
- package/codeyam-cli/templates/codeyam-new-rule.md +13 -0
- package/codeyam-cli/templates/{codeyam:setup.md → codeyam-setup.md} +13 -1
- package/codeyam-cli/templates/{codeyam:sim.md → codeyam-sim.md} +1 -1
- package/codeyam-cli/templates/{codeyam:test.md → codeyam-test.md} +1 -1
- package/codeyam-cli/templates/{codeyam:verify.md → codeyam-verify.md} +1 -1
- package/codeyam-cli/templates/rule-notification-hook.py +56 -0
- package/codeyam-cli/templates/rule-reflection-hook.py +627 -0
- package/codeyam-cli/templates/rules-instructions.md +132 -0
- package/package.json +2 -2
- package/packages/ai/index.js +3 -2
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/analyzeScope.js +50 -13
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +54 -8
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
- package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +317 -44
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/astScopes/sharedPatterns.js +25 -0
- package/packages/ai/src/lib/astScopes/sharedPatterns.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +763 -171
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +5 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +13 -3
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +6 -4
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +33 -3
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +36 -11
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
- package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +113 -11
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js +173 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js +37 -20
- package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +309 -84
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/dataStructureChunking.js +26 -11
- package/packages/ai/src/lib/dataStructureChunking.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDataStructure.js +46 -2
- package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +227 -4
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +7 -1
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateExecutionFlows.js +26 -4
- package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +447 -80
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -1
- package/packages/ai/src/lib/isolateScopes.js +39 -3
- package/packages/ai/src/lib/isolateScopes.js.map +1 -1
- package/packages/ai/src/lib/mergeJsonTypeDefinitions.js +5 -0
- package/packages/ai/src/lib/mergeJsonTypeDefinitions.js.map +1 -1
- package/packages/ai/src/lib/mergeStatements.js +70 -51
- package/packages/ai/src/lib/mergeStatements.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js +97 -0
- package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js.map +1 -0
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +10 -4
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +17 -2
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/resolvePathToControllable.js +24 -14
- package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -1
- package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
- package/packages/analyze/index.js +1 -0
- package/packages/analyze/index.js.map +1 -1
- package/packages/analyze/src/lib/FileAnalyzer.js +60 -36
- package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/ProjectAnalyzer.js +96 -26
- package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js +14 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js +14 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js +6 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js +6 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js +39 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js +2 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +65 -7
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +17 -4
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +2 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +0 -3
- package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeRemixRoute.js +3 -2
- package/packages/analyze/src/lib/files/analyzeRemixRoute.js.map +1 -1
- package/packages/analyze/src/lib/files/getImportedExports.js +11 -7
- package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
- package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +56 -10
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +33 -8
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +150 -17
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +56 -8
- package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +399 -31
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/setImportedExports.js +2 -1
- package/packages/analyze/src/lib/files/setImportedExports.js.map +1 -1
- package/packages/analyze/src/lib/index.js +1 -0
- package/packages/analyze/src/lib/index.js.map +1 -1
- package/packages/analyze/src/lib/utils/getFileByPath.js +12 -0
- package/packages/analyze/src/lib/utils/getFileByPath.js.map +1 -0
- package/packages/database/src/lib/analysisBranchToDb.js +1 -1
- package/packages/database/src/lib/analysisBranchToDb.js.map +1 -1
- package/packages/database/src/lib/analysisToDb.js +1 -1
- package/packages/database/src/lib/analysisToDb.js.map +1 -1
- package/packages/database/src/lib/branchToDb.js +1 -1
- package/packages/database/src/lib/branchToDb.js.map +1 -1
- package/packages/database/src/lib/commitBranchToDb.js +1 -1
- package/packages/database/src/lib/commitBranchToDb.js.map +1 -1
- package/packages/database/src/lib/commitToDb.js +1 -1
- package/packages/database/src/lib/commitToDb.js.map +1 -1
- package/packages/database/src/lib/fileToDb.js +1 -1
- package/packages/database/src/lib/fileToDb.js.map +1 -1
- package/packages/database/src/lib/kysely/db.js +3 -0
- package/packages/database/src/lib/kysely/db.js.map +1 -1
- package/packages/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
- package/packages/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
- package/packages/database/src/lib/projectToDb.js +1 -1
- package/packages/database/src/lib/projectToDb.js.map +1 -1
- package/packages/database/src/lib/saveFiles.js +1 -1
- package/packages/database/src/lib/saveFiles.js.map +1 -1
- package/packages/database/src/lib/scenarioToDb.js +1 -1
- package/packages/database/src/lib/scenarioToDb.js.map +1 -1
- package/scripts/finalize-analyzer.cjs +8 -76
- package/codeyam-cli/src/webserver/build/client/assets/copy-Bb-80kDT.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/file-code-Dhef1kWN.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/globals-D3yhhV8x.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-7522edd4.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/memory-yxFcrxBX.js +0 -92
- package/codeyam-cli/src/webserver/build/client/assets/root-eVAaavTS.js +0 -62
- package/codeyam-cli/src/webserver/build/client/assets/settings-CS5f3WzT.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-4Cr0uToj.js +0 -257
- package/codeyam-cli/templates/codeyam:diagnose.md +0 -803
- package/codeyam-cli/templates/codeyam:memory.md +0 -462
- package/codeyam-cli/templates/codeyam:new-rule.md +0 -13
|
@@ -0,0 +1,880 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Utility Functions
|
|
5
|
+
// ============================================================================
|
|
6
|
+
/**
|
|
7
|
+
* Compute the diff between two schema objects.
|
|
8
|
+
*/
|
|
9
|
+
export function computeSchemaDiff(before, after) {
|
|
10
|
+
const diff = {
|
|
11
|
+
added: {},
|
|
12
|
+
removed: {},
|
|
13
|
+
changed: {},
|
|
14
|
+
};
|
|
15
|
+
const beforeKeys = new Set(Object.keys(before ?? {}));
|
|
16
|
+
const afterKeys = new Set(Object.keys(after ?? {}));
|
|
17
|
+
// Find added keys
|
|
18
|
+
for (const key of afterKeys) {
|
|
19
|
+
if (!beforeKeys.has(key)) {
|
|
20
|
+
diff.added[key] = after[key];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Find removed keys
|
|
24
|
+
for (const key of beforeKeys) {
|
|
25
|
+
if (!afterKeys.has(key)) {
|
|
26
|
+
diff.removed[key] = before[key];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Find changed keys
|
|
30
|
+
for (const key of beforeKeys) {
|
|
31
|
+
if (afterKeys.has(key) && before[key] !== after[key]) {
|
|
32
|
+
diff.changed[key] = { from: before[key], to: after[key] };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return diff;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if a diff has any changes.
|
|
39
|
+
*/
|
|
40
|
+
export function hasDiffChanges(diff) {
|
|
41
|
+
return (Object.keys(diff.added).length > 0 ||
|
|
42
|
+
Object.keys(diff.removed).length > 0 ||
|
|
43
|
+
Object.keys(diff.changed).length > 0);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Count total changes in a diff.
|
|
47
|
+
*/
|
|
48
|
+
export function countDiffChanges(diff) {
|
|
49
|
+
return (Object.keys(diff.added).length +
|
|
50
|
+
Object.keys(diff.removed).length +
|
|
51
|
+
Object.keys(diff.changed).length);
|
|
52
|
+
}
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// TransformationTracer Class
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// Global counter to identify tracer instances
|
|
57
|
+
let tracerInstanceCounter = 0;
|
|
58
|
+
export class TransformationTracer {
|
|
59
|
+
constructor(options) {
|
|
60
|
+
this.traces = new Map();
|
|
61
|
+
this.currentEntity = null;
|
|
62
|
+
this.currentStage = null;
|
|
63
|
+
this.tracerId = ++tracerInstanceCounter;
|
|
64
|
+
this.enabled = options?.enabled ?? false;
|
|
65
|
+
this.outputPath =
|
|
66
|
+
options?.outputPath ?? '/tmp/codeyam/transform-trace.json';
|
|
67
|
+
if (this.enabled) {
|
|
68
|
+
console.log(`[Tracer] Initialized (id=${this.tracerId}, output=${this.outputPath})`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Log a message (only when tracing is enabled).
|
|
73
|
+
*/
|
|
74
|
+
log(message) {
|
|
75
|
+
if (this.isEnabled()) {
|
|
76
|
+
console.log(`[Tracer] ${message}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if tracing is enabled.
|
|
81
|
+
* Dynamically checks environment variable so it works even if set after module load.
|
|
82
|
+
*/
|
|
83
|
+
isEnabled() {
|
|
84
|
+
// Check environment variable dynamically - allows setting after module load
|
|
85
|
+
const envValue = process.env.CODEYAM_TRACE_TRANSFORMS;
|
|
86
|
+
if (envValue === '1' || envValue === 'true') {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return this.enabled;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Enable tracing.
|
|
93
|
+
*/
|
|
94
|
+
enable() {
|
|
95
|
+
this.enabled = true;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Disable tracing.
|
|
99
|
+
*/
|
|
100
|
+
disable() {
|
|
101
|
+
this.enabled = false;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Set the output path for the trace file.
|
|
105
|
+
*/
|
|
106
|
+
setOutputPath(outputPath) {
|
|
107
|
+
this.outputPath = outputPath;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Set the project slug for metadata.
|
|
111
|
+
*/
|
|
112
|
+
setProjectSlug(slug) {
|
|
113
|
+
this.projectSlug = slug;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Start tracing a new entity.
|
|
117
|
+
* If the entity already exists, preserves its existing stages and operations.
|
|
118
|
+
*/
|
|
119
|
+
startEntity(entity) {
|
|
120
|
+
if (!this.isEnabled())
|
|
121
|
+
return;
|
|
122
|
+
this.currentEntity = entity.name;
|
|
123
|
+
// Preserve existing trace data if entity was already started
|
|
124
|
+
// (e.g., early stages from generateEntityDataStructure.ts)
|
|
125
|
+
const existing = this.traces.get(entity.name);
|
|
126
|
+
if (existing) {
|
|
127
|
+
this.log(`startEntity: ${entity.name} already exists, preserving ${existing.stages.length} stages`);
|
|
128
|
+
return; // Keep existing trace data
|
|
129
|
+
}
|
|
130
|
+
this.log(`startEntity: ${entity.name}`);
|
|
131
|
+
this.traces.set(entity.name, {
|
|
132
|
+
entityName: entity.name,
|
|
133
|
+
entityType: entity.entityType,
|
|
134
|
+
filePath: entity.filePath,
|
|
135
|
+
stages: [],
|
|
136
|
+
operations: [],
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Take a coarse-grained snapshot at a transformation stage.
|
|
141
|
+
*/
|
|
142
|
+
snapshot(entityName, stage, data) {
|
|
143
|
+
if (!this.isEnabled())
|
|
144
|
+
return;
|
|
145
|
+
const trace = this.traces.get(entityName);
|
|
146
|
+
if (!trace) {
|
|
147
|
+
this.log(`snapshot: no trace for ${entityName}, creating one`);
|
|
148
|
+
this.startEntity({
|
|
149
|
+
name: entityName,
|
|
150
|
+
entityType: 'unknown',
|
|
151
|
+
filePath: 'unknown',
|
|
152
|
+
});
|
|
153
|
+
return this.snapshot(entityName, stage, data);
|
|
154
|
+
}
|
|
155
|
+
this.log(`snapshot: ${entityName} → ${stage}`);
|
|
156
|
+
this.currentStage = stage;
|
|
157
|
+
// Deep clone the data to avoid capturing references that change later
|
|
158
|
+
const clonedData = JSON.parse(JSON.stringify(data));
|
|
159
|
+
const snapshot = {
|
|
160
|
+
stage,
|
|
161
|
+
timestamp: Date.now(),
|
|
162
|
+
data: clonedData,
|
|
163
|
+
};
|
|
164
|
+
// Compute diff from previous stage if there is one
|
|
165
|
+
const previousSnapshot = trace.stages[trace.stages.length - 1];
|
|
166
|
+
if (previousSnapshot) {
|
|
167
|
+
snapshot.diffFromPrevious = {
|
|
168
|
+
signatureSchema: computeSchemaDiff(previousSnapshot.data.signatureSchema, clonedData.signatureSchema),
|
|
169
|
+
returnValueSchema: computeSchemaDiff(previousSnapshot.data.returnValueSchema, clonedData.returnValueSchema),
|
|
170
|
+
};
|
|
171
|
+
// Compute diffs for dependency schemas
|
|
172
|
+
if (clonedData.dependencySchemas ||
|
|
173
|
+
previousSnapshot.data.dependencySchemas) {
|
|
174
|
+
snapshot.diffFromPrevious.dependencySchemas = {};
|
|
175
|
+
const allDepKeys = new Set([
|
|
176
|
+
...Object.keys(clonedData.dependencySchemas ?? {}),
|
|
177
|
+
...Object.keys(previousSnapshot.data.dependencySchemas ?? {}),
|
|
178
|
+
]);
|
|
179
|
+
for (const depKey of allDepKeys) {
|
|
180
|
+
const prevDep = previousSnapshot.data.dependencySchemas?.[depKey];
|
|
181
|
+
const currDep = clonedData.dependencySchemas?.[depKey];
|
|
182
|
+
// Compare returnValueSchema for each dependency
|
|
183
|
+
for (const entityKey of new Set([
|
|
184
|
+
...Object.keys(prevDep ?? {}),
|
|
185
|
+
...Object.keys(currDep ?? {}),
|
|
186
|
+
])) {
|
|
187
|
+
const fullKey = `${depKey}::${entityKey}`;
|
|
188
|
+
const prevSchema = prevDep?.[entityKey]?.returnValueSchema;
|
|
189
|
+
const currSchema = currDep?.[entityKey]?.returnValueSchema;
|
|
190
|
+
const depDiff = computeSchemaDiff(prevSchema, currSchema);
|
|
191
|
+
if (hasDiffChanges(depDiff)) {
|
|
192
|
+
snapshot.diffFromPrevious.dependencySchemas[fullKey] = depDiff;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
trace.stages.push(snapshot);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Log a fine-grained operation within the current stage.
|
|
202
|
+
*/
|
|
203
|
+
operation(entityName, op) {
|
|
204
|
+
if (!this.isEnabled())
|
|
205
|
+
return;
|
|
206
|
+
const trace = this.traces.get(entityName);
|
|
207
|
+
if (!trace)
|
|
208
|
+
return;
|
|
209
|
+
trace.operations.push({
|
|
210
|
+
...op,
|
|
211
|
+
stage: op.stage ?? this.currentStage ?? undefined,
|
|
212
|
+
timestamp: Date.now(),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Write the trace to the output file.
|
|
217
|
+
*/
|
|
218
|
+
flush() {
|
|
219
|
+
if (!this.isEnabled())
|
|
220
|
+
return;
|
|
221
|
+
if (this.traces.size === 0) {
|
|
222
|
+
this.log('flush: no traces to write');
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const entities = Array.from(this.traces.keys());
|
|
226
|
+
const stageCounts = entities
|
|
227
|
+
.map((e) => `${e}(${this.traces.get(e).stages.length})`)
|
|
228
|
+
.join(', ');
|
|
229
|
+
this.log(`flush: writing ${entities.length} entities: ${stageCounts}`);
|
|
230
|
+
// Compute summary
|
|
231
|
+
const stageChangeCounts = {};
|
|
232
|
+
const entityChangeCounts = new Map();
|
|
233
|
+
for (const [entityName, trace] of this.traces) {
|
|
234
|
+
let entityTotal = 0;
|
|
235
|
+
for (const snapshot of trace.stages) {
|
|
236
|
+
if (!snapshot.diffFromPrevious)
|
|
237
|
+
continue;
|
|
238
|
+
const previousStage = trace.stages[trace.stages.indexOf(snapshot) - 1]?.stage ?? 'start';
|
|
239
|
+
const transitionKey = `${previousStage}→${snapshot.stage}`;
|
|
240
|
+
if (!stageChangeCounts[transitionKey]) {
|
|
241
|
+
stageChangeCounts[transitionKey] = {
|
|
242
|
+
added: 0,
|
|
243
|
+
removed: 0,
|
|
244
|
+
changed: 0,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// Count signature schema changes
|
|
248
|
+
if (snapshot.diffFromPrevious.signatureSchema) {
|
|
249
|
+
const diff = snapshot.diffFromPrevious.signatureSchema;
|
|
250
|
+
stageChangeCounts[transitionKey].added += Object.keys(diff.added).length;
|
|
251
|
+
stageChangeCounts[transitionKey].removed += Object.keys(diff.removed).length;
|
|
252
|
+
stageChangeCounts[transitionKey].changed += Object.keys(diff.changed).length;
|
|
253
|
+
entityTotal += countDiffChanges(diff);
|
|
254
|
+
}
|
|
255
|
+
// Count return value schema changes
|
|
256
|
+
if (snapshot.diffFromPrevious.returnValueSchema) {
|
|
257
|
+
const diff = snapshot.diffFromPrevious.returnValueSchema;
|
|
258
|
+
stageChangeCounts[transitionKey].added += Object.keys(diff.added).length;
|
|
259
|
+
stageChangeCounts[transitionKey].removed += Object.keys(diff.removed).length;
|
|
260
|
+
stageChangeCounts[transitionKey].changed += Object.keys(diff.changed).length;
|
|
261
|
+
entityTotal += countDiffChanges(diff);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
entityChangeCounts.set(entityName, entityTotal);
|
|
265
|
+
}
|
|
266
|
+
// Get top 10 entities with most changes
|
|
267
|
+
const entitiesWithMostChanges = [...entityChangeCounts.entries()]
|
|
268
|
+
.sort((a, b) => b[1] - a[1])
|
|
269
|
+
.slice(0, 10)
|
|
270
|
+
.map(([name]) => name);
|
|
271
|
+
const traceFile = {
|
|
272
|
+
meta: {
|
|
273
|
+
timestamp: new Date().toISOString(),
|
|
274
|
+
projectSlug: this.projectSlug,
|
|
275
|
+
entityCount: this.traces.size,
|
|
276
|
+
},
|
|
277
|
+
summary: {
|
|
278
|
+
stageChangeCounts,
|
|
279
|
+
entitiesWithMostChanges,
|
|
280
|
+
},
|
|
281
|
+
entities: Object.fromEntries(this.traces),
|
|
282
|
+
};
|
|
283
|
+
// Ensure directory exists
|
|
284
|
+
const dir = path.dirname(this.outputPath);
|
|
285
|
+
if (!fs.existsSync(dir)) {
|
|
286
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
287
|
+
}
|
|
288
|
+
fs.writeFileSync(this.outputPath, JSON.stringify(traceFile, null, 2));
|
|
289
|
+
this.log(`flush: wrote trace to ${this.outputPath}`);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Clear all traces (useful for testing).
|
|
293
|
+
*/
|
|
294
|
+
clear() {
|
|
295
|
+
this.traces.clear();
|
|
296
|
+
this.currentEntity = null;
|
|
297
|
+
this.currentStage = null;
|
|
298
|
+
}
|
|
299
|
+
// ============================================================================
|
|
300
|
+
// Analysis Utilities
|
|
301
|
+
// ============================================================================
|
|
302
|
+
/**
|
|
303
|
+
* Load a trace from a file.
|
|
304
|
+
*/
|
|
305
|
+
static loadTrace(tracePath) {
|
|
306
|
+
const content = fs.readFileSync(tracePath, 'utf-8');
|
|
307
|
+
const traceFile = JSON.parse(content);
|
|
308
|
+
const tracer = new TransformationTracer({ enabled: false });
|
|
309
|
+
tracer.projectSlug = traceFile.meta.projectSlug;
|
|
310
|
+
for (const [entityName, entityTrace] of Object.entries(traceFile.entities)) {
|
|
311
|
+
tracer.traces.set(entityName, entityTrace);
|
|
312
|
+
}
|
|
313
|
+
return tracer;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Get a high-level summary of the trace.
|
|
317
|
+
*/
|
|
318
|
+
getSummary() {
|
|
319
|
+
const stageChangeCounts = {};
|
|
320
|
+
const entityChangeCounts = new Map();
|
|
321
|
+
for (const [entityName, trace] of this.traces) {
|
|
322
|
+
let entityTotal = 0;
|
|
323
|
+
for (let i = 1; i < trace.stages.length; i++) {
|
|
324
|
+
const snapshot = trace.stages[i];
|
|
325
|
+
const previousStage = trace.stages[i - 1]?.stage ?? 'start';
|
|
326
|
+
const transitionKey = `${previousStage}→${snapshot.stage}`;
|
|
327
|
+
if (!stageChangeCounts[transitionKey]) {
|
|
328
|
+
stageChangeCounts[transitionKey] = {
|
|
329
|
+
added: 0,
|
|
330
|
+
removed: 0,
|
|
331
|
+
changed: 0,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (snapshot.diffFromPrevious?.signatureSchema) {
|
|
335
|
+
const diff = snapshot.diffFromPrevious.signatureSchema;
|
|
336
|
+
stageChangeCounts[transitionKey].added += Object.keys(diff.added).length;
|
|
337
|
+
stageChangeCounts[transitionKey].removed += Object.keys(diff.removed).length;
|
|
338
|
+
stageChangeCounts[transitionKey].changed += Object.keys(diff.changed).length;
|
|
339
|
+
entityTotal += countDiffChanges(diff);
|
|
340
|
+
}
|
|
341
|
+
if (snapshot.diffFromPrevious?.returnValueSchema) {
|
|
342
|
+
const diff = snapshot.diffFromPrevious.returnValueSchema;
|
|
343
|
+
stageChangeCounts[transitionKey].added += Object.keys(diff.added).length;
|
|
344
|
+
stageChangeCounts[transitionKey].removed += Object.keys(diff.removed).length;
|
|
345
|
+
stageChangeCounts[transitionKey].changed += Object.keys(diff.changed).length;
|
|
346
|
+
entityTotal += countDiffChanges(diff);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
entityChangeCounts.set(entityName, entityTotal);
|
|
350
|
+
}
|
|
351
|
+
const entitiesWithMostChanges = [...entityChangeCounts.entries()]
|
|
352
|
+
.sort((a, b) => b[1] - a[1])
|
|
353
|
+
.slice(0, 10)
|
|
354
|
+
.map(([name, totalChanges]) => ({ name, totalChanges }));
|
|
355
|
+
return {
|
|
356
|
+
entityCount: this.traces.size,
|
|
357
|
+
stageChangeCounts,
|
|
358
|
+
entitiesWithMostChanges,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Get a summary of stages for a specific entity.
|
|
363
|
+
*/
|
|
364
|
+
getEntitySummary(entityName) {
|
|
365
|
+
const trace = this.traces.get(entityName);
|
|
366
|
+
if (!trace)
|
|
367
|
+
return null;
|
|
368
|
+
return {
|
|
369
|
+
entityName,
|
|
370
|
+
stages: trace.stages.map((s) => ({
|
|
371
|
+
stage: s.stage,
|
|
372
|
+
diffFromPrevious: s.diffFromPrevious
|
|
373
|
+
? {
|
|
374
|
+
signatureSchema: s.diffFromPrevious.signatureSchema,
|
|
375
|
+
returnValueSchema: s.diffFromPrevious.returnValueSchema,
|
|
376
|
+
}
|
|
377
|
+
: undefined,
|
|
378
|
+
})),
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Get operations for an entity, optionally filtered by path pattern.
|
|
383
|
+
*/
|
|
384
|
+
getOperations(entityName, pathPattern) {
|
|
385
|
+
const trace = this.traces.get(entityName);
|
|
386
|
+
if (!trace)
|
|
387
|
+
return [];
|
|
388
|
+
if (!pathPattern)
|
|
389
|
+
return trace.operations;
|
|
390
|
+
return trace.operations.filter((op) => op.path && pathPattern.test(op.path));
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Trace the full history of a specific path through all transformations.
|
|
394
|
+
*/
|
|
395
|
+
tracePath(entityName, targetPath) {
|
|
396
|
+
const trace = this.traces.get(entityName);
|
|
397
|
+
const history = [];
|
|
398
|
+
if (!trace) {
|
|
399
|
+
return { entityName, path: targetPath, history };
|
|
400
|
+
}
|
|
401
|
+
// Track value through stages
|
|
402
|
+
for (const snapshot of trace.stages) {
|
|
403
|
+
const sigValue = snapshot.data.signatureSchema?.[targetPath];
|
|
404
|
+
const retValue = snapshot.data.returnValueSchema?.[targetPath];
|
|
405
|
+
const value = sigValue ?? retValue;
|
|
406
|
+
if (value !== undefined) {
|
|
407
|
+
history.push({
|
|
408
|
+
stage: snapshot.stage,
|
|
409
|
+
value,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// Track value through operations
|
|
414
|
+
for (const op of trace.operations) {
|
|
415
|
+
if (op.path === targetPath) {
|
|
416
|
+
history.push({
|
|
417
|
+
operation: op.operation,
|
|
418
|
+
stage: op.stage,
|
|
419
|
+
value: op.after ?? op.before,
|
|
420
|
+
context: op.context,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return { entityName, path: targetPath, history };
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Get the raw entity trace for direct inspection.
|
|
428
|
+
*/
|
|
429
|
+
getEntityTrace(entityName) {
|
|
430
|
+
return this.traces.get(entityName);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Get all entity names in the trace.
|
|
434
|
+
*/
|
|
435
|
+
getEntityNames() {
|
|
436
|
+
return [...this.traces.keys()];
|
|
437
|
+
}
|
|
438
|
+
// ============================================================================
|
|
439
|
+
// Debugging Utilities
|
|
440
|
+
// ============================================================================
|
|
441
|
+
/**
|
|
442
|
+
* Find all paths containing a property name across all stages.
|
|
443
|
+
* Useful for debugging: "where does 'analyses' appear in the schema?"
|
|
444
|
+
*/
|
|
445
|
+
findProperty(entityName, propertyName) {
|
|
446
|
+
const trace = this.traces.get(entityName);
|
|
447
|
+
if (!trace)
|
|
448
|
+
return [];
|
|
449
|
+
const results = [];
|
|
450
|
+
const pattern = new RegExp(`(^|\\.)${propertyName}(\\.|\\[|$)`);
|
|
451
|
+
for (const snapshot of trace.stages) {
|
|
452
|
+
// Search signature schema
|
|
453
|
+
for (const [path, type] of Object.entries(snapshot.data.signatureSchema ?? {})) {
|
|
454
|
+
if (pattern.test(path)) {
|
|
455
|
+
results.push({
|
|
456
|
+
stage: snapshot.stage,
|
|
457
|
+
path,
|
|
458
|
+
type,
|
|
459
|
+
schemaType: 'signature',
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// Search return value schema
|
|
464
|
+
for (const [path, type] of Object.entries(snapshot.data.returnValueSchema ?? {})) {
|
|
465
|
+
if (pattern.test(path)) {
|
|
466
|
+
results.push({
|
|
467
|
+
stage: snapshot.stage,
|
|
468
|
+
path,
|
|
469
|
+
type,
|
|
470
|
+
schemaType: 'returnValue',
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
// Search dependency schemas
|
|
475
|
+
for (const [depPath, depEntities] of Object.entries(snapshot.data.dependencySchemas ?? {})) {
|
|
476
|
+
for (const [depName, depData] of Object.entries(depEntities)) {
|
|
477
|
+
for (const [path, type] of Object.entries(depData.returnValueSchema ?? {})) {
|
|
478
|
+
if (pattern.test(path)) {
|
|
479
|
+
results.push({
|
|
480
|
+
stage: snapshot.stage,
|
|
481
|
+
path: `${depPath}/${depName}::${path}`,
|
|
482
|
+
type,
|
|
483
|
+
schemaType: 'dependency',
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return results;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Find properties that have inconsistent types across different paths.
|
|
494
|
+
* Useful for debugging: "why does 'analyses' have different types?"
|
|
495
|
+
*
|
|
496
|
+
* Only compares paths that end with the same pattern (e.g., both end in `.analyses`
|
|
497
|
+
* or both end in `.analyses[]`). Ignores built-in properties like `.length`.
|
|
498
|
+
*/
|
|
499
|
+
findTypeInconsistencies(entityName) {
|
|
500
|
+
const trace = this.traces.get(entityName);
|
|
501
|
+
if (!trace)
|
|
502
|
+
return [];
|
|
503
|
+
// Find the best stage for comparison (last one with dependency schemas)
|
|
504
|
+
let targetStage = trace.stages[trace.stages.length - 1];
|
|
505
|
+
for (let i = trace.stages.length - 1; i >= 0; i--) {
|
|
506
|
+
if (Object.keys(trace.stages[i].data.dependencySchemas ?? {}).length > 0) {
|
|
507
|
+
targetStage = trace.stages[i];
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
if (!targetStage)
|
|
512
|
+
return [];
|
|
513
|
+
// Built-in properties to ignore
|
|
514
|
+
const builtIns = new Set(['length', 'toString', 'valueOf', 'constructor']);
|
|
515
|
+
// Group paths by their terminal pattern (e.g., ".analyses" or ".analyses[]")
|
|
516
|
+
const propertyGroups = new Map();
|
|
517
|
+
const addToGroup = (path, type) => {
|
|
518
|
+
// Extract terminal property pattern (e.g., "foo.bar.analyses[]" -> "analyses[]")
|
|
519
|
+
const match = path.match(/\.([a-zA-Z_][a-zA-Z0-9_]*)(\[\])?$/);
|
|
520
|
+
if (!match)
|
|
521
|
+
return;
|
|
522
|
+
const propName = match[1];
|
|
523
|
+
const isArray = match[2] === '[]';
|
|
524
|
+
// Skip built-in properties
|
|
525
|
+
if (builtIns.has(propName))
|
|
526
|
+
return;
|
|
527
|
+
// Use pattern as key (includes [] suffix)
|
|
528
|
+
const pattern = propName + (isArray ? '[]' : '');
|
|
529
|
+
if (!propertyGroups.has(pattern)) {
|
|
530
|
+
propertyGroups.set(pattern, []);
|
|
531
|
+
}
|
|
532
|
+
propertyGroups.get(pattern).push({ path, type });
|
|
533
|
+
};
|
|
534
|
+
// Collect from dependency schemas (where inconsistencies usually appear)
|
|
535
|
+
for (const [, depEntities] of Object.entries(targetStage.data.dependencySchemas ?? {})) {
|
|
536
|
+
for (const [, depData] of Object.entries(depEntities)) {
|
|
537
|
+
for (const [path, type] of Object.entries(depData.returnValueSchema ?? {})) {
|
|
538
|
+
addToGroup(path, type);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
// Find inconsistencies (same terminal pattern, different types)
|
|
543
|
+
const inconsistencies = [];
|
|
544
|
+
for (const [pattern, paths] of propertyGroups) {
|
|
545
|
+
// Normalize types for comparison (treat "unknown | undefined" and "unknown" as similar)
|
|
546
|
+
const normalizedTypes = new Set(paths.map((p) => p.type.replace(/ \| undefined/g, '').replace(/ \| null/g, '')));
|
|
547
|
+
if (normalizedTypes.size > 1) {
|
|
548
|
+
inconsistencies.push({
|
|
549
|
+
propertyName: pattern,
|
|
550
|
+
paths: paths.map((p) => ({ ...p, stage: targetStage.stage })),
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
// Sort by number of different types (most inconsistent first)
|
|
555
|
+
inconsistencies.sort((a, b) => {
|
|
556
|
+
const aTypes = new Set(a.paths.map((p) => p.type)).size;
|
|
557
|
+
const bTypes = new Set(b.paths.map((p) => p.type)).size;
|
|
558
|
+
return bTypes - aTypes;
|
|
559
|
+
});
|
|
560
|
+
return inconsistencies;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Get a human-readable summary of changes between two stages.
|
|
564
|
+
*/
|
|
565
|
+
getStageDiffSummary(entityName, fromStage, toStage) {
|
|
566
|
+
const trace = this.traces.get(entityName);
|
|
567
|
+
if (!trace)
|
|
568
|
+
return null;
|
|
569
|
+
const from = trace.stages.find((s) => s.stage === fromStage);
|
|
570
|
+
const to = trace.stages.find((s) => s.stage === toStage);
|
|
571
|
+
if (!from || !to)
|
|
572
|
+
return null;
|
|
573
|
+
const result = {
|
|
574
|
+
added: [],
|
|
575
|
+
removed: [],
|
|
576
|
+
typeChanged: [],
|
|
577
|
+
};
|
|
578
|
+
// Compare return value schemas (most common)
|
|
579
|
+
const fromSchema = from.data.returnValueSchema ?? {};
|
|
580
|
+
const toSchema = to.data.returnValueSchema ?? {};
|
|
581
|
+
const fromKeys = new Set(Object.keys(fromSchema));
|
|
582
|
+
const toKeys = new Set(Object.keys(toSchema));
|
|
583
|
+
for (const key of toKeys) {
|
|
584
|
+
if (!fromKeys.has(key)) {
|
|
585
|
+
result.added.push(`${key}: ${toSchema[key]}`);
|
|
586
|
+
}
|
|
587
|
+
else if (fromSchema[key] !== toSchema[key]) {
|
|
588
|
+
result.typeChanged.push({
|
|
589
|
+
path: key,
|
|
590
|
+
from: fromSchema[key],
|
|
591
|
+
to: toSchema[key],
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
for (const key of fromKeys) {
|
|
596
|
+
if (!toKeys.has(key)) {
|
|
597
|
+
result.removed.push(`${key}: ${fromSchema[key]}`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
return result;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Trace a schema transformation by capturing before/after and logging operations for all changes.
|
|
604
|
+
*
|
|
605
|
+
* This is a helper to wrap transformative functions like:
|
|
606
|
+
* - cleanKnownObjectFunctionsFromMapping
|
|
607
|
+
* - clearAttributesFromMapping
|
|
608
|
+
* - fillInDirectSchemaGapsAndUnknowns
|
|
609
|
+
* - deduplicateFunctionSchemas
|
|
610
|
+
*
|
|
611
|
+
* @param entityName - The entity being traced
|
|
612
|
+
* @param operationName - Name of the transformation (e.g., 'cleanKnownObjectFunctions')
|
|
613
|
+
* @param schema - The schema to transform (will be mutated)
|
|
614
|
+
* @param transformFn - The transformation function to run
|
|
615
|
+
* @param context - Optional context to include in operation logs
|
|
616
|
+
* @returns The schema (same reference, mutated)
|
|
617
|
+
*/
|
|
618
|
+
traceSchemaTransform(entityName, operationName, schema, transformFn, context) {
|
|
619
|
+
if (!this.enabled) {
|
|
620
|
+
transformFn(schema);
|
|
621
|
+
return schema;
|
|
622
|
+
}
|
|
623
|
+
// Capture before state
|
|
624
|
+
const before = { ...schema };
|
|
625
|
+
// Run the transformation
|
|
626
|
+
transformFn(schema);
|
|
627
|
+
// Compute diff and log operations
|
|
628
|
+
const diff = computeSchemaDiff(before, schema);
|
|
629
|
+
// Log added paths
|
|
630
|
+
for (const [path, value] of Object.entries(diff.added)) {
|
|
631
|
+
this.operation(entityName, {
|
|
632
|
+
operation: operationName,
|
|
633
|
+
path,
|
|
634
|
+
before: undefined,
|
|
635
|
+
after: value,
|
|
636
|
+
context: { ...context, changeType: 'added' },
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
// Log removed paths
|
|
640
|
+
for (const [path, value] of Object.entries(diff.removed)) {
|
|
641
|
+
this.operation(entityName, {
|
|
642
|
+
operation: operationName,
|
|
643
|
+
path,
|
|
644
|
+
before: value,
|
|
645
|
+
after: undefined,
|
|
646
|
+
context: { ...context, changeType: 'removed' },
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
// Log changed paths
|
|
650
|
+
for (const [path, { from, to }] of Object.entries(diff.changed)) {
|
|
651
|
+
this.operation(entityName, {
|
|
652
|
+
operation: operationName,
|
|
653
|
+
path,
|
|
654
|
+
before: from,
|
|
655
|
+
after: to,
|
|
656
|
+
context: { ...context, changeType: 'changed' },
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
return schema;
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Trace a schema transformation where the function returns a new schema (non-mutating).
|
|
663
|
+
*
|
|
664
|
+
* Use this for functions like deduplicateFunctionSchemas that return a new object
|
|
665
|
+
* rather than mutating the input.
|
|
666
|
+
*
|
|
667
|
+
* @param entityName - The entity being traced
|
|
668
|
+
* @param operationName - Name of the transformation
|
|
669
|
+
* @param before - The schema before transformation
|
|
670
|
+
* @param after - The schema after transformation
|
|
671
|
+
* @param context - Optional context to include in operation logs
|
|
672
|
+
*/
|
|
673
|
+
traceSchemaTransformResult(entityName, operationName, before, after, context) {
|
|
674
|
+
if (!this.enabled)
|
|
675
|
+
return;
|
|
676
|
+
// Compute diff and log operations
|
|
677
|
+
const diff = computeSchemaDiff(before, after);
|
|
678
|
+
// Log added paths
|
|
679
|
+
for (const [path, value] of Object.entries(diff.added)) {
|
|
680
|
+
this.operation(entityName, {
|
|
681
|
+
operation: operationName,
|
|
682
|
+
path,
|
|
683
|
+
before: undefined,
|
|
684
|
+
after: value,
|
|
685
|
+
context: { ...context, changeType: 'added' },
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
// Log removed paths
|
|
689
|
+
for (const [path, value] of Object.entries(diff.removed)) {
|
|
690
|
+
this.operation(entityName, {
|
|
691
|
+
operation: operationName,
|
|
692
|
+
path,
|
|
693
|
+
before: value,
|
|
694
|
+
after: undefined,
|
|
695
|
+
context: { ...context, changeType: 'removed' },
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
// Log changed paths
|
|
699
|
+
for (const [path, { from, to }] of Object.entries(diff.changed)) {
|
|
700
|
+
this.operation(entityName, {
|
|
701
|
+
operation: operationName,
|
|
702
|
+
path,
|
|
703
|
+
before: from,
|
|
704
|
+
after: to,
|
|
705
|
+
context: { ...context, changeType: 'changed' },
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Trace multiple schemas in a dependency schemas structure.
|
|
711
|
+
* Useful for tracing transformations that apply to all dependency schemas.
|
|
712
|
+
*
|
|
713
|
+
* @param entityName - The entity being traced
|
|
714
|
+
* @param operationName - Name of the transformation
|
|
715
|
+
* @param dependencySchemas - The dependency schemas structure
|
|
716
|
+
* @param transformFn - Function to apply to each schema (signature or returnValue)
|
|
717
|
+
* @param schemaType - Which schema to transform: 'signature', 'returnValue', or 'both'
|
|
718
|
+
*/
|
|
719
|
+
traceDependencySchemaTransform(entityName, operationName, dependencySchemas, transformFn, schemaType = 'both') {
|
|
720
|
+
if (!this.enabled) {
|
|
721
|
+
// Still run the transform even if not tracing
|
|
722
|
+
for (const filePath in dependencySchemas) {
|
|
723
|
+
for (const depName in dependencySchemas[filePath]) {
|
|
724
|
+
const depSchema = dependencySchemas[filePath][depName];
|
|
725
|
+
if ((schemaType === 'signature' || schemaType === 'both') &&
|
|
726
|
+
depSchema.signatureSchema) {
|
|
727
|
+
transformFn(depSchema.signatureSchema);
|
|
728
|
+
}
|
|
729
|
+
if ((schemaType === 'returnValue' || schemaType === 'both') &&
|
|
730
|
+
depSchema.returnValueSchema) {
|
|
731
|
+
transformFn(depSchema.returnValueSchema);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
for (const filePath in dependencySchemas) {
|
|
738
|
+
for (const depName in dependencySchemas[filePath]) {
|
|
739
|
+
const depSchema = dependencySchemas[filePath][depName];
|
|
740
|
+
const depContext = { filePath, dependencyName: depName };
|
|
741
|
+
if ((schemaType === 'signature' || schemaType === 'both') &&
|
|
742
|
+
depSchema.signatureSchema) {
|
|
743
|
+
this.traceSchemaTransform(entityName, operationName, depSchema.signatureSchema, transformFn, { ...depContext, schemaType: 'signature' });
|
|
744
|
+
}
|
|
745
|
+
if ((schemaType === 'returnValue' || schemaType === 'both') &&
|
|
746
|
+
depSchema.returnValueSchema) {
|
|
747
|
+
this.traceSchemaTransform(entityName, operationName, depSchema.returnValueSchema, transformFn, { ...depContext, schemaType: 'returnValue' });
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Trace changes to dependency schemas before/after a function call.
|
|
754
|
+
*
|
|
755
|
+
* Use this for functions like enrichArrayTypesFromChildSignatures or
|
|
756
|
+
* enrichUnknownTypesFromSourceEquivalencies that modify dependency schemas in place.
|
|
757
|
+
*
|
|
758
|
+
* @param entityName - The entity being traced
|
|
759
|
+
* @param operationName - Name of the transformation
|
|
760
|
+
* @param dependencySchemas - The dependency schemas to track
|
|
761
|
+
* @param transformFn - The function to run (should mutate dependencySchemas)
|
|
762
|
+
*/
|
|
763
|
+
traceDependencySchemaChanges(entityName, operationName, dependencySchemas, transformFn) {
|
|
764
|
+
if (!this.enabled) {
|
|
765
|
+
transformFn();
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
// Capture before state (deep copy of all schemas)
|
|
769
|
+
const beforeState = {};
|
|
770
|
+
for (const filePath in dependencySchemas) {
|
|
771
|
+
beforeState[filePath] = {};
|
|
772
|
+
for (const depName in dependencySchemas[filePath]) {
|
|
773
|
+
const depSchema = dependencySchemas[filePath][depName];
|
|
774
|
+
beforeState[filePath][depName] = {
|
|
775
|
+
sig: { ...(depSchema.signatureSchema || {}) },
|
|
776
|
+
rv: { ...(depSchema.returnValueSchema || {}) },
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
// Run the transformation
|
|
781
|
+
transformFn();
|
|
782
|
+
// Compare and log changes
|
|
783
|
+
for (const filePath in dependencySchemas) {
|
|
784
|
+
for (const depName in dependencySchemas[filePath]) {
|
|
785
|
+
const depSchema = dependencySchemas[filePath][depName];
|
|
786
|
+
const before = beforeState[filePath]?.[depName];
|
|
787
|
+
const context = { filePath, dependencyName: depName };
|
|
788
|
+
// Check signature schema changes
|
|
789
|
+
if (depSchema.signatureSchema) {
|
|
790
|
+
const sigBefore = before?.sig || {};
|
|
791
|
+
const diff = computeSchemaDiff(sigBefore, depSchema.signatureSchema);
|
|
792
|
+
for (const [path, value] of Object.entries(diff.added)) {
|
|
793
|
+
this.operation(entityName, {
|
|
794
|
+
operation: operationName,
|
|
795
|
+
path,
|
|
796
|
+
before: undefined,
|
|
797
|
+
after: value,
|
|
798
|
+
context: {
|
|
799
|
+
...context,
|
|
800
|
+
schemaType: 'signature',
|
|
801
|
+
changeType: 'added',
|
|
802
|
+
},
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
for (const [path, { from, to }] of Object.entries(diff.changed)) {
|
|
806
|
+
this.operation(entityName, {
|
|
807
|
+
operation: operationName,
|
|
808
|
+
path,
|
|
809
|
+
before: from,
|
|
810
|
+
after: to,
|
|
811
|
+
context: {
|
|
812
|
+
...context,
|
|
813
|
+
schemaType: 'signature',
|
|
814
|
+
changeType: 'changed',
|
|
815
|
+
},
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
// Check return value schema changes
|
|
820
|
+
if (depSchema.returnValueSchema) {
|
|
821
|
+
const rvBefore = before?.rv || {};
|
|
822
|
+
const diff = computeSchemaDiff(rvBefore, depSchema.returnValueSchema);
|
|
823
|
+
for (const [path, value] of Object.entries(diff.added)) {
|
|
824
|
+
this.operation(entityName, {
|
|
825
|
+
operation: operationName,
|
|
826
|
+
path,
|
|
827
|
+
before: undefined,
|
|
828
|
+
after: value,
|
|
829
|
+
context: {
|
|
830
|
+
...context,
|
|
831
|
+
schemaType: 'returnValue',
|
|
832
|
+
changeType: 'added',
|
|
833
|
+
},
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
for (const [path, { from, to }] of Object.entries(diff.changed)) {
|
|
837
|
+
this.operation(entityName, {
|
|
838
|
+
operation: operationName,
|
|
839
|
+
path,
|
|
840
|
+
before: from,
|
|
841
|
+
after: to,
|
|
842
|
+
context: {
|
|
843
|
+
...context,
|
|
844
|
+
schemaType: 'returnValue',
|
|
845
|
+
changeType: 'changed',
|
|
846
|
+
},
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
// ============================================================================
|
|
855
|
+
// Global Instance
|
|
856
|
+
// ============================================================================
|
|
857
|
+
/**
|
|
858
|
+
* Check if tracing is enabled via environment variable.
|
|
859
|
+
*/
|
|
860
|
+
function isTracingEnabled() {
|
|
861
|
+
const envValue = process.env.CODEYAM_TRACE_TRANSFORMS;
|
|
862
|
+
return envValue === '1' || envValue === 'true';
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Global tracer instance.
|
|
866
|
+
* Enabled via CODEYAM_TRACE_TRANSFORMS=1 environment variable.
|
|
867
|
+
* Output is always written to /tmp/codeyam/transform-trace.json
|
|
868
|
+
*/
|
|
869
|
+
export const transformationTracer = new TransformationTracer({
|
|
870
|
+
enabled: isTracingEnabled(),
|
|
871
|
+
outputPath: '/tmp/codeyam/transform-trace.json',
|
|
872
|
+
});
|
|
873
|
+
// Auto-flush on process exit if tracing is enabled and there's data
|
|
874
|
+
process.on('beforeExit', () => {
|
|
875
|
+
if (transformationTracer.isEnabled()) {
|
|
876
|
+
transformationTracer.flush();
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
export default transformationTracer;
|
|
880
|
+
//# sourceMappingURL=TransformationTracer.js.map
|