@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
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
CompoundConditional,
|
|
19
19
|
DerivedVariableOperation,
|
|
20
20
|
DerivedVariableInfo,
|
|
21
|
+
JsxRenderingUsage,
|
|
21
22
|
} from './astScopes/types';
|
|
22
23
|
import type { EnrichedConditionalUsage } from './worker/SerializableDataStructure';
|
|
23
24
|
import resolvePathToControllable from './resolvePathToControllable';
|
|
@@ -32,7 +33,7 @@ export interface ChildComponentConditionalData {
|
|
|
32
33
|
/** Child's conditional usages keyed by variable name (may include sourceDataPath from enrichment) */
|
|
33
34
|
conditionalUsages: Record<string, ExtendedConditionalUsage[]>;
|
|
34
35
|
/** Child's equivalent signature variables (maps internal paths to prop paths) */
|
|
35
|
-
equivalentSignatureVariables: Record<string, string>;
|
|
36
|
+
equivalentSignatureVariables: Record<string, string | string[]>;
|
|
36
37
|
/** Child's compound conditionals */
|
|
37
38
|
compoundConditionals: CompoundConditional[];
|
|
38
39
|
/**
|
|
@@ -41,6 +42,11 @@ export interface ChildComponentConditionalData {
|
|
|
41
42
|
* then `hasAnalysis` is a gating condition for all of ChildComponent's flows.
|
|
42
43
|
*/
|
|
43
44
|
gatingConditions?: ConditionalUsage[];
|
|
45
|
+
/**
|
|
46
|
+
* Child's JSX rendering usages (arrays rendered via .map(), text interpolation).
|
|
47
|
+
* These generate "variation flows" for different array lengths.
|
|
48
|
+
*/
|
|
49
|
+
jsxRenderingUsages?: JsxRenderingUsage[];
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
export interface GenerateFlowsFromConditionalsArgs {
|
|
@@ -51,7 +57,7 @@ export interface GenerateFlowsFromConditionalsArgs {
|
|
|
51
57
|
/** Map of controllable paths to their types */
|
|
52
58
|
attributesMap: Record<string, string>;
|
|
53
59
|
/** Map from local variable names to data sources */
|
|
54
|
-
equivalentSignatureVariables: Record<string, string>;
|
|
60
|
+
equivalentSignatureVariables: Record<string, string | string[]>;
|
|
55
61
|
/** Map from full paths to short paths */
|
|
56
62
|
fullToShortPathMap: Record<string, string>;
|
|
57
63
|
/**
|
|
@@ -73,6 +79,21 @@ export interface GenerateFlowsFromConditionalsArgs {
|
|
|
73
79
|
* to `currentRun.entityShas` when `isInCurrentRun` isn't in conditionalUsages.
|
|
74
80
|
*/
|
|
75
81
|
derivedVariables?: Record<string, DerivedVariableInfo>;
|
|
82
|
+
/**
|
|
83
|
+
* Optional map of child prop paths to their actual data sources.
|
|
84
|
+
* Used when child props flow through useState but ultimately come from
|
|
85
|
+
* mockable data sources (e.g., API calls, fetchers).
|
|
86
|
+
*
|
|
87
|
+
* Example:
|
|
88
|
+
* - "WorkoutsView().signature[0].workouts" → "createClient()...functionCallReturnValue.data"
|
|
89
|
+
*
|
|
90
|
+
* When a child path translates to a useState value, we check this map
|
|
91
|
+
* to find the real data source that can be mocked.
|
|
92
|
+
*/
|
|
93
|
+
sourceEquivalencies?: Record<
|
|
94
|
+
string,
|
|
95
|
+
Array<{ scopeNodeName: string; schemaPath: string }>
|
|
96
|
+
>;
|
|
76
97
|
}
|
|
77
98
|
|
|
78
99
|
/**
|
|
@@ -117,7 +138,7 @@ function expandDerivedVariableToSources(
|
|
|
117
138
|
path: string,
|
|
118
139
|
conditionalUsages: Record<string, ConditionalUsage[]>,
|
|
119
140
|
attributesMap: Record<string, string>,
|
|
120
|
-
equivalentSignatureVariables: Record<string, string>,
|
|
141
|
+
equivalentSignatureVariables: Record<string, string | string[]>,
|
|
121
142
|
fullToShortPathMap: Record<string, string>,
|
|
122
143
|
visited: Set<string> = new Set(),
|
|
123
144
|
derivedVariables?: Record<string, DerivedVariableInfo>,
|
|
@@ -238,11 +259,15 @@ function cleanSourceDataPath(sourceDataPath: string): string | null {
|
|
|
238
259
|
sourceDataPath.match(/\.functionCallReturnValue/g) || []
|
|
239
260
|
).length;
|
|
240
261
|
|
|
241
|
-
//
|
|
242
|
-
//
|
|
262
|
+
// For chained function calls (e.g., fetch().json()) or paths with non-standard
|
|
263
|
+
// fn call patterns, return the original path so findInAttributesMapForPath can
|
|
264
|
+
// try to look it up in fullToShortPathMap. If it doesn't match, the caller
|
|
265
|
+
// falls through to fallback resolution anyway.
|
|
243
266
|
if (fnCallReturnValues > 1 || emptyFnCalls !== 1) {
|
|
244
|
-
|
|
245
|
-
|
|
267
|
+
console.log(
|
|
268
|
+
`[cleanSourceDataPath] chained/non-standard path (fnCallRVs=${fnCallReturnValues}, emptyFnCalls=${emptyFnCalls}), returning original: "${sourceDataPath}"`,
|
|
269
|
+
);
|
|
270
|
+
return sourceDataPath;
|
|
246
271
|
}
|
|
247
272
|
|
|
248
273
|
// Find the "()" which marks the function call
|
|
@@ -287,6 +312,85 @@ function stripLengthSuffix(path: string): string {
|
|
|
287
312
|
return path;
|
|
288
313
|
}
|
|
289
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Remove contradictory required values from a compound flow.
|
|
317
|
+
*
|
|
318
|
+
* When a lifecycle boolean (like isLoadingAuditData) is traced to a fetch call's
|
|
319
|
+
* return value, a negated condition (!isLoadingAuditData) produces "falsy" on
|
|
320
|
+
* the fetch path. But if another condition in the same compound requires data
|
|
321
|
+
* from a sub-path of that fetch (e.g., topPaths length > 0), the "falsy" on the
|
|
322
|
+
* parent path contradicts it — a null/falsy response has no .json() to call.
|
|
323
|
+
*
|
|
324
|
+
* This function removes "falsy" required values whose attributePath is a prefix
|
|
325
|
+
* of another required value's attributePath. The child data requirement already
|
|
326
|
+
* implies the parent (fetch) succeeded.
|
|
327
|
+
*/
|
|
328
|
+
function removeContradictoryFalsyValues(
|
|
329
|
+
requiredValues: ExecutionFlow['requiredValues'],
|
|
330
|
+
): ExecutionFlow['requiredValues'] {
|
|
331
|
+
return requiredValues.filter((rv) => {
|
|
332
|
+
if (rv.comparison === 'falsy') {
|
|
333
|
+
const hasChildRequirement = requiredValues.some(
|
|
334
|
+
(other) =>
|
|
335
|
+
other !== rv &&
|
|
336
|
+
other.attributePath.startsWith(rv.attributePath + '.'),
|
|
337
|
+
);
|
|
338
|
+
if (hasChildRequirement) {
|
|
339
|
+
return false;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return true;
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Generate a human-readable description snippet for a required value,
|
|
348
|
+
* incorporating the comparison type so the LLM understands the intent.
|
|
349
|
+
*/
|
|
350
|
+
function describeRequiredValue(rv: ExecutionFlow['requiredValues'][0]): string {
|
|
351
|
+
const name = generateNameFromPath(rv.attributePath).toLowerCase();
|
|
352
|
+
switch (rv.comparison) {
|
|
353
|
+
case 'truthy':
|
|
354
|
+
return `${name} is present`;
|
|
355
|
+
case 'falsy':
|
|
356
|
+
return `${name} is absent`;
|
|
357
|
+
case 'length>':
|
|
358
|
+
return rv.value === '0'
|
|
359
|
+
? `${name} has items`
|
|
360
|
+
: `${name} has more than ${rv.value} items`;
|
|
361
|
+
case 'length<':
|
|
362
|
+
return `${name} has fewer than ${rv.value} items`;
|
|
363
|
+
case 'equals':
|
|
364
|
+
return `${name} is ${rv.value}`;
|
|
365
|
+
case 'exists':
|
|
366
|
+
return `${name} exists`;
|
|
367
|
+
case 'not-exists':
|
|
368
|
+
return `${name} does not exist`;
|
|
369
|
+
default:
|
|
370
|
+
return `${name} is ${rv.value}`;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Check whether a resolved path has child entries in the fullToShortPathMap.
|
|
376
|
+
*
|
|
377
|
+
* When a lifecycle boolean (e.g., isLoadingAuditData) resolves to a parent path
|
|
378
|
+
* like fetch(...).functionCallReturnValue, and that path has children (like
|
|
379
|
+
* .json().functionCallReturnValue.topPaths), individual truthy/falsy flows on
|
|
380
|
+
* the parent are misleading. Compound flows with specific child requirements
|
|
381
|
+
* provide better guidance for mock data generation.
|
|
382
|
+
*/
|
|
383
|
+
function hasChildPathsInMap(
|
|
384
|
+
resolvedPath: string,
|
|
385
|
+
fullToShortPathMap: Record<string, string>,
|
|
386
|
+
): boolean {
|
|
387
|
+
return Object.keys(fullToShortPathMap).some(
|
|
388
|
+
(fullPath) =>
|
|
389
|
+
fullPath.startsWith(resolvedPath + '.') ||
|
|
390
|
+
fullPath.startsWith(resolvedPath + '['),
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
290
394
|
/**
|
|
291
395
|
* Extract the controllable base path from a path that may contain method calls.
|
|
292
396
|
*
|
|
@@ -329,13 +433,16 @@ function extractControllableBase(path: string): string {
|
|
|
329
433
|
* The sourceDataPath contains full paths (e.g., "useLoaderData<LoaderData>().functionCallReturnValue.entity.sha")
|
|
330
434
|
* The fullToShortPathMap maps full paths to short paths
|
|
331
435
|
*/
|
|
332
|
-
function findInAttributesMapForPath(
|
|
436
|
+
export function findInAttributesMapForPath(
|
|
333
437
|
path: string,
|
|
334
438
|
attributesMap: Record<string, string>,
|
|
335
439
|
fullToShortPathMap: Record<string, string>,
|
|
336
440
|
): string | null {
|
|
337
441
|
// Direct match in attributesMap (already a short path)
|
|
338
442
|
if (path in attributesMap) {
|
|
443
|
+
console.log(
|
|
444
|
+
`[findInAttributesMapForPath] "${path}" → DIRECT match in attributesMap`,
|
|
445
|
+
);
|
|
339
446
|
return path;
|
|
340
447
|
}
|
|
341
448
|
|
|
@@ -344,19 +451,31 @@ function findInAttributesMapForPath(
|
|
|
344
451
|
if (path in fullToShortPathMap) {
|
|
345
452
|
const shortPath = fullToShortPathMap[path];
|
|
346
453
|
if (shortPath in attributesMap) {
|
|
454
|
+
console.log(
|
|
455
|
+
`[findInAttributesMapForPath] "${path}" → fullToShortPathMap match: shortPath="${shortPath}" found in attributesMap`,
|
|
456
|
+
);
|
|
347
457
|
return path; // Return FULL path to preserve data source context
|
|
348
458
|
}
|
|
459
|
+
console.log(
|
|
460
|
+
`[findInAttributesMapForPath] "${path}" → fullToShortPathMap match shortPath="${shortPath}" but NOT in attributesMap`,
|
|
461
|
+
);
|
|
349
462
|
}
|
|
350
463
|
|
|
351
464
|
// Normalized match (array indices [N] → [])
|
|
352
465
|
const normalizedPath = path.replace(/\[\d+\]/g, '[]');
|
|
353
466
|
if (normalizedPath !== path) {
|
|
354
467
|
if (normalizedPath in attributesMap) {
|
|
468
|
+
console.log(
|
|
469
|
+
`[findInAttributesMapForPath] "${path}" → normalized "${normalizedPath}" DIRECT match in attributesMap`,
|
|
470
|
+
);
|
|
355
471
|
return normalizedPath;
|
|
356
472
|
}
|
|
357
473
|
if (normalizedPath in fullToShortPathMap) {
|
|
358
474
|
const shortPath = fullToShortPathMap[normalizedPath];
|
|
359
475
|
if (shortPath in attributesMap) {
|
|
476
|
+
console.log(
|
|
477
|
+
`[findInAttributesMapForPath] "${path}" → normalized "${normalizedPath}" fullToShortPathMap match: shortPath="${shortPath}"`,
|
|
478
|
+
);
|
|
360
479
|
return normalizedPath; // Return normalized FULL path
|
|
361
480
|
}
|
|
362
481
|
}
|
|
@@ -368,25 +487,92 @@ function findInAttributesMapForPath(
|
|
|
368
487
|
// and we need to find matching short path prefix
|
|
369
488
|
for (const attrPath of Object.keys(attributesMap)) {
|
|
370
489
|
if (path.startsWith(attrPath + '.') || path.startsWith(attrPath + '[')) {
|
|
371
|
-
|
|
490
|
+
console.log(
|
|
491
|
+
`[findInAttributesMapForPath] "${path}" → PREFIX match: starts with attributesMap key "${attrPath}"`,
|
|
492
|
+
);
|
|
372
493
|
return path;
|
|
373
494
|
}
|
|
374
495
|
}
|
|
375
496
|
|
|
376
497
|
// Try suffix matching: if the path ends with ".X.Y.Z" and attributesMap has "X.Y.Z"
|
|
377
498
|
// Return the FULL input path to preserve data source context
|
|
378
|
-
for
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
)
|
|
383
|
-
|
|
499
|
+
// Skip suffix matching for chained function calls (multiple .functionCallReturnValue segments)
|
|
500
|
+
// to avoid false matches: e.g., fetch(...).json().functionCallReturnValue.data falsely matching
|
|
501
|
+
// "data" from a completely different data source like useFetcher
|
|
502
|
+
const fnCallReturnValueCount = (
|
|
503
|
+
path.match(/\.functionCallReturnValue/g) || []
|
|
504
|
+
).length;
|
|
505
|
+
if (fnCallReturnValueCount <= 1) {
|
|
506
|
+
for (const attrPath of Object.keys(attributesMap)) {
|
|
507
|
+
if (
|
|
508
|
+
path.endsWith('.' + attrPath) ||
|
|
509
|
+
path.endsWith('.' + attrPath.replace(/\[\d+\]/g, '[]'))
|
|
510
|
+
) {
|
|
511
|
+
console.log(
|
|
512
|
+
`[findInAttributesMapForPath] "${path}" → SUFFIX match: ends with attributesMap key "${attrPath}"`,
|
|
513
|
+
);
|
|
514
|
+
return path; // Return FULL path, not short attrPath
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Try child path matching against fullToShortPathMap keys
|
|
520
|
+
// If the path starts with a known full path + '.' or '[', it's a child
|
|
521
|
+
// of a controllable path. Build the equivalent short child path.
|
|
522
|
+
// e.g., path = "fetch(...).fCRV.json().fCRV.topPaths.length"
|
|
523
|
+
// fullToShortPathMap has "fetch(...).fCRV.json().fCRV.topPaths" → "json().fCRV.topPaths"
|
|
524
|
+
// → check if "json().fCRV.topPaths.length" is in attributesMap
|
|
525
|
+
for (const [fullPath, shortPath] of Object.entries(fullToShortPathMap)) {
|
|
526
|
+
if (path.startsWith(fullPath + '.') || path.startsWith(fullPath + '[')) {
|
|
527
|
+
const suffix = path.slice(fullPath.length); // e.g., ".length"
|
|
528
|
+
const shortChildPath = shortPath + suffix;
|
|
529
|
+
if (shortChildPath in attributesMap) {
|
|
530
|
+
console.log(
|
|
531
|
+
`[findInAttributesMapForPath] "${path}" → CHILD of fullToShortPathMap key "${fullPath}": shortChildPath="${shortChildPath}" found in attributesMap`,
|
|
532
|
+
);
|
|
533
|
+
return path; // Return full path to preserve data source context
|
|
534
|
+
}
|
|
535
|
+
// Also check if the base short path is an array and suffix is .length
|
|
536
|
+
if (suffix === '.length' && shortPath in attributesMap) {
|
|
537
|
+
console.log(
|
|
538
|
+
`[findInAttributesMapForPath] "${path}" → CHILD .length of fullToShortPathMap key "${fullPath}": base shortPath="${shortPath}" is in attributesMap (array .length)`,
|
|
539
|
+
);
|
|
540
|
+
return path; // Array .length is controllable via the array
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Try parent matching: if the path is a prefix of any fullToShortPathMap key,
|
|
546
|
+
// it's a parent of controllable data and therefore controllable itself
|
|
547
|
+
for (const fullPath of Object.keys(fullToShortPathMap)) {
|
|
548
|
+
if (fullPath.startsWith(path + '.') || fullPath.startsWith(path + '[')) {
|
|
549
|
+
console.log(
|
|
550
|
+
`[findInAttributesMapForPath] "${path}" → PARENT match: fullToShortPathMap key "${fullPath}" starts with this path`,
|
|
551
|
+
);
|
|
552
|
+
return path;
|
|
384
553
|
}
|
|
385
554
|
}
|
|
386
555
|
|
|
556
|
+
console.log(
|
|
557
|
+
`[findInAttributesMapForPath] "${path}" → NO MATCH (checked ${Object.keys(attributesMap).length} attributesMap keys, ${Object.keys(fullToShortPathMap).length} fullToShortPathMap keys)`,
|
|
558
|
+
);
|
|
387
559
|
return null;
|
|
388
560
|
}
|
|
389
561
|
|
|
562
|
+
/**
|
|
563
|
+
* Generate a slug from a path for use in flow IDs and exclusive groups.
|
|
564
|
+
*/
|
|
565
|
+
function pathToSlug(path: string): string {
|
|
566
|
+
return path
|
|
567
|
+
.replace(/\[\d+\]/g, '')
|
|
568
|
+
.replace(/\[\]/g, '')
|
|
569
|
+
.replace(/\(\)/g, '')
|
|
570
|
+
.replace(/\.functionCallReturnValue/g, '')
|
|
571
|
+
.replace(/[<>]/g, '')
|
|
572
|
+
.replace(/\./g, '-')
|
|
573
|
+
.toLowerCase();
|
|
574
|
+
}
|
|
575
|
+
|
|
390
576
|
/**
|
|
391
577
|
* Generate a human-readable name from a path.
|
|
392
578
|
* Extracts the last meaningful part of the path.
|
|
@@ -598,7 +784,15 @@ function generateFlowFromCompound(
|
|
|
598
784
|
condition.requiredValue?.toString() ??
|
|
599
785
|
condition.comparedValues?.[0] ??
|
|
600
786
|
'truthy';
|
|
601
|
-
comparison
|
|
787
|
+
// Map comparison operator to flow comparison type
|
|
788
|
+
const op = condition.comparisonOperator;
|
|
789
|
+
if (op === '>' || op === '>=') {
|
|
790
|
+
comparison = 'length>';
|
|
791
|
+
} else if (op === '<' || op === '<=') {
|
|
792
|
+
comparison = 'length<';
|
|
793
|
+
} else {
|
|
794
|
+
comparison = 'equals';
|
|
795
|
+
}
|
|
602
796
|
}
|
|
603
797
|
|
|
604
798
|
requiredValues.push({
|
|
@@ -609,21 +803,32 @@ function generateFlowFromCompound(
|
|
|
609
803
|
});
|
|
610
804
|
}
|
|
611
805
|
|
|
612
|
-
//
|
|
613
|
-
const
|
|
806
|
+
// Remove contradictory "falsy" values where a child path requires data
|
|
807
|
+
const cleanedValues = removeContradictoryFalsyValues(requiredValues);
|
|
808
|
+
|
|
809
|
+
if (cleanedValues.length === 0) {
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// Generate a combined ID from all paths + values to distinguish different comparisons
|
|
814
|
+
const pathParts = cleanedValues
|
|
614
815
|
.map((rv) => {
|
|
615
816
|
const name = generateNameFromPath(rv.attributePath);
|
|
616
|
-
|
|
817
|
+
const suffix =
|
|
818
|
+
rv.comparison === 'truthy' || rv.comparison === 'falsy'
|
|
819
|
+
? `-${rv.comparison}`
|
|
820
|
+
: `-${rv.comparison}-${rv.value}`;
|
|
821
|
+
return name.toLowerCase().replace(/\s+/g, '-') + suffix;
|
|
617
822
|
})
|
|
618
823
|
.join('-and-');
|
|
619
824
|
|
|
620
825
|
return {
|
|
621
826
|
id: `compound-${pathParts}`,
|
|
622
|
-
name:
|
|
827
|
+
name: cleanedValues
|
|
623
828
|
.map((rv) => generateNameFromPath(rv.attributePath))
|
|
624
829
|
.join(' + '),
|
|
625
|
-
description: `When ${
|
|
626
|
-
requiredValues,
|
|
830
|
+
description: `When ${cleanedValues.map((rv) => describeRequiredValue(rv)).join(' and ')}`,
|
|
831
|
+
requiredValues: cleanedValues,
|
|
627
832
|
impact,
|
|
628
833
|
sourceLocation: {
|
|
629
834
|
lineNumber: compound.sourceLocation.lineNumber,
|
|
@@ -732,8 +937,8 @@ function normalizePathForDeduplication(
|
|
|
732
937
|
*/
|
|
733
938
|
function translateChildPathToParent(
|
|
734
939
|
childPath: string,
|
|
735
|
-
childEquivalentSignatureVariables: Record<string, string>,
|
|
736
|
-
parentEquivalentSignatureVariables: Record<string, string>,
|
|
940
|
+
childEquivalentSignatureVariables: Record<string, string | string[]>,
|
|
941
|
+
parentEquivalentSignatureVariables: Record<string, string | string[]>,
|
|
737
942
|
childName: string,
|
|
738
943
|
): string | null {
|
|
739
944
|
// Extract the root variable from the child path
|
|
@@ -760,7 +965,11 @@ function translateChildPathToParent(
|
|
|
760
965
|
|
|
761
966
|
// Look up the child's equivalence for this root variable
|
|
762
967
|
// e.g., childEquiv[selectedScenario] = "signature[0].selectedScenario"
|
|
763
|
-
|
|
968
|
+
// Handle array case (OR expressions) - use first element if array
|
|
969
|
+
const rawChildPropPath = childEquivalentSignatureVariables[rootVar];
|
|
970
|
+
const childPropPath = Array.isArray(rawChildPropPath)
|
|
971
|
+
? rawChildPropPath[0]
|
|
972
|
+
: rawChildPropPath;
|
|
764
973
|
|
|
765
974
|
if (!childPropPath) {
|
|
766
975
|
// No mapping found - this might be internal state, not a prop
|
|
@@ -773,7 +982,11 @@ function translateChildPathToParent(
|
|
|
773
982
|
|
|
774
983
|
// Look up parent's equivalence to find what value was passed to this prop
|
|
775
984
|
// e.g., parentEquiv["ChildName().signature[0].selectedScenario"] = "selectedScenario"
|
|
776
|
-
|
|
985
|
+
// Handle array case (OR expressions) - use first element if array
|
|
986
|
+
const rawParentValue = parentEquivalentSignatureVariables[fullChildPropPath];
|
|
987
|
+
const parentValue = Array.isArray(rawParentValue)
|
|
988
|
+
? rawParentValue[0]
|
|
989
|
+
: rawParentValue;
|
|
777
990
|
|
|
778
991
|
if (!parentValue) {
|
|
779
992
|
// No parent mapping found - log ALL parent keys that contain the childName
|
|
@@ -800,11 +1013,28 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
800
1013
|
fullToShortPathMap,
|
|
801
1014
|
childComponentData,
|
|
802
1015
|
derivedVariables,
|
|
1016
|
+
sourceEquivalencies,
|
|
803
1017
|
} = args;
|
|
804
1018
|
|
|
805
1019
|
const flows: ExecutionFlow[] = [];
|
|
806
1020
|
const seenFlowIds = new Set<string>();
|
|
807
1021
|
|
|
1022
|
+
console.log(
|
|
1023
|
+
`[genFlowsFromConditionals] INPUT: ${Object.keys(conditionalUsages).length} conditional paths, ${Object.keys(attributesMap).length} attributesMap entries, ${Object.keys(fullToShortPathMap).length} fullToShortPathMap entries, ${Object.keys(equivalentSignatureVariables).length} equivSigVars, ${compoundConditionals.length} compound conditionals`,
|
|
1024
|
+
);
|
|
1025
|
+
console.log(
|
|
1026
|
+
`[genFlowsFromConditionals] conditionalUsages keys: [${Object.keys(conditionalUsages).join(', ')}]`,
|
|
1027
|
+
);
|
|
1028
|
+
console.log(
|
|
1029
|
+
`[genFlowsFromConditionals] attributesMap keys: [${Object.keys(attributesMap).join(', ')}]`,
|
|
1030
|
+
);
|
|
1031
|
+
console.log(
|
|
1032
|
+
`[genFlowsFromConditionals] fullToShortPathMap: ${JSON.stringify(fullToShortPathMap)}`,
|
|
1033
|
+
);
|
|
1034
|
+
console.log(
|
|
1035
|
+
`[genFlowsFromConditionals] equivalentSignatureVariables: ${JSON.stringify(equivalentSignatureVariables)}`,
|
|
1036
|
+
);
|
|
1037
|
+
|
|
808
1038
|
// Track normalized resolved paths to prevent duplicate flows
|
|
809
1039
|
// This handles the case where we have usages for both:
|
|
810
1040
|
// - "hasNewerVersion" (short path from destructured variable)
|
|
@@ -822,9 +1052,16 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
822
1052
|
for (const usage of usages) {
|
|
823
1053
|
// Skip usages that are part of compound conditionals (handled separately)
|
|
824
1054
|
if (usage.chainId && compoundChainIds.has(usage.chainId)) {
|
|
1055
|
+
console.log(
|
|
1056
|
+
`[genFlowsFromConditionals] "${usage.path}" SKIP: part of compound conditional chain=${usage.chainId}`,
|
|
1057
|
+
);
|
|
825
1058
|
continue;
|
|
826
1059
|
}
|
|
827
1060
|
|
|
1061
|
+
console.log(
|
|
1062
|
+
`[genFlowsFromConditionals] --- Processing "${usage.path}" (type=${usage.conditionType}, negated=${usage.isNegated}, sourceDataPath="${usage.sourceDataPath ?? '(none)'}", derivedFrom=${usage.derivedFrom ? JSON.stringify(usage.derivedFrom) : 'none'})`,
|
|
1063
|
+
);
|
|
1064
|
+
|
|
828
1065
|
// First, try to use pre-computed sourceDataPath if available
|
|
829
1066
|
let resolvedPath: string | null = null;
|
|
830
1067
|
|
|
@@ -834,7 +1071,9 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
834
1071
|
// should become "useLoaderData<LoaderData>().functionCallReturnValue.entity.sha"
|
|
835
1072
|
// Returns null for malformed paths (e.g., chained function calls like fetch().json())
|
|
836
1073
|
const cleanedPath = cleanSourceDataPath(usage.sourceDataPath);
|
|
837
|
-
|
|
1074
|
+
console.log(
|
|
1075
|
+
`[genFlowsFromConditionals] "${usage.path}" cleanSourceDataPath("${usage.sourceDataPath}") → "${cleanedPath}"`,
|
|
1076
|
+
);
|
|
838
1077
|
if (cleanedPath) {
|
|
839
1078
|
// Verify the cleaned path exists in attributesMap
|
|
840
1079
|
const pathMatch = findInAttributesMapForPath(
|
|
@@ -842,6 +1081,9 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
842
1081
|
attributesMap,
|
|
843
1082
|
fullToShortPathMap,
|
|
844
1083
|
);
|
|
1084
|
+
console.log(
|
|
1085
|
+
`[genFlowsFromConditionals] "${usage.path}" findInAttributesMapForPath("${cleanedPath}") → ${pathMatch ? `"${pathMatch}"` : 'null (not found)'}`,
|
|
1086
|
+
);
|
|
845
1087
|
if (pathMatch) {
|
|
846
1088
|
resolvedPath = pathMatch;
|
|
847
1089
|
}
|
|
@@ -851,13 +1093,18 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
851
1093
|
|
|
852
1094
|
// Fall back to resolution via equivalentSignatureVariables
|
|
853
1095
|
if (!resolvedPath) {
|
|
1096
|
+
console.log(
|
|
1097
|
+
`[genFlowsFromConditionals] "${usage.path}" sourceDataPath resolution failed, trying resolvePathToControllable("${usage.path}")...`,
|
|
1098
|
+
);
|
|
854
1099
|
const resolution = resolvePathToControllable(
|
|
855
1100
|
usage.path,
|
|
856
1101
|
attributesMap,
|
|
857
1102
|
equivalentSignatureVariables,
|
|
858
1103
|
fullToShortPathMap,
|
|
859
1104
|
);
|
|
860
|
-
|
|
1105
|
+
console.log(
|
|
1106
|
+
`[genFlowsFromConditionals] "${usage.path}" resolvePathToControllable → isControllable=${resolution.isControllable}, resolvedPath="${resolution.resolvedPath ?? '(none)'}"`,
|
|
1107
|
+
);
|
|
861
1108
|
if (resolution.isControllable && resolution.resolvedPath) {
|
|
862
1109
|
resolvedPath = resolution.resolvedPath;
|
|
863
1110
|
}
|
|
@@ -869,7 +1116,9 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
869
1116
|
if (!resolvedPath && usage.derivedFrom) {
|
|
870
1117
|
const { operation, sourcePath, sourcePaths, comparedValue } =
|
|
871
1118
|
usage.derivedFrom;
|
|
872
|
-
|
|
1119
|
+
console.log(
|
|
1120
|
+
`[genFlowsFromConditionals] "${usage.path}" trying derivedFrom: operation=${operation}, sourcePath="${sourcePath ?? '(none)'}", sourcePaths=${sourcePaths ? JSON.stringify(sourcePaths) : '(none)'}, comparedValue="${comparedValue ?? '(none)'}"`,
|
|
1121
|
+
);
|
|
873
1122
|
// For single-source derivations (notNull, equals, etc.)
|
|
874
1123
|
if (sourcePath) {
|
|
875
1124
|
const resolution = resolvePathToControllable(
|
|
@@ -878,7 +1127,6 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
878
1127
|
equivalentSignatureVariables,
|
|
879
1128
|
fullToShortPathMap,
|
|
880
1129
|
);
|
|
881
|
-
|
|
882
1130
|
if (resolution.isControllable && resolution.resolvedPath) {
|
|
883
1131
|
resolvedPath = resolution.resolvedPath;
|
|
884
1132
|
}
|
|
@@ -1174,6 +1422,9 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1174
1422
|
|
|
1175
1423
|
if (!resolvedPath) {
|
|
1176
1424
|
// Path is not controllable - skip (no invalid flows possible)
|
|
1425
|
+
console.log(
|
|
1426
|
+
`[genFlowsFromConditionals] "${usage.path}" SKIP: not controllable (no resolvedPath after all attempts)`,
|
|
1427
|
+
);
|
|
1177
1428
|
continue;
|
|
1178
1429
|
}
|
|
1179
1430
|
|
|
@@ -1188,10 +1439,33 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1188
1439
|
// Skip if we've already generated flows for this normalized path
|
|
1189
1440
|
// This prevents duplicate flows when we have usages for both short and full paths
|
|
1190
1441
|
if (seenNormalizedPaths.has(normalizedPath)) {
|
|
1442
|
+
console.log(
|
|
1443
|
+
`[genFlowsFromConditionals] "${usage.path}" SKIP: duplicate normalizedPath="${normalizedPath}" (resolvedPath="${resolvedPath}")`,
|
|
1444
|
+
);
|
|
1191
1445
|
continue;
|
|
1192
1446
|
}
|
|
1193
1447
|
seenNormalizedPaths.add(normalizedPath);
|
|
1194
1448
|
|
|
1449
|
+
// Skip individual truthy/falsy flows on parent paths that have child data entries.
|
|
1450
|
+
// Lifecycle booleans (like isLoadingAuditData) traced to fetch(...).functionCallReturnValue
|
|
1451
|
+
// produce misleading truthy/falsy flows: "truthy" can't show loading (mock resolves instantly),
|
|
1452
|
+
// "falsy" tells the LLM to return null (breaking .json()). Compound flows with specific child
|
|
1453
|
+
// data requirements provide the correct mock guidance.
|
|
1454
|
+
if (
|
|
1455
|
+
usage.conditionType === 'truthiness' &&
|
|
1456
|
+
resolvedPath &&
|
|
1457
|
+
hasChildPathsInMap(resolvedPath, fullToShortPathMap)
|
|
1458
|
+
) {
|
|
1459
|
+
console.log(
|
|
1460
|
+
`[genFlowsFromConditionals] "${usage.path}" SKIP: parent path "${resolvedPath}" has child data paths — compound flows will handle this`,
|
|
1461
|
+
);
|
|
1462
|
+
continue;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
console.log(
|
|
1466
|
+
`[genFlowsFromConditionals] "${usage.path}" RESOLVED → resolvedPath="${resolvedPath}", normalizedPath="${normalizedPath}" — generating flows`,
|
|
1467
|
+
);
|
|
1468
|
+
|
|
1195
1469
|
// Generate flows for this controllable usage
|
|
1196
1470
|
const usageFlows = generateFlowsFromUsage(usage, resolvedPath);
|
|
1197
1471
|
|
|
@@ -1200,6 +1474,9 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1200
1474
|
if (!seenFlowIds.has(flow.id)) {
|
|
1201
1475
|
seenFlowIds.add(flow.id);
|
|
1202
1476
|
flows.push(flow);
|
|
1477
|
+
console.log(
|
|
1478
|
+
`[genFlowsFromConditionals] "${usage.path}" FLOW ADDED: id="${flow.id}", requiredValues=${JSON.stringify(flow.requiredValues.map((rv) => ({ attr: rv.attributePath, val: rv.value })))}`,
|
|
1479
|
+
);
|
|
1203
1480
|
}
|
|
1204
1481
|
}
|
|
1205
1482
|
}
|
|
@@ -1253,25 +1530,85 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1253
1530
|
// Use the first source's path for the resolvedPaths map (for ID generation)
|
|
1254
1531
|
resolvedPaths.set(condition.path, sources[0].path);
|
|
1255
1532
|
} else {
|
|
1256
|
-
// Derived variable
|
|
1257
|
-
|
|
1258
|
-
|
|
1533
|
+
// Derived variable expansion failed — try sourceDataPath fallback
|
|
1534
|
+
// This handles cases where the derivation chain goes through useMemo/useState
|
|
1535
|
+
// but the enriched sourceDataPath already traced to the actual data source
|
|
1536
|
+
const usageWithSource = usagesForPath?.find(
|
|
1537
|
+
(u) => u.sourceDataPath,
|
|
1538
|
+
);
|
|
1539
|
+
let derivedFallbackPath: string | null = null;
|
|
1540
|
+
|
|
1541
|
+
if (usageWithSource?.sourceDataPath) {
|
|
1542
|
+
const cleanedPath = cleanSourceDataPath(
|
|
1543
|
+
usageWithSource.sourceDataPath,
|
|
1544
|
+
);
|
|
1545
|
+
if (cleanedPath) {
|
|
1546
|
+
const pathMatch = findInAttributesMapForPath(
|
|
1547
|
+
cleanedPath,
|
|
1548
|
+
attributesMap,
|
|
1549
|
+
fullToShortPathMap,
|
|
1550
|
+
);
|
|
1551
|
+
if (pathMatch) {
|
|
1552
|
+
derivedFallbackPath = pathMatch;
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
if (derivedFallbackPath) {
|
|
1558
|
+
resolvedPaths.set(condition.path, derivedFallbackPath);
|
|
1559
|
+
console.log(
|
|
1560
|
+
`[genFlowsFromConditionals] COMPOUND "${condition.path}" derived expansion failed but sourceDataPath fallback resolved → "${derivedFallbackPath}"`,
|
|
1561
|
+
);
|
|
1562
|
+
} else {
|
|
1563
|
+
// Truly not controllable
|
|
1564
|
+
console.log(
|
|
1565
|
+
`[genFlowsFromConditionals] COMPOUND "${condition.path}" derived but no controllable sources and no sourceDataPath fallback → NOT controllable`,
|
|
1566
|
+
);
|
|
1567
|
+
allControllable = false;
|
|
1568
|
+
break;
|
|
1569
|
+
}
|
|
1259
1570
|
}
|
|
1260
1571
|
} else {
|
|
1261
1572
|
// Not a derived variable - resolve directly
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
attributesMap,
|
|
1265
|
-
equivalentSignatureVariables,
|
|
1266
|
-
fullToShortPathMap,
|
|
1267
|
-
);
|
|
1573
|
+
// First try sourceDataPath from the usage (same as individual processing)
|
|
1574
|
+
let compoundResolvedPath: string | null = null;
|
|
1268
1575
|
|
|
1269
|
-
|
|
1576
|
+
const usageWithSource = usagesForPath?.find((u) => u.sourceDataPath);
|
|
1577
|
+
if (usageWithSource?.sourceDataPath) {
|
|
1578
|
+
const cleanedPath = cleanSourceDataPath(
|
|
1579
|
+
usageWithSource.sourceDataPath,
|
|
1580
|
+
);
|
|
1581
|
+
if (cleanedPath) {
|
|
1582
|
+
const pathMatch = findInAttributesMapForPath(
|
|
1583
|
+
cleanedPath,
|
|
1584
|
+
attributesMap,
|
|
1585
|
+
fullToShortPathMap,
|
|
1586
|
+
);
|
|
1587
|
+
if (pathMatch) {
|
|
1588
|
+
compoundResolvedPath = pathMatch;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
if (!compoundResolvedPath) {
|
|
1594
|
+
const resolution = resolvePathToControllable(
|
|
1595
|
+
condition.path,
|
|
1596
|
+
attributesMap,
|
|
1597
|
+
equivalentSignatureVariables,
|
|
1598
|
+
fullToShortPathMap,
|
|
1599
|
+
);
|
|
1600
|
+
|
|
1601
|
+
if (resolution.isControllable && resolution.resolvedPath) {
|
|
1602
|
+
compoundResolvedPath = resolution.resolvedPath;
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
if (!compoundResolvedPath) {
|
|
1270
1607
|
allControllable = false;
|
|
1271
1608
|
break;
|
|
1272
1609
|
}
|
|
1273
1610
|
|
|
1274
|
-
resolvedPaths.set(condition.path,
|
|
1611
|
+
resolvedPaths.set(condition.path, compoundResolvedPath);
|
|
1275
1612
|
}
|
|
1276
1613
|
}
|
|
1277
1614
|
|
|
@@ -1349,7 +1686,14 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1349
1686
|
condition.requiredValue?.toString() ??
|
|
1350
1687
|
condition.comparedValues?.[0] ??
|
|
1351
1688
|
'truthy';
|
|
1352
|
-
|
|
1689
|
+
const op = condition.comparisonOperator;
|
|
1690
|
+
if (op === '>' || op === '>=') {
|
|
1691
|
+
comparison = 'length>';
|
|
1692
|
+
} else if (op === '<' || op === '<=') {
|
|
1693
|
+
comparison = 'length<';
|
|
1694
|
+
} else {
|
|
1695
|
+
comparison = 'equals';
|
|
1696
|
+
}
|
|
1353
1697
|
}
|
|
1354
1698
|
|
|
1355
1699
|
requiredValues.push({
|
|
@@ -1362,24 +1706,31 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1362
1706
|
}
|
|
1363
1707
|
}
|
|
1364
1708
|
|
|
1365
|
-
|
|
1709
|
+
// Remove contradictory "falsy" values where a child path requires data
|
|
1710
|
+
const cleanedValues = removeContradictoryFalsyValues(requiredValues);
|
|
1711
|
+
|
|
1712
|
+
if (cleanedValues.length > 0) {
|
|
1366
1713
|
const impact: ExecutionFlow['impact'] =
|
|
1367
1714
|
compound.controlsJsxRendering ? 'high' : 'medium';
|
|
1368
1715
|
|
|
1369
|
-
// Generate a combined ID from all paths
|
|
1370
|
-
const pathParts =
|
|
1716
|
+
// Generate a combined ID from all paths + values
|
|
1717
|
+
const pathParts = cleanedValues
|
|
1371
1718
|
.map((rv) => {
|
|
1372
1719
|
const name = generateNameFromPath(rv.attributePath);
|
|
1373
|
-
|
|
1720
|
+
const suffix =
|
|
1721
|
+
rv.comparison === 'truthy' || rv.comparison === 'falsy'
|
|
1722
|
+
? `-${rv.comparison}`
|
|
1723
|
+
: `-${rv.comparison}-${rv.value}`;
|
|
1724
|
+
return name.toLowerCase().replace(/\s+/g, '-') + suffix;
|
|
1374
1725
|
})
|
|
1375
1726
|
.join('-and-');
|
|
1376
1727
|
|
|
1377
1728
|
const compoundFlow: ExecutionFlow = {
|
|
1378
|
-
id: `${pathParts}
|
|
1379
|
-
name: generateNameFromPath(
|
|
1380
|
-
description: `When ${
|
|
1729
|
+
id: `${pathParts}`,
|
|
1730
|
+
name: generateNameFromPath(cleanedValues[0].attributePath),
|
|
1731
|
+
description: `When ${cleanedValues.map((rv) => describeRequiredValue(rv)).join(' and ')}`,
|
|
1381
1732
|
impact,
|
|
1382
|
-
requiredValues,
|
|
1733
|
+
requiredValues: cleanedValues,
|
|
1383
1734
|
sourceLocation: compound.sourceLocation,
|
|
1384
1735
|
};
|
|
1385
1736
|
|
|
@@ -1596,9 +1947,6 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1596
1947
|
childData.conditionalUsages,
|
|
1597
1948
|
)) {
|
|
1598
1949
|
for (const usage of usages) {
|
|
1599
|
-
// Debug logging (disabled - set to true for troubleshooting child flow resolution)
|
|
1600
|
-
const shouldDebugChild = false;
|
|
1601
|
-
|
|
1602
1950
|
// Skip usages that are part of compound conditionals (handled separately)
|
|
1603
1951
|
// Fix 33: Only skip if the chainId is in the child's compound conditionals
|
|
1604
1952
|
if (usage.chainId && childCompoundChainIds.has(usage.chainId)) {
|
|
@@ -1613,18 +1961,6 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1613
1961
|
childPath = usage.derivedFrom.sourcePath;
|
|
1614
1962
|
}
|
|
1615
1963
|
|
|
1616
|
-
if (shouldDebugChild) {
|
|
1617
|
-
console.log(
|
|
1618
|
-
`[DEBUG CHILD ${childName}] Processing usage path: ${usage.path}`,
|
|
1619
|
-
);
|
|
1620
|
-
console.log(
|
|
1621
|
-
`[DEBUG CHILD ${childName}] childPath (after derivedFrom): ${childPath}`,
|
|
1622
|
-
);
|
|
1623
|
-
console.log(
|
|
1624
|
-
`[DEBUG CHILD ${childName}] sourceDataPath: ${usage.sourceDataPath}`,
|
|
1625
|
-
);
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
1964
|
// Translate the child path to a parent path
|
|
1629
1965
|
let translatedPath = translateChildPathToParent(
|
|
1630
1966
|
childPath,
|
|
@@ -1633,12 +1969,6 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1633
1969
|
childName,
|
|
1634
1970
|
);
|
|
1635
1971
|
|
|
1636
|
-
if (shouldDebugChild) {
|
|
1637
|
-
console.log(
|
|
1638
|
-
`[DEBUG CHILD ${childName}] translatedPath (from translateChildPathToParent): ${translatedPath}`,
|
|
1639
|
-
);
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
1972
|
// If translation failed but we have sourceDataPath, try to extract the prop path from it
|
|
1643
1973
|
// sourceDataPath format: "ChildName.signature[n].propPath.rest" → extract "propPath.rest"
|
|
1644
1974
|
if (!translatedPath && usage.sourceDataPath) {
|
|
@@ -1647,21 +1977,11 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1647
1977
|
);
|
|
1648
1978
|
if (signatureMatch) {
|
|
1649
1979
|
translatedPath = signatureMatch[1];
|
|
1650
|
-
if (shouldDebugChild) {
|
|
1651
|
-
console.log(
|
|
1652
|
-
`[DEBUG CHILD ${childName}] translatedPath (from sourceDataPath regex): ${translatedPath}`,
|
|
1653
|
-
);
|
|
1654
|
-
}
|
|
1655
1980
|
}
|
|
1656
1981
|
}
|
|
1657
1982
|
|
|
1658
1983
|
if (!translatedPath) {
|
|
1659
1984
|
// Could not translate - skip this usage
|
|
1660
|
-
if (shouldDebugChild) {
|
|
1661
|
-
console.log(
|
|
1662
|
-
`[DEBUG CHILD ${childName}] SKIPPED - no translation found`,
|
|
1663
|
-
);
|
|
1664
|
-
}
|
|
1665
1985
|
continue;
|
|
1666
1986
|
}
|
|
1667
1987
|
|
|
@@ -1674,21 +1994,6 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1674
1994
|
fullToShortPathMap,
|
|
1675
1995
|
);
|
|
1676
1996
|
|
|
1677
|
-
if (shouldDebugChild) {
|
|
1678
|
-
console.log(
|
|
1679
|
-
`[DEBUG CHILD ${childName}] resolvePathToControllable result:`,
|
|
1680
|
-
);
|
|
1681
|
-
console.log(
|
|
1682
|
-
`[DEBUG CHILD ${childName}] isControllable: ${resolution.isControllable}`,
|
|
1683
|
-
);
|
|
1684
|
-
console.log(
|
|
1685
|
-
`[DEBUG CHILD ${childName}] resolvedPath: ${resolution.resolvedPath}`,
|
|
1686
|
-
);
|
|
1687
|
-
console.log(
|
|
1688
|
-
`[DEBUG CHILD ${childName}] chain: ${resolution.resolutionChain.join(' -> ')}`,
|
|
1689
|
-
);
|
|
1690
|
-
}
|
|
1691
|
-
|
|
1692
1997
|
// Only create flows for controllable paths (whitelist approach).
|
|
1693
1998
|
// If the path doesn't resolve to something in attributesMap, skip it.
|
|
1694
1999
|
// This prevents creating flows for useState values which are not
|
|
@@ -1726,32 +2031,11 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1726
2031
|
}
|
|
1727
2032
|
}
|
|
1728
2033
|
|
|
1729
|
-
if (shouldDebugChild) {
|
|
1730
|
-
console.log(
|
|
1731
|
-
`[DEBUG CHILD ${childName}] useState fallback: looking for URL param`,
|
|
1732
|
-
);
|
|
1733
|
-
console.log(
|
|
1734
|
-
`[DEBUG CHILD ${childName}] useStatePattern: ${useStatePattern}`,
|
|
1735
|
-
);
|
|
1736
|
-
console.log(
|
|
1737
|
-
`[DEBUG CHILD ${childName}] useStateVarName: ${useStateVarName}`,
|
|
1738
|
-
);
|
|
1739
|
-
}
|
|
1740
|
-
|
|
1741
2034
|
if (useStateVarName) {
|
|
1742
2035
|
// Look for a related URL param like "varNameFromUrl"
|
|
1743
2036
|
const urlParamName = `${useStateVarName}FromUrl`;
|
|
1744
2037
|
const urlParamPath = equivalentSignatureVariables[urlParamName];
|
|
1745
2038
|
|
|
1746
|
-
if (shouldDebugChild) {
|
|
1747
|
-
console.log(
|
|
1748
|
-
`[DEBUG CHILD ${childName}] urlParamName: ${urlParamName}`,
|
|
1749
|
-
);
|
|
1750
|
-
console.log(
|
|
1751
|
-
`[DEBUG CHILD ${childName}] urlParamPath: ${urlParamPath}`,
|
|
1752
|
-
);
|
|
1753
|
-
}
|
|
1754
|
-
|
|
1755
2039
|
if (urlParamPath) {
|
|
1756
2040
|
// For useState values initialized from URL params, use the
|
|
1757
2041
|
// URL param variable name directly (e.g., "viewModeFromUrl")
|
|
@@ -1762,10 +2046,62 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1762
2046
|
// The flow will use the URL param name as the attributePath,
|
|
1763
2047
|
// which gets properly resolved when generating mock data.
|
|
1764
2048
|
resolvedPath = urlParamName;
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
// Fallback 2: Try sourceEquivalencies to find the actual data source
|
|
2054
|
+
// This handles the case where props flow through useState but originate
|
|
2055
|
+
// from a mockable data source (e.g., API call, fetcher).
|
|
2056
|
+
//
|
|
2057
|
+
// Example: WorkoutsView receives `workouts` prop which in parent is stored
|
|
2058
|
+
// in useState, but ultimately comes from a Supabase query.
|
|
2059
|
+
// sourceEquivalencies tells us: "WorkoutsView().signature[0].workouts" → "createClient()...data"
|
|
2060
|
+
if (!resolvedPath && sourceEquivalencies) {
|
|
2061
|
+
// Build the child prop path to look up in sourceEquivalencies
|
|
2062
|
+
// Format: "ChildName().signature[0].propName"
|
|
2063
|
+
// First, find what prop this child path maps to
|
|
2064
|
+
let childPropName: string | null = null;
|
|
2065
|
+
for (const [varName, varPath] of Object.entries(
|
|
2066
|
+
childData.equivalentSignatureVariables,
|
|
2067
|
+
)) {
|
|
2068
|
+
// Check if childPath starts with this variable name
|
|
2069
|
+
// e.g., childPath = "workouts.length", varName = "workouts", varPath = "signature[0].workouts"
|
|
2070
|
+
if (
|
|
2071
|
+
childPath === varName ||
|
|
2072
|
+
childPath.startsWith(`${varName}.`)
|
|
2073
|
+
) {
|
|
2074
|
+
childPropName = varName;
|
|
2075
|
+
break;
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
if (childPropName) {
|
|
2080
|
+
// Build the full sourceEquivalencies key
|
|
2081
|
+
const sourceEquivKey = `${childName}().signature[0].${childPropName}`;
|
|
2082
|
+
|
|
2083
|
+
const sourceEquivEntry = sourceEquivalencies[sourceEquivKey];
|
|
2084
|
+
if (sourceEquivEntry && sourceEquivEntry.length > 0) {
|
|
2085
|
+
const dataSourcePath = sourceEquivEntry[0].schemaPath;
|
|
2086
|
+
|
|
2087
|
+
// Check if this data source path is controllable
|
|
2088
|
+
const dataSourceResolution = resolvePathToControllable(
|
|
2089
|
+
dataSourcePath,
|
|
2090
|
+
attributesMap,
|
|
2091
|
+
equivalentSignatureVariables,
|
|
2092
|
+
fullToShortPathMap,
|
|
2093
|
+
);
|
|
2094
|
+
|
|
2095
|
+
if (
|
|
2096
|
+
dataSourceResolution.isControllable &&
|
|
2097
|
+
dataSourceResolution.resolvedPath
|
|
2098
|
+
) {
|
|
2099
|
+
// Preserve any suffix from the child path
|
|
2100
|
+
// e.g., childPath = "workouts.length" → suffix = ".length"
|
|
2101
|
+
const suffix = childPath.startsWith(`${childPropName}.`)
|
|
2102
|
+
? childPath.slice(childPropName.length)
|
|
2103
|
+
: '';
|
|
2104
|
+
resolvedPath = dataSourceResolution.resolvedPath + suffix;
|
|
1769
2105
|
}
|
|
1770
2106
|
}
|
|
1771
2107
|
}
|
|
@@ -1773,11 +2109,6 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1773
2109
|
|
|
1774
2110
|
// If still not resolved after fallback, skip
|
|
1775
2111
|
if (!resolvedPath) {
|
|
1776
|
-
if (shouldDebugChild) {
|
|
1777
|
-
console.log(
|
|
1778
|
-
`[DEBUG CHILD ${childName}] SKIPPED - path not controllable`,
|
|
1779
|
-
);
|
|
1780
|
-
}
|
|
1781
2112
|
continue;
|
|
1782
2113
|
}
|
|
1783
2114
|
}
|
|
@@ -1789,11 +2120,6 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1789
2120
|
);
|
|
1790
2121
|
|
|
1791
2122
|
if (seenNormalizedPaths.has(normalizedPath)) {
|
|
1792
|
-
if (shouldDebugChild) {
|
|
1793
|
-
console.log(
|
|
1794
|
-
`[DEBUG CHILD ${childName}] SKIPPED - duplicate normalized path: ${normalizedPath}`,
|
|
1795
|
-
);
|
|
1796
|
-
}
|
|
1797
2123
|
continue;
|
|
1798
2124
|
}
|
|
1799
2125
|
seenNormalizedPaths.add(normalizedPath);
|
|
@@ -1810,17 +2136,6 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1810
2136
|
resolvedPath,
|
|
1811
2137
|
);
|
|
1812
2138
|
|
|
1813
|
-
if (shouldDebugChild) {
|
|
1814
|
-
console.log(
|
|
1815
|
-
`[DEBUG CHILD ${childName}] GENERATING ${usageFlows.length} flows with resolvedPath: ${resolvedPath}`,
|
|
1816
|
-
);
|
|
1817
|
-
for (const f of usageFlows) {
|
|
1818
|
-
console.log(
|
|
1819
|
-
`[DEBUG CHILD ${childName}] - Flow ID: ${f.id}, path: ${f.requiredValues[0]?.attributePath}`,
|
|
1820
|
-
);
|
|
1821
|
-
}
|
|
1822
|
-
}
|
|
1823
|
-
|
|
1824
2139
|
// Add gating conditions to each flow
|
|
1825
2140
|
for (const flow of usageFlows) {
|
|
1826
2141
|
// Add gating required values to the flow
|
|
@@ -1970,8 +2285,200 @@ export default function generateExecutionFlowsFromConditionals(
|
|
|
1970
2285
|
}
|
|
1971
2286
|
}
|
|
1972
2287
|
}
|
|
2288
|
+
|
|
2289
|
+
// Process child's jsxRenderingUsages (array.map flows)
|
|
2290
|
+
// This generates array variation flows (empty, few, many) for arrays rendered in child
|
|
2291
|
+
if (childData.jsxRenderingUsages) {
|
|
2292
|
+
for (const jsxUsage of childData.jsxRenderingUsages) {
|
|
2293
|
+
// Translate the child path to a parent path
|
|
2294
|
+
const translatedPath = translateChildPathToParent(
|
|
2295
|
+
jsxUsage.path,
|
|
2296
|
+
childData.equivalentSignatureVariables,
|
|
2297
|
+
equivalentSignatureVariables,
|
|
2298
|
+
childName,
|
|
2299
|
+
);
|
|
2300
|
+
|
|
2301
|
+
if (!translatedPath) {
|
|
2302
|
+
continue;
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
// Resolve to controllable path in parent context
|
|
2306
|
+
const resolution = resolvePathToControllable(
|
|
2307
|
+
translatedPath,
|
|
2308
|
+
attributesMap,
|
|
2309
|
+
equivalentSignatureVariables,
|
|
2310
|
+
fullToShortPathMap,
|
|
2311
|
+
);
|
|
2312
|
+
|
|
2313
|
+
let resolvedPath = resolution.resolvedPath;
|
|
2314
|
+
|
|
2315
|
+
// Try sourceEquivalencies fallback if not controllable
|
|
2316
|
+
if (!resolution.isControllable || !resolvedPath) {
|
|
2317
|
+
if (sourceEquivalencies) {
|
|
2318
|
+
// Build the sourceEquivalencies key
|
|
2319
|
+
// The child path (e.g., "workouts") maps to a prop path (e.g., "signature[0].workouts")
|
|
2320
|
+
let childPropName: string | null = null;
|
|
2321
|
+
for (const [varName, varPath] of Object.entries(
|
|
2322
|
+
childData.equivalentSignatureVariables,
|
|
2323
|
+
)) {
|
|
2324
|
+
if (
|
|
2325
|
+
jsxUsage.path === varName ||
|
|
2326
|
+
jsxUsage.path.startsWith(`${varName}.`)
|
|
2327
|
+
) {
|
|
2328
|
+
childPropName = varName;
|
|
2329
|
+
break;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
if (childPropName) {
|
|
2334
|
+
const sourceEquivKey = `${childName}().signature[0].${childPropName}`;
|
|
2335
|
+
const sourceEquivEntry = sourceEquivalencies[sourceEquivKey];
|
|
2336
|
+
|
|
2337
|
+
if (sourceEquivEntry && sourceEquivEntry.length > 0) {
|
|
2338
|
+
const dataSourcePath = sourceEquivEntry[0].schemaPath;
|
|
2339
|
+
|
|
2340
|
+
const dataSourceResolution = resolvePathToControllable(
|
|
2341
|
+
dataSourcePath,
|
|
2342
|
+
attributesMap,
|
|
2343
|
+
equivalentSignatureVariables,
|
|
2344
|
+
fullToShortPathMap,
|
|
2345
|
+
);
|
|
2346
|
+
|
|
2347
|
+
if (
|
|
2348
|
+
dataSourceResolution.isControllable &&
|
|
2349
|
+
dataSourceResolution.resolvedPath
|
|
2350
|
+
) {
|
|
2351
|
+
resolvedPath = dataSourceResolution.resolvedPath;
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
if (!resolvedPath) {
|
|
2359
|
+
continue;
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
// Check for duplicates
|
|
2363
|
+
const normalizedPath = normalizePathForDeduplication(
|
|
2364
|
+
resolvedPath,
|
|
2365
|
+
fullToShortPathMap,
|
|
2366
|
+
);
|
|
2367
|
+
const dedupeKey = `${normalizedPath}:${jsxUsage.renderingType}`;
|
|
2368
|
+
if (seenNormalizedPaths.has(dedupeKey)) {
|
|
2369
|
+
continue;
|
|
2370
|
+
}
|
|
2371
|
+
seenNormalizedPaths.add(dedupeKey);
|
|
2372
|
+
|
|
2373
|
+
// Generate array variation flows for array-map rendering
|
|
2374
|
+
if (jsxUsage.renderingType === 'array-map') {
|
|
2375
|
+
const baseName = generateNameFromPath(resolvedPath);
|
|
2376
|
+
const pathSlug = pathToSlug(resolvedPath);
|
|
2377
|
+
const exclusiveGroup = `array-length-${pathSlug}`;
|
|
2378
|
+
|
|
2379
|
+
// Empty array flow
|
|
2380
|
+
const emptyFlow: ExecutionFlow = {
|
|
2381
|
+
id: `${pathSlug}-empty-array`,
|
|
2382
|
+
name: `${baseName} Empty`,
|
|
2383
|
+
description: `When ${baseName.toLowerCase()} array is empty`,
|
|
2384
|
+
requiredValues: [
|
|
2385
|
+
{
|
|
2386
|
+
attributePath: resolvedPath,
|
|
2387
|
+
value: '0',
|
|
2388
|
+
comparison: 'length<',
|
|
2389
|
+
valueType: 'array',
|
|
2390
|
+
},
|
|
2391
|
+
...gatingRequiredValues,
|
|
2392
|
+
],
|
|
2393
|
+
impact: 'medium',
|
|
2394
|
+
exclusiveGroup,
|
|
2395
|
+
sourceLocation: jsxUsage.sourceLocation
|
|
2396
|
+
? {
|
|
2397
|
+
lineNumber: jsxUsage.sourceLocation.lineNumber,
|
|
2398
|
+
column: jsxUsage.sourceLocation.column,
|
|
2399
|
+
}
|
|
2400
|
+
: undefined,
|
|
2401
|
+
codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
|
|
2402
|
+
};
|
|
2403
|
+
|
|
2404
|
+
if (!seenFlowIds.has(emptyFlow.id)) {
|
|
2405
|
+
seenFlowIds.add(emptyFlow.id);
|
|
2406
|
+
flows.push(emptyFlow);
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
// Few items flow (1-3)
|
|
2410
|
+
const fewFlow: ExecutionFlow = {
|
|
2411
|
+
id: `${pathSlug}-few-items`,
|
|
2412
|
+
name: `${baseName} Few Items`,
|
|
2413
|
+
description: `When ${baseName.toLowerCase()} array has 1-3 items`,
|
|
2414
|
+
requiredValues: [
|
|
2415
|
+
{
|
|
2416
|
+
attributePath: resolvedPath,
|
|
2417
|
+
value: '3',
|
|
2418
|
+
comparison: 'length<',
|
|
2419
|
+
valueType: 'array',
|
|
2420
|
+
},
|
|
2421
|
+
...gatingRequiredValues,
|
|
2422
|
+
],
|
|
2423
|
+
impact: 'low',
|
|
2424
|
+
exclusiveGroup,
|
|
2425
|
+
sourceLocation: jsxUsage.sourceLocation
|
|
2426
|
+
? {
|
|
2427
|
+
lineNumber: jsxUsage.sourceLocation.lineNumber,
|
|
2428
|
+
column: jsxUsage.sourceLocation.column,
|
|
2429
|
+
}
|
|
2430
|
+
: undefined,
|
|
2431
|
+
codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
|
|
2432
|
+
};
|
|
2433
|
+
|
|
2434
|
+
if (!seenFlowIds.has(fewFlow.id)) {
|
|
2435
|
+
seenFlowIds.add(fewFlow.id);
|
|
2436
|
+
flows.push(fewFlow);
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
// Many items flow (10+)
|
|
2440
|
+
const manyFlow: ExecutionFlow = {
|
|
2441
|
+
id: `${pathSlug}-many-items`,
|
|
2442
|
+
name: `${baseName} Many Items`,
|
|
2443
|
+
description: `When ${baseName.toLowerCase()} array has many items`,
|
|
2444
|
+
requiredValues: [
|
|
2445
|
+
{
|
|
2446
|
+
attributePath: resolvedPath,
|
|
2447
|
+
value: '10',
|
|
2448
|
+
comparison: 'length>',
|
|
2449
|
+
valueType: 'array',
|
|
2450
|
+
},
|
|
2451
|
+
...gatingRequiredValues,
|
|
2452
|
+
],
|
|
2453
|
+
impact: 'low',
|
|
2454
|
+
exclusiveGroup,
|
|
2455
|
+
sourceLocation: jsxUsage.sourceLocation
|
|
2456
|
+
? {
|
|
2457
|
+
lineNumber: jsxUsage.sourceLocation.lineNumber,
|
|
2458
|
+
column: jsxUsage.sourceLocation.column,
|
|
2459
|
+
}
|
|
2460
|
+
: undefined,
|
|
2461
|
+
codeSnippet: jsxUsage.sourceLocation?.codeSnippet,
|
|
2462
|
+
};
|
|
2463
|
+
|
|
2464
|
+
if (!seenFlowIds.has(manyFlow.id)) {
|
|
2465
|
+
seenFlowIds.add(manyFlow.id);
|
|
2466
|
+
flows.push(manyFlow);
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
1973
2471
|
}
|
|
1974
2472
|
}
|
|
1975
2473
|
|
|
2474
|
+
console.log(
|
|
2475
|
+
`[genFlowsFromConditionals] RESULT: ${flows.length} total flows generated`,
|
|
2476
|
+
);
|
|
2477
|
+
for (const flow of flows) {
|
|
2478
|
+
console.log(
|
|
2479
|
+
`[genFlowsFromConditionals] FLOW: id="${flow.id}" requiredValues=[${flow.requiredValues.map((rv) => `${rv.attributePath}=${rv.value}`).join(', ')}]`,
|
|
2480
|
+
);
|
|
2481
|
+
}
|
|
2482
|
+
|
|
1976
2483
|
return flows;
|
|
1977
2484
|
}
|