@codeyam/codeyam-cli 0.1.0-staging.1 → 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 +8 -7
- package/analyzer-template/packages/ai/index.ts +2 -1
- package/analyzer-template/packages/ai/package.json +2 -2
- package/analyzer-template/packages/ai/scripts/ai-test-matrix.mjs +424 -0
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +24 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +6 -16
- package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +197 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/paths.ts +28 -2
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +127 -4
- package/analyzer-template/packages/ai/src/lib/checkAllAttributes.ts +1 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +1821 -542
- 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 +14 -6
- 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/generateChangesEntityDocumentation.ts +20 -2
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityKeyAttributes.ts +51 -107
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarioData.ts +56 -160
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +79 -265
- package/analyzer-template/packages/ai/src/lib/generateEntityDocumentation.ts +16 -2
- package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +53 -176
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +53 -154
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +84 -254
- package/analyzer-template/packages/ai/src/lib/generateStatementAnalysis.ts +48 -71
- package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +27 -6
- package/analyzer-template/packages/ai/src/lib/getLLMCallStats.ts +0 -14
- package/analyzer-template/packages/ai/src/lib/modelInfo.ts +15 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +42 -4
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityDocumentationGenerator.ts +8 -33
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.ts +54 -62
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +93 -109
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.ts +8 -27
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +33 -38
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +30 -30
- package/analyzer-template/packages/ai/src/lib/types/index.ts +2 -0
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +39 -0
- package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +52 -6
- package/analyzer-template/packages/analyze/src/lib/asts/nodes/index.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.ts +238 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getDeclaredEntityNode.ts +25 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/index.ts +2 -0
- 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/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +15 -7
- 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/componentScenarioPage/componentScenarioPageNext.ts +28 -21
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.ts +18 -11
- package/analyzer-template/packages/generate/src/lib/scenarioComponent.ts +6 -3
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +28 -21
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js +18 -11
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js.map +1 -1
- 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 +2 -0
- package/analyzer-template/packages/github/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/index.js +2 -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/getNextRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getNextRoutePath.js +5 -3
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- 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/nextRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js +2 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.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/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts +12 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- 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/ui-components/src/scenario-editor/components/DataItemEditor.tsx +1 -1
- package/analyzer-template/packages/utils/dist/utils/index.d.ts +2 -0
- package/analyzer-template/packages/utils/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/index.js +2 -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/getNextRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getNextRoutePath.js +5 -3
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- 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/nextRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js +2 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.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/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts +12 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- package/analyzer-template/packages/utils/index.ts +2 -0
- package/analyzer-template/packages/utils/src/lib/Semaphore.ts +42 -0
- package/analyzer-template/packages/utils/src/lib/frameworks/getNextRoutePath.ts +8 -3
- package/analyzer-template/packages/utils/src/lib/frameworks/getRemixRoutePath.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/nextRouteFileNameToRoute.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.ts +1 -0
- package/analyzer-template/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.ts +33 -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/startScenarioCapture.ts +24 -0
- package/analyzer-template/project/trackGeneratedFiles.ts +41 -0
- package/analyzer-template/project/writeMockDataTsx.ts +125 -4
- package/analyzer-template/project/writeScenarioComponents.ts +199 -45
- package/analyzer-template/project/writeUniversalMocks.ts +72 -10
- 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/startScenarioCapture.js +18 -0
- package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/trackGeneratedFiles.js +30 -0
- package/background/src/lib/virtualized/project/trackGeneratedFiles.js.map +1 -0
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +95 -3
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +144 -28
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeUniversalMocks.js +59 -9
- package/background/src/lib/virtualized/project/writeUniversalMocks.js.map +1 -1
- package/codeyam-cli/scripts/apply-setup.js +288 -0
- package/codeyam-cli/scripts/apply-setup.js.map +1 -0
- package/codeyam-cli/scripts/extract-setup.js +130 -0
- package/codeyam-cli/scripts/extract-setup.js.map +1 -0
- package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js +238 -0
- package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js.map +1 -0
- 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/init.js +4 -23
- package/codeyam-cli/src/commands/init.js.map +1 -1
- 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/analysisRunner.js +4 -3
- package/codeyam-cli/src/utils/analysisRunner.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/backgroundServer.js +25 -5
- package/codeyam-cli/src/utils/backgroundServer.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/fileWatcher.js +75 -5
- package/codeyam-cli/src/utils/fileWatcher.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 +8 -3
- 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/utils/webappDetection.js +2 -1
- package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js +63 -2
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/backgroundServer.js +15 -35
- package/codeyam-cli/src/webserver/backgroundServer.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-Dh-FldQK.js → InteractivePreview-XDSzQLOY.js} +3 -3
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-BYVx9KFp.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-Dp6DC845.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-Bual6h18.js +1 -0
- 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-B2I7jQx2.js → chart-column-B8fb6wnw.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-De6i8FUT.js +26 -0
- package/codeyam-cli/src/webserver/build/client/assets/{circle-alert-GwwOAbhw.js → circle-alert-IdsgAK39.js} +1 -1
- 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._-1Z6D0fLM.js → entity._sha._-8Els_3Wb.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-C3FZJx1w.js +1 -0
- 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/{entityVersioning-DO2gCvXv.js → entityVersioning-Bk_YB1jM.js} +1 -1
- 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-BXmqrWCH.js +12 -0
- 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-D-zYbzFZ.js +8 -0
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-DN7Vr40D.js → loader-circle-BXPKbHEb.js} +1 -1
- 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-MZc4XdmE.js → settings-5zF_GOcS.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-Dc4MlMpK.js +1 -0
- 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-BBlyqxij.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-B4gsLUZQ.js → zap-_jw-9DCp.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-D4JpXSIO.js +1 -0
- 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/src/webserver/server.js +1 -1
- package/codeyam-cli/src/webserver/server.js.map +1 -1
- package/codeyam-cli/templates/codeyam-setup-skill.md +85 -94
- package/codeyam-cli/templates/debug-command.md +125 -0
- package/package.json +9 -11
- package/packages/ai/index.js +1 -2
- 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/astScopeAnalyzer.js +6 -15
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
- package/packages/ai/src/lib/astScopes/methodSemantics.js +134 -0
- package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
- package/packages/ai/src/lib/astScopes/paths.js +28 -3
- package/packages/ai/src/lib/astScopes/paths.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +111 -3
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/checkAllAttributes.js +1 -3
- package/packages/ai/src/lib/checkAllAttributes.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1320 -396
- 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 +14 -6
- 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/generateChangesEntityDocumentation.js +19 -1
- package/packages/ai/src/lib/generateChangesEntityDocumentation.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js +51 -107
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js +55 -156
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarios.js +79 -262
- package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDocumentation.js +15 -1
- package/packages/ai/src/lib/generateEntityDocumentation.js.map +1 -1
- package/packages/ai/src/lib/generateEntityKeyAttributes.js +53 -176
- package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +52 -152
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +88 -258
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateStatementAnalysis.js +46 -71
- package/packages/ai/src/lib/generateStatementAnalysis.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/getLLMCallStats.js +0 -14
- package/packages/ai/src/lib/getLLMCallStats.js.map +1 -1
- package/packages/ai/src/lib/modelInfo.js +15 -0
- package/packages/ai/src/lib/modelInfo.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/promptGenerators/generateChangesEntityDocumentationGenerator.js +8 -33
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityDocumentationGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js +35 -41
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +59 -72
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.js +8 -27
- package/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +24 -27
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +21 -22
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/types/index.js +2 -0
- package/packages/ai/src/lib/types/index.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 +45 -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/asts/sourceFiles/getAllDeclaredEntityNodes.js +191 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js.map +1 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getDeclaredEntityNode.js +16 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getDeclaredEntityNode.js.map +1 -0
- package/packages/analyze/src/lib/asts/sourceFiles/index.js +2 -0
- package/packages/analyze/src/lib/asts/sourceFiles/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/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +16 -7
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +28 -21
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js +18 -11
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.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 +2 -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/getNextRoutePath.js +5 -3
- package/packages/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- 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/nextRouteFileNameToRoute.js +2 -1
- package/packages/utils/src/lib/frameworks/nextRouteFileNameToRoute.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/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- package/analyzer-template/packages/ai/src/lib/generateEntityDataMap.ts +0 -375
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-GqWwt5wG.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-p0fuyqGQ.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-xwuhwsZH.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bl2IRh55.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-M2QuSHKC.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/_index-CAVtep9Q.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-CLmzsLsT.js +0 -10
- package/codeyam-cli/src/webserver/build/client/assets/components-CAx5ONX_.js +0 -40
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CgyOwWip.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DGy3zrli.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-ChAdTrrU.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-D9L7267w.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-C6FRgjPr.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-C3-cQjgv.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-Dp4EB9nv.js +0 -12
- package/codeyam-cli/src/webserver/build/client/assets/globals-Da3jt49-.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-172a4629.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-COyVTsPq.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/search-CvyP_1Lo.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-Hbf8b7J_.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-BMBi0VzO.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-C_VxoXTh.js +0 -1
- package/codeyam-cli/src/webserver/build/client/cy-logo-cli.svg +0 -13
- package/codeyam-cli/src/webserver/build/server/assets/index-eAULANMV.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-lutv16q5.js +0 -161
- package/codeyam-cli/src/webserver/public/cy-logo-cli.svg +0 -13
- package/packages/ai/src/lib/generateEntityDataMap.js +0 -335
- package/packages/ai/src/lib/generateEntityDataMap.js.map +0 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityDataMapGenerator.js +0 -17
- package/packages/ai/src/lib/promptGenerators/generateEntityDataMapGenerator.js.map +0 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PathManager
|
|
3
|
+
*
|
|
4
|
+
* Centralized utility for schema path manipulation with built-in caching.
|
|
5
|
+
* Handles splitting, joining, and validating schema paths used throughout
|
|
6
|
+
* the ScopeDataStructure analysis.
|
|
7
|
+
*
|
|
8
|
+
* ## Context in the Analysis Pipeline
|
|
9
|
+
*
|
|
10
|
+
* Schema paths are dot-separated strings representing data access patterns:
|
|
11
|
+
* - `signature[0].user.id` - First argument's user.id property
|
|
12
|
+
* - `items[].name` - name property of array elements
|
|
13
|
+
* - `functionCallReturnValue(fetch).data` - Return value from fetch() call
|
|
14
|
+
*
|
|
15
|
+
* These paths are created during AST analysis and used extensively in:
|
|
16
|
+
* 1. **Equivalency tracking** - Linking data flow between scopes
|
|
17
|
+
* 2. **Schema building** - Determining the shape of function inputs/outputs
|
|
18
|
+
* 3. **Database queries** - Finding source/usage relationships
|
|
19
|
+
*
|
|
20
|
+
* ## Performance Notes
|
|
21
|
+
*
|
|
22
|
+
* Path operations are called thousands of times per analysis. Caching
|
|
23
|
+
* provides ~10x speedup for repeated operations on the same paths.
|
|
24
|
+
*
|
|
25
|
+
* ## Related Modules
|
|
26
|
+
*
|
|
27
|
+
* - `splitOutsideParentheses.ts` - Low-level split/join with parentheses awareness
|
|
28
|
+
* - `cleanPath.ts` - Normalizes paths by removing noise
|
|
29
|
+
* - `uniqueIdUtils.ts` - Creates unique keys from scope+path combinations
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import {
|
|
33
|
+
joinParenthesesAndArrays,
|
|
34
|
+
splitOutsideParenthesesAndArrays,
|
|
35
|
+
} from '../../splitOutsideParentheses';
|
|
36
|
+
import cleanOutBoundary from '../../cleanOutBoundary';
|
|
37
|
+
|
|
38
|
+
export class PathManager {
|
|
39
|
+
private pathPartsCache: Map<string, string[]> = new Map();
|
|
40
|
+
private pathJoinCache: Map<string, string> = new Map();
|
|
41
|
+
private isValidPathCache: Map<string, boolean> = new Map();
|
|
42
|
+
private stripGenericsCache: Map<string, string> = new Map();
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Splits a schema path into its component parts.
|
|
46
|
+
* Results are cached for performance.
|
|
47
|
+
*
|
|
48
|
+
* IMPORTANT: The returned array must NOT be mutated by callers.
|
|
49
|
+
* This allows us to return the cached array directly without cloning,
|
|
50
|
+
* providing significant performance gains (structuredClone is expensive).
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* splitPath('user.profile.name') // ['user', 'profile', 'name']
|
|
54
|
+
* splitPath('items[].id') // ['items[]', 'id']
|
|
55
|
+
*/
|
|
56
|
+
splitPath(path: string): readonly string[] {
|
|
57
|
+
const cached = this.pathPartsCache.get(path);
|
|
58
|
+
if (cached) {
|
|
59
|
+
return cached;
|
|
60
|
+
}
|
|
61
|
+
const pathParts = splitOutsideParenthesesAndArrays(path);
|
|
62
|
+
this.pathPartsCache.set(path, pathParts);
|
|
63
|
+
return pathParts;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Joins path parts back into a schema path string.
|
|
68
|
+
* Results are cached for performance.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* joinPathParts(['user', 'profile', 'name']) // 'user.profile.name'
|
|
72
|
+
*/
|
|
73
|
+
joinPathParts(pathParts: readonly string[]): string {
|
|
74
|
+
const cacheKey = pathParts.join('|');
|
|
75
|
+
if (this.pathJoinCache.has(cacheKey)) {
|
|
76
|
+
return this.pathJoinCache.get(cacheKey)!;
|
|
77
|
+
}
|
|
78
|
+
const result = joinParenthesesAndArrays(pathParts as string[]);
|
|
79
|
+
this.pathJoinCache.set(cacheKey, result);
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Validates whether a string is a valid schema path.
|
|
85
|
+
* Results are cached for performance since this is called very frequently.
|
|
86
|
+
* Rejects:
|
|
87
|
+
* - Non-strings
|
|
88
|
+
* - Empty strings
|
|
89
|
+
* - Boolean literals ('true', 'false')
|
|
90
|
+
* - Numeric strings
|
|
91
|
+
* - Quoted strings (starting with ' or ")
|
|
92
|
+
* - Paths containing whitespace outside of brackets
|
|
93
|
+
*/
|
|
94
|
+
isValidPath(path: string): boolean {
|
|
95
|
+
// Quick type checks (not cacheable)
|
|
96
|
+
if (typeof path !== 'string' || !path) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Check cache first
|
|
101
|
+
if (this.isValidPathCache.has(path)) {
|
|
102
|
+
return this.isValidPathCache.get(path)!;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Compute validity
|
|
106
|
+
let result = true;
|
|
107
|
+
|
|
108
|
+
if (path === 'true' || path === 'false') {
|
|
109
|
+
result = false;
|
|
110
|
+
} else if (!isNaN(Number(path))) {
|
|
111
|
+
result = false;
|
|
112
|
+
} else if (path.charCodeAt(0) === 39 || path.charCodeAt(0) === 34) {
|
|
113
|
+
// Check for ' (39) or " (34) at start - faster than regex
|
|
114
|
+
result = false;
|
|
115
|
+
} else {
|
|
116
|
+
// Check for whitespace in path parts
|
|
117
|
+
result = this.splitPath(path).every((part) => {
|
|
118
|
+
const cleaned = cleanOutBoundary(
|
|
119
|
+
cleanOutBoundary(cleanOutBoundary(part, '<', '>'), '[', ']'),
|
|
120
|
+
);
|
|
121
|
+
// Use indexOf instead of regex for speed
|
|
122
|
+
return (
|
|
123
|
+
cleaned.indexOf(' ') === -1 &&
|
|
124
|
+
cleaned.indexOf('\t') === -1 &&
|
|
125
|
+
cleaned.indexOf('\n') === -1
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this.isValidPathCache.set(path, result);
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Strips generic type parameters from a name.
|
|
136
|
+
* Cached for performance since this is called frequently.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* stripGenerics('MyComponent<Props>') // 'MyComponent'
|
|
140
|
+
* stripGenerics('Array<T>') // 'Array'
|
|
141
|
+
* stripGenerics('Simple') // 'Simple'
|
|
142
|
+
*/
|
|
143
|
+
stripGenerics(name: string): string {
|
|
144
|
+
if (this.stripGenericsCache.has(name)) {
|
|
145
|
+
return this.stripGenericsCache.get(name)!;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Find position of '<' - if not found, return original
|
|
149
|
+
const ltIndex = name.indexOf('<');
|
|
150
|
+
const result = ltIndex === -1 ? name : name.slice(0, ltIndex);
|
|
151
|
+
|
|
152
|
+
this.stripGenericsCache.set(name, result);
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Clears all caches. Useful for testing or memory management.
|
|
158
|
+
*/
|
|
159
|
+
clearCache(): void {
|
|
160
|
+
this.pathPartsCache.clear();
|
|
161
|
+
this.pathJoinCache.clear();
|
|
162
|
+
this.isValidPathCache.clear();
|
|
163
|
+
this.stripGenericsCache.clear();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Returns cache statistics for debugging/monitoring.
|
|
168
|
+
*/
|
|
169
|
+
getCacheStats(): {
|
|
170
|
+
pathParts: number;
|
|
171
|
+
pathJoin: number;
|
|
172
|
+
isValidPath: number;
|
|
173
|
+
stripGenerics: number;
|
|
174
|
+
} {
|
|
175
|
+
return {
|
|
176
|
+
pathParts: this.pathPartsCache.size,
|
|
177
|
+
pathJoin: this.pathJoinCache.size,
|
|
178
|
+
isValidPath: this.isValidPathCache.size,
|
|
179
|
+
stripGenerics: this.stripGenericsCache.size,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Default instance for simple use cases
|
|
185
|
+
export const defaultPathManager = new PathManager();
|
|
186
|
+
|
|
187
|
+
// Convenience functions that use the default instance
|
|
188
|
+
// These can be used when a shared cache is acceptable
|
|
189
|
+
export function splitPath(path: string): readonly string[] {
|
|
190
|
+
return defaultPathManager.splitPath(path);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function joinPathParts(pathParts: readonly string[]): string {
|
|
194
|
+
return defaultPathManager.joinPathParts(pathParts);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function isValidPath(path: string): boolean {
|
|
198
|
+
return defaultPathManager.isValidPath(path);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function stripGenerics(name: string): string {
|
|
202
|
+
return defaultPathManager.stripGenerics(name);
|
|
203
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# ScopeDataStructure Helpers
|
|
2
|
+
|
|
3
|
+
This directory contains extracted helper modules from `ScopeDataStructure.ts`, the core engine for CodeYam's static analysis.
|
|
4
|
+
|
|
5
|
+
## Architecture Overview
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
9
|
+
│ ScopeDataStructure │
|
|
10
|
+
│ │
|
|
11
|
+
│ Two-Phase Analysis: │
|
|
12
|
+
│ ┌─────────────────────┐ ┌──────────────────────────────────────┐ │
|
|
13
|
+
│ │ Phase 1: Discovery │ ──▶ │ Phase 2: Schema Building │ │
|
|
14
|
+
│ │ (onlyEquivalencies) │ │ (captureCompleteSchema) │ │
|
|
15
|
+
│ └─────────────────────┘ └──────────────────────────────────────┘ │
|
|
16
|
+
│ │
|
|
17
|
+
│ Core Data Structures: │
|
|
18
|
+
│ ┌──────────────┐ ┌───────────────────┐ ┌────────────────────────┐ │
|
|
19
|
+
│ │ scopeNodes │ │ equivalencyDB │ │ externalFunctionCalls │ │
|
|
20
|
+
│ │ (per-scope) │ │ (cross-scope) │ │ (API tracking) │ │
|
|
21
|
+
│ └──────────────┘ └───────────────────┘ └────────────────────────┘ │
|
|
22
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
23
|
+
|
|
24
|
+
Helper Modules:
|
|
25
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ ┌──────────────┐
|
|
26
|
+
│ PathManager │ │ UniqueId │ │ VisitedTracker │ │ ScopeTree │
|
|
27
|
+
│ │ │ Utils │ │ │ │ Manager │
|
|
28
|
+
└─────────────┘ └─────────────┘ └─────────────────┘ └──────────────┘
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Module Index
|
|
32
|
+
|
|
33
|
+
### PathManager.ts
|
|
34
|
+
|
|
35
|
+
**Purpose**: Path string manipulation with caching.
|
|
36
|
+
|
|
37
|
+
**Key Functions**:
|
|
38
|
+
|
|
39
|
+
- `splitPath(path)` - Split `user.profile.name` → `['user', 'profile', 'name']`
|
|
40
|
+
- `joinPathParts(parts)` - Join `['user', 'id']` → `user.id`
|
|
41
|
+
- `isValidPath(path)` - Validate path format
|
|
42
|
+
|
|
43
|
+
**When to Use**: Whenever you need to parse or construct schema paths.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### uniqueIdUtils.ts
|
|
48
|
+
|
|
49
|
+
**Purpose**: Create unique identifiers for scope/path combinations.
|
|
50
|
+
|
|
51
|
+
**Key Functions**:
|
|
52
|
+
|
|
53
|
+
- `uniqueId({scopeNodeName, schemaPath, value})` - Create lookup key
|
|
54
|
+
- `uniqueScopeAndPaths(array)` - Deduplicate by scope+path
|
|
55
|
+
|
|
56
|
+
**Key Format**: `scopeNodeName::schemaPath[::value]`
|
|
57
|
+
|
|
58
|
+
**When to Use**: Building cache keys, deduplicating equivalencies.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### VisitedTracker.ts
|
|
63
|
+
|
|
64
|
+
**Purpose**: Prevent infinite loops during recursive schema traversal.
|
|
65
|
+
|
|
66
|
+
**Key Methods**:
|
|
67
|
+
|
|
68
|
+
- `checkAndMarkGlobalVisited(scope, path, value)` - Fine-grained (includes type)
|
|
69
|
+
- `checkAndMarkComplexSourceVisited(scope, path)` - Coarse (ignores type)
|
|
70
|
+
- `resetGlobalVisited()` - Called between analysis phases
|
|
71
|
+
|
|
72
|
+
**When to Use**: Inside recursive methods like `addToSchema()` or `followEquivalencies()`.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### ScopeTreeManager.ts
|
|
77
|
+
|
|
78
|
+
**Purpose**: Track parent-child relationships between function scopes.
|
|
79
|
+
|
|
80
|
+
**Key Methods**:
|
|
81
|
+
|
|
82
|
+
- `addPath(['outer', 'inner'])` - Build tree as scopes are discovered
|
|
83
|
+
- `findNode(name)` - Look up scope in hierarchy
|
|
84
|
+
- `getTree()` - Get full tree structure
|
|
85
|
+
|
|
86
|
+
**When to Use**: Understanding scope nesting, debugging scope resolution.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### selectBestValue.ts
|
|
91
|
+
|
|
92
|
+
**Purpose**: Choose the most specific type when merging schemas.
|
|
93
|
+
|
|
94
|
+
**Logic**: Prefers `'string'` over `'unknown'`, handles union types.
|
|
95
|
+
|
|
96
|
+
**When to Use**: Merging type information from multiple sources.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
### DebugTracer.ts
|
|
101
|
+
|
|
102
|
+
**Purpose**: Structured debug/trace system for selective tracing without code changes.
|
|
103
|
+
|
|
104
|
+
**Key Features**:
|
|
105
|
+
|
|
106
|
+
- `trace(label, context)` - Simple trace point
|
|
107
|
+
- `traceEnter/traceExit(label)` - Track call depth
|
|
108
|
+
- Path/scope pattern filtering - Only trace what you care about
|
|
109
|
+
- Max depth limiting - Prevent runaway output
|
|
110
|
+
|
|
111
|
+
**Example Usage**:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
const tracer = new DebugTracer({
|
|
115
|
+
enabled: true,
|
|
116
|
+
pathPatterns: [/user\.id/], // Only trace paths matching this pattern
|
|
117
|
+
maxDepth: 10,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
tracer.traceEnter('addToSchema', { path, scope: scopeNode.name });
|
|
121
|
+
// ... do work ...
|
|
122
|
+
tracer.traceExit('addToSchema', { wrote: true });
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**When to Use**: Debugging specific paths through the analysis without modifying code.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Key Concepts for Debugging
|
|
130
|
+
|
|
131
|
+
### Equivalencies
|
|
132
|
+
|
|
133
|
+
An **equivalency** connects two data paths that refer to the same data:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
// In code:
|
|
137
|
+
const { user } = props;
|
|
138
|
+
return <Name name={user.name} />;
|
|
139
|
+
|
|
140
|
+
// Creates equivalencies:
|
|
141
|
+
props.user.name ←→ user.name ←→ <Name>.props.name
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Equivalencies are stored in `scopeNode.equivalencies` as:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
{
|
|
148
|
+
'user.name': [
|
|
149
|
+
{ scopeNodeName: 'MyComponent', schemaPath: 'signature[0].user.name', ... }
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Schema Paths
|
|
155
|
+
|
|
156
|
+
Schema paths describe the shape of data:
|
|
157
|
+
|
|
158
|
+
| Path | Meaning |
|
|
159
|
+
| -------------------------------- | ------------------------------------ |
|
|
160
|
+
| `signature[0]` | First function argument |
|
|
161
|
+
| `signature[0].user.id` | `id` property of `user` in first arg |
|
|
162
|
+
| `items[].name` | `name` property of array elements |
|
|
163
|
+
| `returnValue` | Function return value |
|
|
164
|
+
| `functionCallReturnValue(fetch)` | Return value from `fetch()` call |
|
|
165
|
+
|
|
166
|
+
### The Two Phases
|
|
167
|
+
|
|
168
|
+
1. **Phase 1 (Discovery)**: `onlyEquivalencies = true`
|
|
169
|
+
- Processes all scopes
|
|
170
|
+
- Builds equivalency relationships
|
|
171
|
+
- Does NOT populate schemas
|
|
172
|
+
|
|
173
|
+
2. **Phase 2 (Schema Building)**: `captureCompleteSchema()`
|
|
174
|
+
- Resets visited tracker
|
|
175
|
+
- Follows equivalencies to build complete schemas
|
|
176
|
+
- Populates `equivalencyDatabase` for source/usage tracking
|
|
177
|
+
|
|
178
|
+
## ScopeDataStructure Debugging Methods
|
|
179
|
+
|
|
180
|
+
ScopeDataStructure includes built-in debugging helpers. These methods are accessible on any ScopeDataStructure instance:
|
|
181
|
+
|
|
182
|
+
### `explainPath(scopeName, path)`
|
|
183
|
+
|
|
184
|
+
Traces a path through equivalencies and shows where data comes from:
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const explanation = sds.explainPath('MyComponent', 'user.id');
|
|
188
|
+
// {
|
|
189
|
+
// path: 'user.id',
|
|
190
|
+
// scope: 'MyComponent',
|
|
191
|
+
// schemaValue: 'string',
|
|
192
|
+
// equivalencies: [{ scope: 'MyComponent', path: 'signature[0].user.id' }],
|
|
193
|
+
// source: { scope: 'fetchUser', path: 'functionCallReturnValue(fetch).data.user.id' }
|
|
194
|
+
// }
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### `traceEquivalencyChain(scopeName, path, maxDepth?)`
|
|
198
|
+
|
|
199
|
+
Shows the full chain of equivalencies for a path:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
const chain = sds.traceEquivalencyChain('MyComponent', 'user.id');
|
|
203
|
+
// Returns array of steps showing how the data is traced back to its source
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `findPaths(scopeName, pattern)`
|
|
207
|
+
|
|
208
|
+
Finds all paths matching a regex pattern:
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const paths = sds.findPaths('MyComponent', /user/);
|
|
212
|
+
// Returns paths containing "user" with their values and equivalency status
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### `diagnoseMissingPath(scopeName, path)`
|
|
216
|
+
|
|
217
|
+
Explains why a path might be missing from the schema:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
const diagnosis = sds.diagnoseMissingPath('MyComponent', 'user.id');
|
|
221
|
+
// { exists: false, possibleReasons: [...], suggestions: [...] }
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### `dumpState(options?)`
|
|
225
|
+
|
|
226
|
+
Dumps the current analysis state for inspection:
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const state = sds.dumpState({ includeSchemas: true, scopeFilter: 'MyComp' });
|
|
230
|
+
// { scopeCount, metrics, scopes: [...] }
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Common Debugging Patterns
|
|
236
|
+
|
|
237
|
+
### "Why is this path missing from the schema?"
|
|
238
|
+
|
|
239
|
+
**Quick approach**: Use `diagnoseMissingPath()`:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
const diagnosis = sds.diagnoseMissingPath('MyComponent', 'user.id');
|
|
243
|
+
console.log(diagnosis.possibleReasons);
|
|
244
|
+
console.log(diagnosis.suggestions);
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Manual investigation**:
|
|
248
|
+
|
|
249
|
+
1. Check if the path exists in equivalencies: `scopeNode.equivalencies[path]`
|
|
250
|
+
2. Check if it was visited: Enable debug logging in `addToSchema()`
|
|
251
|
+
3. Check if it was filtered: Look at `isValidPath()` rejections
|
|
252
|
+
|
|
253
|
+
### "Why is this type wrong?"
|
|
254
|
+
|
|
255
|
+
**Quick approach**: Use `traceEquivalencyChain()`:
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
const chain = sds.traceEquivalencyChain('MyComponent', 'user.id');
|
|
259
|
+
// Each step shows the schemaValue - find where the wrong type appears
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Manual investigation**:
|
|
263
|
+
|
|
264
|
+
1. Find where the type is set: Search for the path in `addToSchema()` calls
|
|
265
|
+
2. Check `selectBestValue()` logic: Multiple sources may be merged
|
|
266
|
+
3. Check equivalency chain: Type may come from a linked path
|
|
267
|
+
|
|
268
|
+
### "Infinite loop or hang"
|
|
269
|
+
|
|
270
|
+
1. Check `VisitedTracker` usage: Missing cycle detection?
|
|
271
|
+
2. Look for recursive equivalencies: A → B → C → A
|
|
272
|
+
3. Enable metrics: `maxEquivalencyChainDepth` tracks depth
|
|
273
|
+
|
|
274
|
+
## Testing
|
|
275
|
+
|
|
276
|
+
Each module has tests in `__tests__/`:
|
|
277
|
+
|
|
278
|
+
- `PathManager.test.ts`
|
|
279
|
+
- `uniqueIdUtils.test.ts`
|
|
280
|
+
- `VisitedTracker.test.ts`
|
|
281
|
+
- `ScopeTreeManager.test.ts`
|
|
282
|
+
- `selectBestValue.test.ts`
|
|
283
|
+
|
|
284
|
+
Run with: `npx jest packages/ai/src/lib/dataStructure/helpers`
|
|
285
|
+
|
|
286
|
+
## Adding New Helpers
|
|
287
|
+
|
|
288
|
+
When extracting new functionality:
|
|
289
|
+
|
|
290
|
+
1. **Single Responsibility**: One concept per module
|
|
291
|
+
2. **Document Context**: Explain WHY, not just WHAT
|
|
292
|
+
3. **Link Related Modules**: Help readers navigate
|
|
293
|
+
4. **Write Tests First**: Tests are documentation
|
|
294
|
+
5. **Keep Interfaces Stable**: ScopeDataStructure's public API shouldn't change
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScopeTreeManager
|
|
3
|
+
*
|
|
4
|
+
* Manages the hierarchical tree structure of scopes in the analysis.
|
|
5
|
+
* Tracks parent-child relationships between function scopes.
|
|
6
|
+
*
|
|
7
|
+
* ## Purpose
|
|
8
|
+
*
|
|
9
|
+
* When analyzing nested functions, we need to track which functions
|
|
10
|
+
* are defined inside other functions. This affects:
|
|
11
|
+
* - Variable scope inheritance (inner functions can access outer variables)
|
|
12
|
+
* - Equivalency propagation (data flows between parent and child scopes)
|
|
13
|
+
* - Schema merging (combining schemas from nested call hierarchies)
|
|
14
|
+
*
|
|
15
|
+
* ## Tree Structure Example
|
|
16
|
+
*
|
|
17
|
+
* For code like:
|
|
18
|
+
* ```typescript
|
|
19
|
+
* function outer(data) {
|
|
20
|
+
* function inner(item) {
|
|
21
|
+
* return item.name;
|
|
22
|
+
* }
|
|
23
|
+
* return data.map(inner);
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* The tree would be:
|
|
28
|
+
* ```
|
|
29
|
+
* outer
|
|
30
|
+
* └── inner
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ## Key Operations
|
|
34
|
+
*
|
|
35
|
+
* - `addPath(['outer', 'inner'])` - Builds tree as scopes are discovered
|
|
36
|
+
* - `findNode('inner')` - Locates scope node for equivalency lookups
|
|
37
|
+
* - `getTree()` - Returns full tree for debugging/visualization
|
|
38
|
+
*
|
|
39
|
+
* ## Related Modules
|
|
40
|
+
*
|
|
41
|
+
* - `ScopeDataStructure.addScopeAnalysis()` - Adds paths when processing scopes
|
|
42
|
+
* - `ScopeDataStructure.getAnalysisTree()` - Exposes tree to callers
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
export interface ScopeTreeNode {
|
|
46
|
+
name: string;
|
|
47
|
+
children: ScopeTreeNode[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const ROOT_SCOPE_NAME = 'root';
|
|
51
|
+
|
|
52
|
+
export class ScopeTreeManager {
|
|
53
|
+
private tree: ScopeTreeNode;
|
|
54
|
+
|
|
55
|
+
constructor(rootName: string = ROOT_SCOPE_NAME) {
|
|
56
|
+
this.tree = { name: rootName, children: [] };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Gets the name of the root scope.
|
|
61
|
+
* This is frequently used as the default scope name throughout the analysis.
|
|
62
|
+
*/
|
|
63
|
+
getRootName(): string {
|
|
64
|
+
return this.tree.name;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Sets the name of the root scope.
|
|
69
|
+
* Called during initialization when the actual root scope name is known.
|
|
70
|
+
*/
|
|
71
|
+
setRootName(name: string): void {
|
|
72
|
+
this.tree.name = name;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Gets the entire tree structure.
|
|
77
|
+
* Used by getAnalysisTree() to return the scope hierarchy.
|
|
78
|
+
*/
|
|
79
|
+
getTree(): ScopeTreeNode {
|
|
80
|
+
return this.tree;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Adds a scope path to the tree.
|
|
85
|
+
* Creates intermediate nodes as needed.
|
|
86
|
+
*
|
|
87
|
+
* @param pathParts - Array of scope names representing the path from root
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* // For a nested function: root -> parentFunc -> childFunc
|
|
91
|
+
* addPath(['root', 'parentFunc', 'childFunc'])
|
|
92
|
+
*/
|
|
93
|
+
addPath(pathParts: string[]): void {
|
|
94
|
+
let currentNode: { children: ScopeTreeNode[] } = { children: [this.tree] };
|
|
95
|
+
|
|
96
|
+
for (const pathPart of pathParts) {
|
|
97
|
+
const existingChild = currentNode.children.find(
|
|
98
|
+
(child) => child.name === pathPart,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
if (existingChild) {
|
|
102
|
+
currentNode = existingChild;
|
|
103
|
+
} else {
|
|
104
|
+
const newChild: ScopeTreeNode = {
|
|
105
|
+
name: pathPart,
|
|
106
|
+
children: [],
|
|
107
|
+
};
|
|
108
|
+
currentNode.children.push(newChild);
|
|
109
|
+
currentNode = newChild;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Finds a node by name in the tree (breadth-first search).
|
|
116
|
+
* Returns undefined if not found.
|
|
117
|
+
*/
|
|
118
|
+
findNode(name: string): ScopeTreeNode | undefined {
|
|
119
|
+
const queue: ScopeTreeNode[] = [this.tree];
|
|
120
|
+
|
|
121
|
+
while (queue.length > 0) {
|
|
122
|
+
const node = queue.shift()!;
|
|
123
|
+
if (node.name === name) {
|
|
124
|
+
return node;
|
|
125
|
+
}
|
|
126
|
+
queue.push(...node.children);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Gets all scope names in the tree (flattened).
|
|
134
|
+
*/
|
|
135
|
+
getAllNames(): string[] {
|
|
136
|
+
const names: string[] = [];
|
|
137
|
+
const queue: ScopeTreeNode[] = [this.tree];
|
|
138
|
+
|
|
139
|
+
while (queue.length > 0) {
|
|
140
|
+
const node = queue.shift()!;
|
|
141
|
+
names.push(node.name);
|
|
142
|
+
queue.push(...node.children);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return names;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Returns the depth of the tree (for debugging/metrics).
|
|
150
|
+
*/
|
|
151
|
+
getDepth(): number {
|
|
152
|
+
const getNodeDepth = (node: ScopeTreeNode): number => {
|
|
153
|
+
if (node.children.length === 0) {
|
|
154
|
+
return 1;
|
|
155
|
+
}
|
|
156
|
+
return 1 + Math.max(...node.children.map(getNodeDepth));
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
return getNodeDepth(this.tree);
|
|
160
|
+
}
|
|
161
|
+
}
|