@codeyam/codeyam-cli 0.1.0-staging.09652b8 → 0.1.0-staging.28f73cf
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 +7 -6
- package/analyzer-template/packages/ai/index.ts +2 -0
- package/analyzer-template/packages/ai/package.json +2 -2
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +24 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +14 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +1402 -546
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.ts +138 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +139 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/DebugTracer.ts +224 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/PathManager.ts +203 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/README.md +294 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +161 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.ts +235 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +2 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/selectBestValue.ts +70 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.ts +113 -0
- package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +36 -0
- package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +32 -8
- package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +27 -6
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +42 -4
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +39 -0
- package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +18 -6
- package/analyzer-template/packages/analyze/src/lib/asts/nodes/index.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +8 -10
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +6 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +8 -6
- package/analyzer-template/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.ts +5 -13
- package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +34 -15
- package/analyzer-template/packages/analyze/src/lib/files/analyzeEntity.ts +17 -3
- package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +35 -16
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +7 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +9 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +6 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +9 -1
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.d.ts +23 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.d.ts.map +1 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.js +30 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.js.map +1 -0
- package/analyzer-template/packages/aws/package.json +5 -4
- package/analyzer-template/packages/aws/s3/index.ts +4 -0
- package/analyzer-template/packages/aws/src/lib/s3/getPresignedUrl.ts +62 -0
- package/analyzer-template/packages/generate/src/lib/scenarioComponent.ts +6 -3
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.js +5 -3
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.js.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.d.ts +2 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.js +3 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.js.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tableRelations.d.ts +2 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tableRelations.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.d.ts +37 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.js +27 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.js.map +1 -0
- package/analyzer-template/packages/github/dist/utils/index.d.ts +1 -0
- package/analyzer-template/packages/github/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/index.js +1 -0
- package/analyzer-template/packages/github/dist/utils/index.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.d.ts +25 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.js +40 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.js.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/supabase/src/lib/kysely/db.ts +6 -0
- package/analyzer-template/packages/supabase/src/lib/kysely/tableRelations.ts +3 -0
- package/analyzer-template/packages/supabase/src/lib/kysely/tables/debugReportsTable.ts +61 -0
- package/analyzer-template/packages/utils/dist/utils/index.d.ts +1 -0
- package/analyzer-template/packages/utils/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/index.js +1 -0
- package/analyzer-template/packages/utils/dist/utils/index.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.d.ts +25 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.d.ts.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.js +40 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.js.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/utils/index.ts +1 -0
- package/analyzer-template/packages/utils/src/lib/Semaphore.ts +42 -0
- package/analyzer-template/packages/utils/src/lib/frameworks/getRemixRoutePath.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.ts +1 -0
- package/analyzer-template/project/constructMockCode.ts +170 -6
- package/analyzer-template/project/reconcileMockDataKeys.ts +13 -0
- package/analyzer-template/project/start.ts +1 -11
- package/analyzer-template/project/writeMockDataTsx.ts +32 -1
- package/analyzer-template/project/writeScenarioComponents.ts +164 -18
- package/analyzer-template/project/writeUniversalMocks.ts +66 -8
- package/background/src/lib/virtualized/project/constructMockCode.js +158 -7
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +12 -0
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
- package/background/src/lib/virtualized/project/start.js +1 -8
- package/background/src/lib/virtualized/project/start.js.map +1 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +25 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +129 -17
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeUniversalMocks.js +56 -7
- package/background/src/lib/virtualized/project/writeUniversalMocks.js.map +1 -1
- package/codeyam-cli/src/cli.js +6 -0
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/codeyam-cli.js +0 -0
- package/codeyam-cli/src/commands/debug.js +221 -0
- package/codeyam-cli/src/commands/debug.js.map +1 -0
- package/codeyam-cli/src/commands/report.js +102 -0
- package/codeyam-cli/src/commands/report.js.map +1 -0
- package/codeyam-cli/src/commands/setup-sandbox.js +164 -0
- package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/cleanupAnalysisFiles.test.js +6 -6
- package/codeyam-cli/src/utils/__tests__/cleanupAnalysisFiles.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +8 -0
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
- package/codeyam-cli/src/utils/analyzer.js +30 -0
- package/codeyam-cli/src/utils/analyzer.js.map +1 -1
- package/codeyam-cli/src/utils/cleanupAnalysisFiles.js +2 -2
- package/codeyam-cli/src/utils/cleanupAnalysisFiles.js.map +1 -1
- package/codeyam-cli/src/utils/generateReport.js +219 -0
- package/codeyam-cli/src/utils/generateReport.js.map +1 -0
- package/codeyam-cli/src/utils/install-skills.js +7 -0
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/queue/__tests__/job.pidTracking.test.js +1 -0
- package/codeyam-cli/src/utils/queue/__tests__/job.pidTracking.test.js.map +1 -1
- package/codeyam-cli/src/utils/queue/job.js +5 -1
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +4 -0
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js +50 -2
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-D5ZHFomX.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CDnfNKKQ.js → InteractivePreview-XDSzQLOY.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-DUS-3h7I.js → LibraryFunctionPreview-BYVx9KFp.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-TJzDQku1.js → LogViewer-CRcT5fOZ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-BORLgi0X.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-BgdlWM6p.js → SafeScreenshot-Bual6h18.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bi-YUMa-.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-4D2vLLJz.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/_index-BC200mfN.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-CxvZPkCv.js +10 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.generate-report-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/chart-column-B8fb6wnw.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{chunk-WWGJGFF6-DvL0YqDJ.js → chunk-WWGJGFF6-De6i8FUT.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/circle-alert-IdsgAK39.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-BACUUf75.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/clock-vWeoCemX.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CS7XDrKv.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DIOEw_3i.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-3bYjyojg.js → entity._sha._-8Els_3Wb.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-DtfwpN9J.js → entity._sha_.create-scenario-C3FZJx1w.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-YJz_igar.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/entityStatus-BEqj2qBy.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-DiP0q291.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/file-text-LM0mgxXE.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/files-Dxh9CcaV.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{git-WoKohOtW.js → git-BXmqrWCH.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/globals-BGS74ED-.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-Vvbl94Xc.js → index-D-zYbzFZ.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-BXPKbHEb.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/manifest-1af162d4.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-DB7VgjCY.js +16 -0
- package/codeyam-cli/src/webserver/build/client/assets/settings-5zF_GOcS.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{settings-LuiJ1UIm.js → settings-Dc4MlMpK.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-BQ-02-jB.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-D7k-ArFa.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-CpUcCv1V.js → useLastLogLine-AlhS7g5F.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-Ddo4UQv7.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/zap-_jw-9DCp.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/{index-DzbqTxoN.js → index-D4JpXSIO.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-vwbN7n65.js +169 -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-setup-skill.md +65 -85
- package/codeyam-cli/templates/debug-command.md +125 -0
- package/package.json +4 -6
- package/packages/ai/index.js +1 -1
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/analyzeScope.js +13 -0
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +12 -0
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1023 -405
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.js +137 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +112 -0
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/DebugTracer.js +176 -0
- package/packages/ai/src/lib/dataStructure/helpers/DebugTracer.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/PathManager.js +178 -0
- package/packages/ai/src/lib/dataStructure/helpers/PathManager.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +138 -0
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.js +199 -0
- package/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +2 -0
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/selectBestValue.js +62 -0
- package/packages/ai/src/lib/dataStructure/helpers/selectBestValue.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.js +90 -0
- package/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.js.map +1 -0
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +22 -0
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateEntityKeyAttributes.js +32 -8
- package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js +13 -8
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +36 -3
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
- package/packages/ai/src/lib/worker/SerializableDataStructure.js +7 -0
- package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/FileAnalyzer.js +17 -5
- package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/asts/nodes/index.js +2 -1
- package/packages/analyze/src/lib/asts/nodes/index.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +6 -8
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +5 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +8 -2
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js +5 -8
- package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeChange.js +21 -9
- package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeEntity.js +10 -4
- package/packages/analyze/src/lib/files/analyzeEntity.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeInitial.js +21 -9
- package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +6 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +9 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +5 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +9 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
- package/packages/generate/src/lib/scenarioComponent.js +5 -3
- package/packages/generate/src/lib/scenarioComponent.js.map +1 -1
- package/packages/supabase/src/lib/kysely/db.js +3 -0
- package/packages/supabase/src/lib/kysely/db.js.map +1 -1
- package/packages/supabase/src/lib/kysely/tables/debugReportsTable.js +27 -0
- package/packages/supabase/src/lib/kysely/tables/debugReportsTable.js.map +1 -0
- package/packages/utils/index.js +1 -0
- package/packages/utils/index.js.map +1 -1
- package/packages/utils/src/lib/Semaphore.js +40 -0
- package/packages/utils/src/lib/Semaphore.js.map +1 -0
- package/packages/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/packages/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-B9Sf8e9w.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bl6GY-OE.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-BDq8RX50.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/_index-Bh3y3Wsl.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-tq7Bl6-t.js +0 -10
- package/codeyam-cli/src/webserver/build/client/assets/chart-column-q9_nHfwv.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/circle-alert-CKMpA1v_.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/clock-Wnfog8Qw.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-C_ixaqqh.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-QecTs_sq.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-hnkEgHrC.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/file-text-CvCVdKLW.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-DgUCYhbd.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-DZfbt0u5.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-Bxm63UxG.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-c90b8608.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-DrVZQamX.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/search-CJkk16Ct.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-ConzHeiL.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-B9LRwAej.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-DOxmMaSg.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/zap-D5R1FAcH.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-DGGis3OZ.js +0 -166
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VisitedTracker
|
|
3
|
+
*
|
|
4
|
+
* Manages visited state tracking for the ScopeDataStructure analysis.
|
|
5
|
+
* Prevents infinite loops and redundant processing by tracking which
|
|
6
|
+
* scope/path/value combinations have already been processed.
|
|
7
|
+
*
|
|
8
|
+
* ## Why This Exists
|
|
9
|
+
*
|
|
10
|
+
* The schema building process recursively follows equivalencies between
|
|
11
|
+
* data paths. Without cycle detection, circular references like:
|
|
12
|
+
* `user.profile` → `currentUser` → `user.profile`
|
|
13
|
+
* would cause infinite loops.
|
|
14
|
+
*
|
|
15
|
+
* ## Two Tracking Modes
|
|
16
|
+
*
|
|
17
|
+
* ### 1. Global Visited (scope::path::value)
|
|
18
|
+
* Fine-grained deduplication for `addToSchema()`. Tracks the complete
|
|
19
|
+
* tuple so the same path can be visited with different type values.
|
|
20
|
+
*
|
|
21
|
+
* Example: `myFunc::user.id::string` and `myFunc::user.id::number`
|
|
22
|
+
* are tracked separately, allowing both types to be recorded.
|
|
23
|
+
*
|
|
24
|
+
* ### 2. Complex Source Visited (scope::path)
|
|
25
|
+
* Coarser deduplication for `addComplexSourcePathVariables()`. Ignores
|
|
26
|
+
* the type value because complex source processing should happen once
|
|
27
|
+
* per path regardless of type.
|
|
28
|
+
*
|
|
29
|
+
* ## Lifecycle
|
|
30
|
+
*
|
|
31
|
+
* - Global visited is **reset** at the start of `captureCompleteSchema()`
|
|
32
|
+
* to allow re-processing in the schema building phase.
|
|
33
|
+
* - Complex source visited is **never reset** during normal operation.
|
|
34
|
+
*
|
|
35
|
+
* ## Related Modules
|
|
36
|
+
*
|
|
37
|
+
* - `ScopeDataStructure.addToSchema()` - Primary consumer of global visited
|
|
38
|
+
* - `ScopeDataStructure.addComplexSourcePathVariables()` - Uses complex source visited
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Tracks visited state to prevent infinite loops during schema building.
|
|
43
|
+
*/
|
|
44
|
+
export class VisitedTracker {
|
|
45
|
+
/**
|
|
46
|
+
* Fine-grained visited tracking using scope::path::value.
|
|
47
|
+
* Used by addToSchema to skip already-processed combinations.
|
|
48
|
+
*/
|
|
49
|
+
private globalVisited: Set<string> = new Set();
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Coarser visited tracking using scope::path only (without value).
|
|
53
|
+
* Used by addComplexSourcePathVariables to allow each unique
|
|
54
|
+
* scope+path combo to be processed once, regardless of value.
|
|
55
|
+
*/
|
|
56
|
+
private complexSourceVisited: Set<string> = new Set();
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates a unique key for global visited tracking.
|
|
60
|
+
* @param scopeNodeName - Name of the scope
|
|
61
|
+
* @param path - Schema path
|
|
62
|
+
* @param value - Type value
|
|
63
|
+
*/
|
|
64
|
+
private makeGlobalKey(
|
|
65
|
+
scopeNodeName: string,
|
|
66
|
+
path: string,
|
|
67
|
+
value: string,
|
|
68
|
+
): string {
|
|
69
|
+
return `${scopeNodeName}::${path}::${value}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a unique key for complex source visited tracking.
|
|
74
|
+
* @param scopeNodeName - Name of the scope
|
|
75
|
+
* @param path - Schema path
|
|
76
|
+
*/
|
|
77
|
+
private makeComplexKey(scopeNodeName: string, path: string): string {
|
|
78
|
+
return `${scopeNodeName}::${path}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Checks if a scope/path/value combination has been globally visited.
|
|
83
|
+
* Does NOT mark it as visited - use markGlobalVisited for that.
|
|
84
|
+
*
|
|
85
|
+
* @returns true if already visited
|
|
86
|
+
*/
|
|
87
|
+
hasGlobalVisited(
|
|
88
|
+
scopeNodeName: string,
|
|
89
|
+
path: string,
|
|
90
|
+
value: string,
|
|
91
|
+
): boolean {
|
|
92
|
+
return this.globalVisited.has(
|
|
93
|
+
this.makeGlobalKey(scopeNodeName, path, value),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Marks a scope/path/value combination as globally visited.
|
|
99
|
+
*/
|
|
100
|
+
markGlobalVisited(scopeNodeName: string, path: string, value: string): void {
|
|
101
|
+
this.globalVisited.add(this.makeGlobalKey(scopeNodeName, path, value));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Checks and marks a scope/path/value combination as globally visited.
|
|
106
|
+
* This is a convenience method that combines check and mark.
|
|
107
|
+
*
|
|
108
|
+
* @returns true if was already visited (should skip processing)
|
|
109
|
+
*/
|
|
110
|
+
checkAndMarkGlobalVisited(
|
|
111
|
+
scopeNodeName: string,
|
|
112
|
+
path: string,
|
|
113
|
+
value: string,
|
|
114
|
+
): boolean {
|
|
115
|
+
const key = this.makeGlobalKey(scopeNodeName, path, value);
|
|
116
|
+
if (this.globalVisited.has(key)) {
|
|
117
|
+
return true; // Already visited
|
|
118
|
+
}
|
|
119
|
+
this.globalVisited.add(key);
|
|
120
|
+
return false; // Not visited, now marked
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Checks if a scope/path combination has been visited for complex sources.
|
|
125
|
+
* Does NOT mark it as visited - use markComplexSourceVisited for that.
|
|
126
|
+
*
|
|
127
|
+
* @returns true if already visited
|
|
128
|
+
*/
|
|
129
|
+
hasComplexSourceVisited(scopeNodeName: string, path: string): boolean {
|
|
130
|
+
return this.complexSourceVisited.has(
|
|
131
|
+
this.makeComplexKey(scopeNodeName, path),
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Marks a scope/path combination as visited for complex sources.
|
|
137
|
+
*/
|
|
138
|
+
markComplexSourceVisited(scopeNodeName: string, path: string): void {
|
|
139
|
+
this.complexSourceVisited.add(this.makeComplexKey(scopeNodeName, path));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Checks and marks a scope/path combination as visited for complex sources.
|
|
144
|
+
* This is a convenience method that combines check and mark.
|
|
145
|
+
*
|
|
146
|
+
* @returns true if was already visited (should skip processing)
|
|
147
|
+
*/
|
|
148
|
+
checkAndMarkComplexSourceVisited(
|
|
149
|
+
scopeNodeName: string,
|
|
150
|
+
path: string,
|
|
151
|
+
): boolean {
|
|
152
|
+
const key = this.makeComplexKey(scopeNodeName, path);
|
|
153
|
+
if (this.complexSourceVisited.has(key)) {
|
|
154
|
+
return true; // Already visited
|
|
155
|
+
}
|
|
156
|
+
this.complexSourceVisited.add(key);
|
|
157
|
+
return false; // Not visited, now marked
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Resets the global visited set.
|
|
162
|
+
* Called at the start of captureCompleteSchema() to allow
|
|
163
|
+
* re-processing in the second phase.
|
|
164
|
+
*/
|
|
165
|
+
resetGlobalVisited(): void {
|
|
166
|
+
this.globalVisited.clear();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Resets the complex source visited set.
|
|
171
|
+
* Note: In the original code, this was never reset.
|
|
172
|
+
*/
|
|
173
|
+
resetComplexSourceVisited(): void {
|
|
174
|
+
this.complexSourceVisited.clear();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Resets all visited tracking.
|
|
179
|
+
*/
|
|
180
|
+
resetAll(): void {
|
|
181
|
+
this.globalVisited.clear();
|
|
182
|
+
this.complexSourceVisited.clear();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Returns statistics about the visited sets for debugging/monitoring.
|
|
187
|
+
*/
|
|
188
|
+
getStats(): { globalVisited: number; complexSourceVisited: number } {
|
|
189
|
+
return {
|
|
190
|
+
globalVisited: this.globalVisited.size,
|
|
191
|
+
complexSourceVisited: this.complexSourceVisited.size,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Checks if ANY variant of a scope/path was ever visited (ignores value).
|
|
197
|
+
* Useful for debugging to see if a path was processed at all.
|
|
198
|
+
*
|
|
199
|
+
* @returns true if any variant of this scope/path was visited
|
|
200
|
+
*/
|
|
201
|
+
wasVisited(scopeNodeName: string, path: string): boolean {
|
|
202
|
+
const prefix = `${scopeNodeName}::${path}::`;
|
|
203
|
+
for (const key of this.globalVisited) {
|
|
204
|
+
if (key.startsWith(prefix)) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return this.hasComplexSourceVisited(scopeNodeName, path);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Gets all visited entries for a scope (for debugging).
|
|
213
|
+
* Returns an array of {path, value} objects.
|
|
214
|
+
*/
|
|
215
|
+
getVisitedForScope(
|
|
216
|
+
scopeNodeName: string,
|
|
217
|
+
): Array<{ path: string; value: string }> {
|
|
218
|
+
const prefix = `${scopeNodeName}::`;
|
|
219
|
+
const results: Array<{ path: string; value: string }> = [];
|
|
220
|
+
|
|
221
|
+
for (const key of this.globalVisited) {
|
|
222
|
+
if (key.startsWith(prefix)) {
|
|
223
|
+
const parts = key.slice(prefix.length).split('::');
|
|
224
|
+
if (parts.length >= 2) {
|
|
225
|
+
results.push({
|
|
226
|
+
path: parts.slice(0, -1).join('::'), // Everything except last part
|
|
227
|
+
value: parts[parts.length - 1], // Last part is value
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return results;
|
|
234
|
+
}
|
|
235
|
+
}
|
package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts
CHANGED
|
@@ -355,9 +355,11 @@ export function fillInDirectSchemaGapsAndUnknowns({
|
|
|
355
355
|
|
|
356
356
|
// Don't set to 'function' if this is a promise method on an async function
|
|
357
357
|
// (we want the awaited value, not the promise)
|
|
358
|
+
// Also don't overwrite 'array' - the function might return an array (e.g., getAll())
|
|
358
359
|
if (
|
|
359
360
|
schema[functionReturnValuePath] &&
|
|
360
361
|
schema[functionReturnValuePath] !== 'function' &&
|
|
362
|
+
schema[functionReturnValuePath] !== 'array' &&
|
|
361
363
|
!(isPromiseMethod && isPreviousAsync)
|
|
362
364
|
) {
|
|
363
365
|
schema[functionReturnValuePath] = 'function';
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* selectBestValue
|
|
3
|
+
*
|
|
4
|
+
* Selects the most specific type value from two candidates.
|
|
5
|
+
* Prefers more specific types over 'unknown' values.
|
|
6
|
+
*
|
|
7
|
+
* ## Context
|
|
8
|
+
*
|
|
9
|
+
* During schema building, the same path may have type information from
|
|
10
|
+
* multiple sources (e.g., from a return statement and from a function call).
|
|
11
|
+
* When merging these, we want to keep the most specific type.
|
|
12
|
+
*
|
|
13
|
+
* "Specific" means:
|
|
14
|
+
* - `'string'` is more specific than `'unknown'`
|
|
15
|
+
* - `'string'` is more specific than `'unknown|string'`
|
|
16
|
+
* - `'string|number'` is equal specificity to `'number|string'`
|
|
17
|
+
*
|
|
18
|
+
* ## Selection Rules
|
|
19
|
+
*
|
|
20
|
+
* 1. If value1 exists and is not 'unknown', use value1
|
|
21
|
+
* 2. If value2 exists and is more specific (not 'unknown'), prefer value2
|
|
22
|
+
* 3. Otherwise use the first available value, or 'unknown' as default
|
|
23
|
+
*
|
|
24
|
+
* ## Where Used
|
|
25
|
+
*
|
|
26
|
+
* - `propagateSourceAndUsageEquivalencies.equateSchema()` - Merging schemas
|
|
27
|
+
* - `getReturnValue()` - Combining return type information
|
|
28
|
+
*
|
|
29
|
+
* ## Related Modules
|
|
30
|
+
*
|
|
31
|
+
* - `ensureSchemaConsistency.ts` - Also deals with type merging
|
|
32
|
+
* - `fillInSchemaGapsAndUnknowns.ts` - Fills in missing types after schema building
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Selects the best (most specific) value between two type candidates.
|
|
37
|
+
*
|
|
38
|
+
* @param value1 - Primary value (preferred if specific)
|
|
39
|
+
* @param value2 - Secondary value (used if value1 is 'unknown')
|
|
40
|
+
* @param defaultValue - Default when both are undefined (defaults to 'unknown')
|
|
41
|
+
* @returns The most specific type value
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* selectBestValue('string', 'number') // 'string' - value1 is specific
|
|
45
|
+
* selectBestValue('unknown', 'string') // 'string' - value2 is more specific
|
|
46
|
+
* selectBestValue(undefined, 'number') // 'number' - value1 undefined
|
|
47
|
+
* selectBestValue(undefined, undefined) // 'unknown' - default
|
|
48
|
+
* selectBestValue('unknown|string', 'string') // 'string' - value2 has no unknown
|
|
49
|
+
*/
|
|
50
|
+
export default function selectBestValue(
|
|
51
|
+
value1: string | undefined,
|
|
52
|
+
value2: string | undefined,
|
|
53
|
+
defaultValue = 'unknown',
|
|
54
|
+
): string {
|
|
55
|
+
let bestValue = value1 ?? value2 ?? defaultValue;
|
|
56
|
+
|
|
57
|
+
// Prefer value2 if:
|
|
58
|
+
// - value2 exists AND
|
|
59
|
+
// - bestValue is 'unknown' and value2 is not, OR
|
|
60
|
+
// - bestValue contains 'unknown' and value2 doesn't
|
|
61
|
+
if (
|
|
62
|
+
value2 &&
|
|
63
|
+
((bestValue === 'unknown' && value2 !== 'unknown') ||
|
|
64
|
+
(bestValue.includes('unknown') && !value2.includes('unknown')))
|
|
65
|
+
) {
|
|
66
|
+
bestValue = value2;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return bestValue;
|
|
70
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UniqueIdUtils
|
|
3
|
+
*
|
|
4
|
+
* Utility functions for creating unique identifiers and deduplicating
|
|
5
|
+
* scope variables in the ScopeDataStructure analysis.
|
|
6
|
+
*
|
|
7
|
+
* ## Why Unique IDs Matter
|
|
8
|
+
*
|
|
9
|
+
* The analysis tracks data flow across many scopes and paths. When building
|
|
10
|
+
* equivalency chains or schemas, we need to:
|
|
11
|
+
* - Detect cycles (have we seen this scope+path+value before?)
|
|
12
|
+
* - Deduplicate results (don't report the same equivalency twice)
|
|
13
|
+
* - Index efficiently (O(1) lookups in large datasets)
|
|
14
|
+
*
|
|
15
|
+
* ## Key Format
|
|
16
|
+
*
|
|
17
|
+
* The unique ID format is `scopeNodeName::schemaPath[::value]`:
|
|
18
|
+
* - `myFunc::user.id` - Scope+path without type value
|
|
19
|
+
* - `myFunc::user.id::string` - Full tuple including type
|
|
20
|
+
*
|
|
21
|
+
* The `::` delimiter is chosen because:
|
|
22
|
+
* - Scope names never contain `::`
|
|
23
|
+
* - Schema paths use `.` and `[]` but not `::`
|
|
24
|
+
* - Type values may contain `:` (e.g., `union::type`) but only as the last part
|
|
25
|
+
*
|
|
26
|
+
* ## Performance
|
|
27
|
+
*
|
|
28
|
+
* `uniqueScopeAndPaths` uses O(n) Set-based deduplication instead of O(n²)
|
|
29
|
+
* array comparisons. This matters when processing thousands of equivalencies.
|
|
30
|
+
*
|
|
31
|
+
* ## Related Modules
|
|
32
|
+
*
|
|
33
|
+
* - `VisitedTracker.ts` - Uses similar key format for cycle detection
|
|
34
|
+
* - `ScopeDataStructure.equivalencyDatabase` - Indexed by these unique IDs
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Interface for items that can be deduplicated by scope and path.
|
|
39
|
+
* Matches the ScopeVariable interface's required fields.
|
|
40
|
+
*/
|
|
41
|
+
export interface ScopeAndPath {
|
|
42
|
+
scopeNodeName: string;
|
|
43
|
+
schemaPath: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Creates a unique identifier string from scope, path, and optional value.
|
|
48
|
+
* Used for tracking visited combinations and equivalency chains.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* uniqueId({ scopeNodeName: 'myFunc', schemaPath: 'user.id' }) // 'myFunc::user.id'
|
|
52
|
+
* uniqueId({ scopeNodeName: 'myFunc', schemaPath: 'user.id', value: 'string' }) // 'myFunc::user.id::string'
|
|
53
|
+
*/
|
|
54
|
+
export function uniqueId({
|
|
55
|
+
scopeNodeName,
|
|
56
|
+
schemaPath,
|
|
57
|
+
value,
|
|
58
|
+
}: {
|
|
59
|
+
scopeNodeName: string;
|
|
60
|
+
schemaPath: string;
|
|
61
|
+
value?: string;
|
|
62
|
+
}): string {
|
|
63
|
+
const parts = [scopeNodeName, schemaPath, value].filter(Boolean);
|
|
64
|
+
return parts.join('::');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Removes duplicate scope variables from an array, keeping only the first occurrence
|
|
69
|
+
* of each unique scopeNodeName + schemaPath combination.
|
|
70
|
+
*
|
|
71
|
+
* This is a type-preserving version of uniqueScopeAndPaths that returns the full
|
|
72
|
+
* ScopeVariable objects (with id and equivalencyReason).
|
|
73
|
+
*
|
|
74
|
+
* @param scopeVariables - Array of scope variables to deduplicate
|
|
75
|
+
* @returns Deduplicated array preserving original type
|
|
76
|
+
*/
|
|
77
|
+
export function uniqueScopeVariables<T extends ScopeAndPath>(
|
|
78
|
+
scopeVariables: T[],
|
|
79
|
+
): T[] {
|
|
80
|
+
return uniqueScopeAndPaths(scopeVariables);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Removes duplicates from an array of objects with scopeNodeName and schemaPath.
|
|
85
|
+
* Uses O(n) Set-based deduplication for performance.
|
|
86
|
+
*
|
|
87
|
+
* @param scopeVariables - Array of objects to deduplicate
|
|
88
|
+
* @returns Deduplicated array preserving original type
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* uniqueScopeAndPaths([
|
|
92
|
+
* { scopeNodeName: 'a', schemaPath: 'x' },
|
|
93
|
+
* { scopeNodeName: 'a', schemaPath: 'x' },
|
|
94
|
+
* { scopeNodeName: 'b', schemaPath: 'y' },
|
|
95
|
+
* ])
|
|
96
|
+
* // Returns: [{ scopeNodeName: 'a', schemaPath: 'x' }, { scopeNodeName: 'b', schemaPath: 'y' }]
|
|
97
|
+
*/
|
|
98
|
+
export function uniqueScopeAndPaths<T extends ScopeAndPath>(
|
|
99
|
+
scopeVariables: T[] | undefined | null,
|
|
100
|
+
): T[] {
|
|
101
|
+
if (!scopeVariables || scopeVariables.length === 0) return [];
|
|
102
|
+
|
|
103
|
+
// Optimize from O(n²) to O(n) using Set for deduplication
|
|
104
|
+
const seen = new Set<string>();
|
|
105
|
+
return scopeVariables.filter((varItem) => {
|
|
106
|
+
const key = `${varItem.scopeNodeName}::${varItem.schemaPath}`;
|
|
107
|
+
if (seen.has(key)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
seen.add(key);
|
|
111
|
+
return true;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
@@ -70,6 +70,42 @@ export default function gatherRelevantDependentKeyAttributes(
|
|
|
70
70
|
const signatureSchema = dependencySchema?.signatureSchema;
|
|
71
71
|
if (!signatureSchema) return;
|
|
72
72
|
|
|
73
|
+
const sourceEquivalencies = dependencySchema?.sourceEquivalencies ?? {};
|
|
74
|
+
|
|
75
|
+
// If sourceEquivalencies is empty but the child has mocked imports,
|
|
76
|
+
// propagate key attributes directly since they affect the parent's visual output
|
|
77
|
+
if (Object.keys(sourceEquivalencies).length === 0) {
|
|
78
|
+
// Check both importedExports and nodeModuleImports for mocked imports
|
|
79
|
+
const importedExports =
|
|
80
|
+
dependentAnalysis.entity?.metadata?.importedExports ?? [];
|
|
81
|
+
const nodeModuleImports =
|
|
82
|
+
dependentAnalysis.entity?.metadata?.nodeModuleImports ?? {};
|
|
83
|
+
|
|
84
|
+
const hasMockedImportedExports = importedExports.some(
|
|
85
|
+
(imp: { isMocked?: boolean }) => imp.isMocked,
|
|
86
|
+
);
|
|
87
|
+
const hasMockedNodeModuleImports = Object.values(
|
|
88
|
+
nodeModuleImports,
|
|
89
|
+
).some((imports: any[]) =>
|
|
90
|
+
imports?.some((imp: { isMocked?: boolean }) => imp.isMocked),
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const childHasMockedImports =
|
|
94
|
+
hasMockedImportedExports || hasMockedNodeModuleImports;
|
|
95
|
+
|
|
96
|
+
if (childHasMockedImports) {
|
|
97
|
+
for (const dependentKeyAttribute of dependentKeyAtttributes) {
|
|
98
|
+
relevantDependentKeyAttributes.push({
|
|
99
|
+
...dependentKeyAttribute,
|
|
100
|
+
dependentEntityName: entityName,
|
|
101
|
+
originalEntityName: entityName,
|
|
102
|
+
filePath: path,
|
|
103
|
+
} as any);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
73
109
|
for (const dependentKeyAttribute of dependentKeyAtttributes) {
|
|
74
110
|
const dependentKeyAttributeExternalPathParts =
|
|
75
111
|
splitOutsideParenthesesAndArrays(dependentKeyAttribute.externalPath);
|
|
@@ -57,8 +57,8 @@ export default async function generateEntityKeyAttributes({
|
|
|
57
57
|
staticAnalysisContext,
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
console.
|
|
61
|
-
console.
|
|
60
|
+
console.log('Generated prompt for generateEntityKeyAttributes:');
|
|
61
|
+
console.log(prompt);
|
|
62
62
|
|
|
63
63
|
const response = await completionCall({
|
|
64
64
|
type: `generateEntityKeyAttributes`,
|
|
@@ -167,15 +167,26 @@ NOT key attributes:
|
|
|
167
167
|
- Values that would cause errors if changed
|
|
168
168
|
- Guard clauses that render literally nothing
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
## Conditional Key Attributes
|
|
171
|
+
|
|
172
|
+
We've provided a list of variables that are used in conditional statements in the code. These are very likely key attributes.
|
|
173
|
+
|
|
174
|
+
Each conditional lists it's source and how it is used. This should help you identify which attributes to include and what values to suggest.
|
|
171
175
|
|
|
172
176
|
## Path Format
|
|
173
177
|
|
|
174
|
-
Only return attributes from the "Attributes and Value Types" list—these are the only values we can control. Use the exact \`fullPath\` provided. Use \`functionCallReturnValue\` for function return values. Use \`[]\` for array items (e.g., \`items[]\`).
|
|
178
|
+
Only return attributes from the "Attributes and Value Types" list — these are the only values we can control. Use the exact \`fullPath\` provided. Use \`functionCallReturnValue\` for function return values. Use \`[]\` for array items (e.g., \`items[]\`).
|
|
179
|
+
|
|
180
|
+
## Valid Value Options
|
|
181
|
+
|
|
182
|
+
- For \`validValueOptions\`, include boundary/extreme values that trigger different behavior
|
|
183
|
+
- Be very specific with values. Do not make them ambiguous in any way
|
|
184
|
+
— Do NOT include values that would cause unexpected/unhandled errors.
|
|
185
|
+
- Ensure all values or value ranges that will trigger different rendering behavior are included
|
|
175
186
|
|
|
176
187
|
## Response Format
|
|
177
188
|
|
|
178
|
-
|
|
189
|
+
List all key attributes in order from most impactful to least impactful regarding how dramatically they will change the rendering of the component using the following format:
|
|
179
190
|
|
|
180
191
|
\`\`\`json
|
|
181
192
|
{
|
|
@@ -183,7 +194,7 @@ For \`validValueOptions\`, include boundary/extreme values that trigger differen
|
|
|
183
194
|
{
|
|
184
195
|
"fullPath": "signature[0].user",
|
|
185
196
|
"description": "Controls whether the main form or redirect screen displays",
|
|
186
|
-
"validValueOptions": ["
|
|
197
|
+
"validValueOptions": ["an empty object {}", "null/undefined"]
|
|
187
198
|
}
|
|
188
199
|
]
|
|
189
200
|
}
|
|
@@ -205,13 +216,26 @@ NOT key attributes:
|
|
|
205
216
|
- Values that would cause errors if changed
|
|
206
217
|
- Guard clauses that return nothing/minimal data
|
|
207
218
|
|
|
219
|
+
## Conditional Key Attributes
|
|
220
|
+
|
|
221
|
+
We've provided a list of variables that are used in conditional statements in the code. These are very likely key attributes.
|
|
222
|
+
|
|
223
|
+
Each conditional lists it's source and how it is used. This should help you identify which attributes to include and what values to suggest.
|
|
224
|
+
|
|
208
225
|
## Path Format
|
|
209
226
|
|
|
210
|
-
Only return attributes from the "Attributes and Value Types" list—these are the only values we can control. Use the exact \`fullPath\` provided. Use \`functionCallReturnValue\` for function return values. Use \`[]\` for array items (e.g., \`items[]\`).
|
|
227
|
+
Only return attributes from the "Attributes and Value Types" list — these are the only values we can control. Use the exact \`fullPath\` provided. Use \`functionCallReturnValue\` for function return values. Use \`[]\` for array items (e.g., \`items[]\`).
|
|
228
|
+
|
|
229
|
+
## Valid Value Options
|
|
230
|
+
|
|
231
|
+
- For \`validValueOptions\`, include boundary/extreme values that trigger different behavior
|
|
232
|
+
- Be very specific with values. Do not make them ambiguous in any way
|
|
233
|
+
— Do NOT include values that would cause unexpected/unhandled errors.
|
|
234
|
+
- Ensure all values or value ranges that will trigger different rendering behavior are included
|
|
211
235
|
|
|
212
236
|
## Response Format
|
|
213
237
|
|
|
214
|
-
|
|
238
|
+
List all key attributes in order from most impactful to least impactful using the following format:
|
|
215
239
|
|
|
216
240
|
\`\`\`json
|
|
217
241
|
{
|
|
@@ -259,8 +259,16 @@ function getLiteralValue(expr: ts.Expression): string | undefined {
|
|
|
259
259
|
/**
|
|
260
260
|
* Format conditional usages into a string for the LLM prompt
|
|
261
261
|
*/
|
|
262
|
+
/**
|
|
263
|
+
* Interface for conditional usages that may have source tracing information.
|
|
264
|
+
* This is a superset of ConditionalUsage that includes optional sourceDataPath.
|
|
265
|
+
*/
|
|
266
|
+
interface EnrichedConditionalUsageInput extends ConditionalUsage {
|
|
267
|
+
sourceDataPath?: string;
|
|
268
|
+
}
|
|
269
|
+
|
|
262
270
|
export function formatConditionalUsagesForPrompt(
|
|
263
|
-
conditionalUsages: Record<string,
|
|
271
|
+
conditionalUsages: Record<string, EnrichedConditionalUsageInput[]>,
|
|
264
272
|
): string {
|
|
265
273
|
const entries = Object.entries(conditionalUsages);
|
|
266
274
|
if (entries.length === 0) {
|
|
@@ -270,7 +278,7 @@ export function formatConditionalUsagesForPrompt(
|
|
|
270
278
|
const lines: string[] = [
|
|
271
279
|
'\n## Static Analysis: Attributes Used in Conditionals',
|
|
272
280
|
'',
|
|
273
|
-
'The following attributes were found to be used in conditional statements, making them
|
|
281
|
+
'The following attributes were found to be used in conditional statements, making them very likely key attributes:',
|
|
274
282
|
'',
|
|
275
283
|
];
|
|
276
284
|
|
|
@@ -281,20 +289,30 @@ export function formatConditionalUsagesForPrompt(
|
|
|
281
289
|
.flatMap((u) => u.comparedValues || []);
|
|
282
290
|
const uniqueValues = [...new Set(allComparedValues)];
|
|
283
291
|
|
|
284
|
-
|
|
292
|
+
// Get the source data path if available (traced back to data source)
|
|
293
|
+
const sourceDataPath = usages.find((u) => u.sourceDataPath)?.sourceDataPath;
|
|
294
|
+
|
|
295
|
+
let description = `- "${path}"`;
|
|
296
|
+
|
|
297
|
+
// If we have a source data path, show that the local variable derives from a data source
|
|
298
|
+
if (sourceDataPath) {
|
|
299
|
+
description += `\n - Source: "${sourceDataPath}"`;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
description += '\n - ';
|
|
285
303
|
|
|
286
304
|
if (uniqueTypes.includes('switch')) {
|
|
287
|
-
description += '
|
|
305
|
+
description += 'Used as switch discriminant';
|
|
288
306
|
if (uniqueValues.length > 0) {
|
|
289
307
|
description += ` with cases: ${uniqueValues.map((v) => `"${v}"`).join(', ')}`;
|
|
290
308
|
}
|
|
291
309
|
} else if (uniqueTypes.includes('comparison')) {
|
|
292
|
-
description += '
|
|
310
|
+
description += 'Used in comparison';
|
|
293
311
|
if (uniqueValues.length > 0) {
|
|
294
312
|
description += ` against values: ${uniqueValues.map((v) => `"${v}"`).join(', ')}`;
|
|
295
313
|
}
|
|
296
314
|
} else {
|
|
297
|
-
description += '
|
|
315
|
+
description += 'Used in truthiness check (presence/absence matters)';
|
|
298
316
|
}
|
|
299
317
|
|
|
300
318
|
lines.push(description);
|
|
@@ -304,6 +322,9 @@ export function formatConditionalUsagesForPrompt(
|
|
|
304
322
|
lines.push(
|
|
305
323
|
'Consider these attributes as candidates for key attributes, especially those with specific comparison values.',
|
|
306
324
|
);
|
|
325
|
+
lines.push(
|
|
326
|
+
'When a local variable derives from a data source, the data source is the key attribute.',
|
|
327
|
+
);
|
|
307
328
|
|
|
308
329
|
return lines.join('\n');
|
|
309
330
|
}
|
|
@@ -5,9 +5,44 @@ import {
|
|
|
5
5
|
splitOutsideParenthesesAndArrays,
|
|
6
6
|
} from '../splitOutsideParentheses';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Checks if a bracket-only path is a valid string key access (not just an index).
|
|
10
|
+
* Valid: ['*'], ['someKey'] - string key access
|
|
11
|
+
* Invalid: [0], [1] - numeric index only (meaningless without parent path)
|
|
12
|
+
*/
|
|
13
|
+
function isValidBracketStringKey(attribute: string): boolean {
|
|
14
|
+
// Match ['string'] or ["string"] patterns
|
|
15
|
+
return /^\[['"][^'"]+['"]\]$/.test(attribute);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Extracts the string key from a bracket notation like ['*'] or ["key"]
|
|
20
|
+
* Returns the key without quotes and brackets, e.g., '*' or 'key'
|
|
21
|
+
*/
|
|
22
|
+
function extractBracketStringKey(attribute: string): string | null {
|
|
23
|
+
const match = attribute.match(/^\[['"]([^'"]+)['"]\]$/);
|
|
24
|
+
return match ? match[1] : null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Normalizes a path by extracting string keys from bracket notation.
|
|
29
|
+
* If the path is a single bracket string key like ['*'], returns the key ('*').
|
|
30
|
+
* Otherwise returns the path unchanged.
|
|
31
|
+
*/
|
|
32
|
+
function normalizePathForInternalUse(path: string): string {
|
|
33
|
+
const extracted = extractBracketStringKey(path);
|
|
34
|
+
return extracted !== null ? extracted : path;
|
|
35
|
+
}
|
|
36
|
+
|
|
8
37
|
function validAttribute(attribute: string) {
|
|
9
|
-
if (!attribute || attribute.length === 0
|
|
10
|
-
|
|
38
|
+
if (!attribute || attribute.length === 0) return false;
|
|
39
|
+
|
|
40
|
+
// Allow string-key bracket access like ['*'] or ['someKey']
|
|
41
|
+
// These are valid data paths from objects with dynamic/special keys
|
|
42
|
+
if (attribute.startsWith('[')) {
|
|
43
|
+
return isValidBracketStringKey(attribute);
|
|
44
|
+
}
|
|
45
|
+
|
|
11
46
|
const attributeParts = splitOutsideParenthesesAndArrays(attribute);
|
|
12
47
|
if (
|
|
13
48
|
attributeParts.some((part) =>
|
|
@@ -153,8 +188,11 @@ export function gatherAttributesMap(
|
|
|
153
188
|
// Fall through to normal processing for other return value properties
|
|
154
189
|
}
|
|
155
190
|
|
|
156
|
-
const
|
|
157
|
-
if (!validAttribute(
|
|
191
|
+
const rawRelativePath = joinParenthesesAndArrays(pathParts.slice(2));
|
|
192
|
+
if (!validAttribute(rawRelativePath)) continue;
|
|
193
|
+
|
|
194
|
+
// Normalize the path for internal use (e.g., ['*'] -> '*')
|
|
195
|
+
const relativePath = normalizePathForInternalUse(rawRelativePath);
|
|
158
196
|
|
|
159
197
|
attributesMap[relativePath] = returnValueDataStructure[path];
|
|
160
198
|
associationMap[reverse ? relativePath : path] = reverse
|