@codeyam/codeyam-cli 0.1.0-staging.596f0eb → 0.1.0-staging.76566f9
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 +2 -1
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +2 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +22 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.ts +23 -1
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +401 -106
- package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +60 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +734 -45
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +2 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.ts +715 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +233 -75
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +19 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +34 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +23 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.ts +98 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +34 -1
- package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +236 -24
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityKeyAttributes.ts +18 -1
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarioData.ts +41 -0
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +37 -4
- package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +5 -0
- package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +213 -12
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +36 -25
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +114 -11
- package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +143 -31
- package/analyzer-template/packages/ai/src/lib/guessScenarioDataFromDescription.ts +8 -2
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +7 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +42 -2
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +38 -2
- package/analyzer-template/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.ts +28 -2
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +5 -0
- package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +8 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +127 -43
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +158 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +405 -45
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.ts +1 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +260 -133
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +10 -5
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +77 -83
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +2 -5
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +196 -86
- package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts +15 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts.map +1 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js +31 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js.map +1 -0
- package/analyzer-template/packages/aws/package.json +1 -1
- package/analyzer-template/packages/aws/s3/index.ts +1 -0
- package/analyzer-template/packages/aws/src/lib/s3/checkS3ObjectExists.ts +47 -0
- package/analyzer-template/packages/database/src/lib/kysely/db.ts +4 -4
- package/analyzer-template/packages/database/src/lib/kysely/tableRelations.ts +2 -2
- package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +20 -9
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.ts +9 -4
- package/analyzer-template/packages/generate/src/lib/deepMerge.ts +26 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -2
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +2 -2
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tableRelations.d.ts +2 -2
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts +8 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +14 -7
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js +27 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/index.d.ts +4 -3
- package/analyzer-template/packages/github/dist/types/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/index.js +1 -0
- package/analyzer-template/packages/github/dist/types/index.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts +31 -1
- package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +51 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.js +21 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +48 -0
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js +25 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/analyzer-template/packages/types/index.ts +8 -0
- package/analyzer-template/packages/types/src/types/Analysis.ts +32 -1
- package/analyzer-template/packages/types/src/types/Scenario.ts +75 -6
- package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +49 -0
- package/analyzer-template/packages/ui-components/src/components/ScenarioDetailInteractiveView.tsx +23 -7
- package/analyzer-template/packages/utils/dist/types/index.d.ts +4 -3
- package/analyzer-template/packages/utils/dist/types/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/index.js +1 -0
- package/analyzer-template/packages/utils/dist/types/index.js.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts +31 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +51 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.js +21 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.js.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +48 -0
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js +25 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/analyzer-template/packages/utils/src/lib/lightweightEntityExtractor.ts +27 -0
- package/analyzer-template/playwright/takeElementScreenshot.ts +26 -11
- package/analyzer-template/playwright/takeScreenshot.ts +9 -7
- package/analyzer-template/project/constructMockCode.ts +286 -84
- package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +77 -37
- package/analyzer-template/project/reconcileMockDataKeys.ts +5 -2
- package/analyzer-template/project/runMultiScenarioServer.ts +11 -10
- package/analyzer-template/project/serverOnlyModules.ts +71 -23
- package/analyzer-template/project/start.ts +10 -0
- package/analyzer-template/project/startScenarioCapture.ts +73 -41
- package/analyzer-template/project/writeMockDataTsx.ts +115 -54
- package/analyzer-template/project/writeScenarioComponents.ts +571 -162
- package/analyzer-template/project/writeSimpleRoot.ts +11 -13
- package/background/src/lib/virtualized/project/constructMockCode.js +265 -75
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +67 -32
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +5 -2
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
- package/background/src/lib/virtualized/project/runMultiScenarioServer.js +11 -9
- package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
- package/background/src/lib/virtualized/project/serverOnlyModules.js +62 -25
- package/background/src/lib/virtualized/project/serverOnlyModules.js.map +1 -1
- package/background/src/lib/virtualized/project/start.js +6 -0
- package/background/src/lib/virtualized/project/start.js.map +1 -1
- package/background/src/lib/virtualized/project/startScenarioCapture.js +54 -31
- package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +106 -46
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +399 -106
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeSimpleRoot.js +11 -11
- package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
- package/codeyam-cli/src/cli.js +2 -0
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/commands/debug.js +14 -2
- package/codeyam-cli/src/commands/debug.js.map +1 -1
- package/codeyam-cli/src/commands/recapture.js +215 -0
- package/codeyam-cli/src/commands/recapture.js.map +1 -0
- package/codeyam-cli/src/commands/report.js +26 -23
- package/codeyam-cli/src/commands/report.js.map +1 -1
- package/codeyam-cli/src/utils/backgroundServer.js +2 -2
- package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/utils/generateReport.js +252 -106
- package/codeyam-cli/src/utils/generateReport.js.map +1 -1
- package/codeyam-cli/src/utils/install-skills.js +2 -2
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/queue/__tests__/manager.test.js +38 -0
- package/codeyam-cli/src/utils/queue/__tests__/manager.test.js.map +1 -1
- package/codeyam-cli/src/utils/queue/job.js +140 -16
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/queue/manager.js +19 -7
- package/codeyam-cli/src/utils/queue/manager.js.map +1 -1
- package/codeyam-cli/src/utils/queue/persistence.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js +47 -0
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
- package/codeyam-cli/src/webserver/backgroundServer.js +5 -10
- package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/webserver/bootstrap.js +9 -0
- package/codeyam-cli/src/webserver/bootstrap.js.map +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-wXL1Z2Aq.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-efWKDYMr.js → EntityTypeBadge-CzGX-miz.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-CXFKsCOD.js +41 -0
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-D-9pXIaY.js +25 -0
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-CBQPrpT0.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/LoadingDots-D1CdlbrV.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/LogViewer-wDPcZNKx.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-4lcOlid-.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BfmDgXxG.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-CUxUNEEC.js +15 -0
- package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-COPstp9J.js → TruncatedFilePath-6J7zDUD5.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/_index-DHImXdXq.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-CVP_WGQ3.js +32 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.link-scenario-value-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.update-key-attributes-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.update-valid-values-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/chevron-down-BYimnrHg.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/chunk-JMJ3UQ3L-BambyYE_.js +51 -0
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-CaVsIRxt.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CgUsG7ib.js +21 -0
- package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-CKnwPCDr.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DW_hdGUc.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-Dt-SjPsw.js +23 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DyB90fWk.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-D_3ero5o.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-CfLCUi9S.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-DKJyZfAY.js +29 -0
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-DAtOlaWE.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/files-ClR0d32A.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/git-D62Lxxmv.js +15 -0
- package/codeyam-cli/src/webserver/build/client/assets/globals-C9s7Lhdl.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-fmIEn3Bc.js +9 -0
- package/codeyam-cli/src/webserver/build/client/assets/index-BosqDOlH.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/index-CzNNiTkw.js +9 -0
- package/codeyam-cli/src/webserver/build/client/assets/keyAttributeCoverage-CTlFMihX.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-CNp9QFCX.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/manifest-0d27da29.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/preload-helper-ckwbz45p.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-B_wIKCIf.js +56 -0
- package/codeyam-cli/src/webserver/build/client/assets/scenarioStatus-B_8jpV3e.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/search-DDGjYAMJ.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/settings-DgTyB-Wg.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/simulations-CoNWGt0K.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-CBc5dE1s.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-BMIGFP-m.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/useInteractiveMode-Dk_FQqWJ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-3pmpUQB-.js → useLastLogLine-BqPPNjAl.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-DsJbgMY9.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-DEyawJ8r.js → useToast-DWHcCcl1.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-CU58-Ttc.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-D35o2uae.js +175 -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/devServer.js +1 -3
- package/codeyam-cli/src/webserver/devServer.js.map +1 -1
- package/codeyam-cli/templates/codeyam-setup-skill.md +138 -3
- package/codeyam-cli/templates/debug-codeyam.md +625 -0
- package/package.json +14 -14
- package/packages/ai/src/lib/analyzeScope.js +2 -0
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +16 -0
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js +16 -0
- package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +305 -88
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +582 -41
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +2 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js +454 -0
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +173 -55
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +16 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +30 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +20 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.js +86 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +28 -2
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +179 -17
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js +6 -0
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js +41 -0
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarios.js +37 -4
- package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDataStructure.js +4 -0
- package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
- package/packages/ai/src/lib/generateEntityKeyAttributes.js +176 -9
- package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +29 -25
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +105 -9
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js +84 -14
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
- package/packages/ai/src/lib/guessScenarioDataFromDescription.js +2 -1
- package/packages/ai/src/lib/guessScenarioDataFromDescription.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +6 -0
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +38 -2
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +38 -2
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js +16 -3
- package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js.map +1 -1
- package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
- package/packages/ai/src/lib/worker/analyzeScopeWorker.js +4 -0
- package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +100 -23
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +125 -0
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +298 -45
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +201 -80
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +10 -5
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +55 -69
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +2 -5
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +171 -81
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/database/src/lib/kysely/db.js +2 -2
- package/packages/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
- package/packages/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
- package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
- package/packages/generate/src/lib/deepMerge.js +27 -1
- package/packages/generate/src/lib/deepMerge.js.map +1 -1
- package/packages/types/index.js +1 -0
- package/packages/types/index.js.map +1 -1
- package/packages/types/src/types/Scenario.js +21 -1
- package/packages/types/src/types/Scenario.js.map +1 -1
- package/packages/utils/src/lib/lightweightEntityExtractor.js +25 -0
- package/packages/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/scripts/finalize-analyzer.cjs +3 -1
- package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js +0 -238
- package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js.map +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-CVbSvOjo.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-DcwcHyl5.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-WgwC1GfJ.js +0 -26
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-IEKom9O2.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/LogViewer-BYnfxbUG.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-_lBPJCzG.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-lHVhvsu_.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-d_TBk4GQ.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/_index-kGT7VUqj.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-DDGmhu7P.js +0 -7
- package/codeyam-cli/src/webserver/build/client/assets/chevron-down-n_HPRfM_.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-CbVoyx1U.js +0 -26
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-D1VOYveA.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-YR8jjAlu.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-B8vP3V_s.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-CN6aLCT1.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-DA5Jeu2P.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-BTeitalf.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-du6UEYD-.js +0 -13
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-BpjkhMoi.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-BQGvk4lJ.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-DVdYRT-I.js +0 -12
- package/codeyam-cli/src/webserver/build/client/assets/globals-CO-U8Bpo.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/index-DCG-vks0.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-GazdNeLl.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-0b694d28.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-D3tQP7hx.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/search-CIY6XmtE.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/server-build-CMKNK2uU.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-CoMDgElu.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-agkniXp2.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-B2VUcygF.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-EvdK-zXP.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-DGVHQEXD.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-CghkTkIL.js +0 -166
- package/codeyam-cli/templates/debug-command.md +0 -303
- /package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CMKNK2uU.css → styles-CMKNK2uU.css} +0 -0
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import completionCall from './completionCall';
|
|
2
2
|
import { saveLlmCall } from '~codeyam/aws/dynamodb';
|
|
3
|
-
import { DataStructure, Entity } from '~codeyam/types';
|
|
3
|
+
import { DataStructure, Entity, SourceLocation } from '~codeyam/types';
|
|
4
4
|
import generateEntityKeyAttributesGenerator from './promptGenerators/generateEntityKeyAttributesGenerator';
|
|
5
5
|
import { awsLog } from '~codeyam/utils';
|
|
6
6
|
import { DEFAULT_LARGER_MODEL } from './aiConfig';
|
|
7
7
|
import { gatherAttributesMap } from './promptGenerators/gatherAttributesMap';
|
|
8
8
|
import { fillInDirectSchemaGapsAndUnknowns } from './dataStructure/helpers/fillInSchemaGapsAndUnknowns';
|
|
9
|
+
import { clearAttributesFromMapping } from './dataStructure/helpers/cleanNonObjectFunctions';
|
|
9
10
|
import isFrontend from './isFrontend';
|
|
10
11
|
import { AI } from '~codeyam/ai';
|
|
11
12
|
import { formatConditionalUsagesForPrompt } from './getConditionalUsagesFromCode';
|
|
12
|
-
import type { ConditionalUsage } from '~codeyam/types';
|
|
13
|
+
import type { CompoundConditional, ConditionalUsage } from '~codeyam/types';
|
|
13
14
|
|
|
14
15
|
interface GenerateEntityKeyAttributesArgs {
|
|
15
16
|
entity: Pick<Entity, 'sha' | 'name' | 'filePath' | 'code' | 'metadata'>;
|
|
@@ -38,6 +39,11 @@ export default async function generateEntityKeyAttributes({
|
|
|
38
39
|
true,
|
|
39
40
|
);
|
|
40
41
|
|
|
42
|
+
// Clean the attributes map to remove primitive-returning array method paths
|
|
43
|
+
// like .includes().functionCallReturnValue, .indexOf().functionCallReturnValue, etc.
|
|
44
|
+
// These paths are not mockable and should not be presented as key attributes.
|
|
45
|
+
clearAttributesFromMapping(attributesMap);
|
|
46
|
+
|
|
41
47
|
if (Object.keys(attributesMap).length === 0) {
|
|
42
48
|
console.log(
|
|
43
49
|
`CodeYam Error: No valid attributes found for ${entity.filePath} ${entity.name}`,
|
|
@@ -48,17 +54,31 @@ export default async function generateEntityKeyAttributes({
|
|
|
48
54
|
};
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
// Build merged schema for type inference (has more complete nested paths)
|
|
58
|
+
// Strip signature[N] prefix to match attributesMap format
|
|
59
|
+
const mergedSchemaForTypeLookup = Object.fromEntries(
|
|
60
|
+
Object.entries(mergedDataStructure.signatureSchema ?? {})
|
|
61
|
+
.filter(([k]) => k.startsWith('signature['))
|
|
62
|
+
.map(([k, v]) => [k.replace(/^signature\[\d+\]\./, ''), v]),
|
|
63
|
+
);
|
|
64
|
+
|
|
51
65
|
// Resolve unknown types using heuristics (e.g., "unknown | undefined" -> "string | undefined")
|
|
66
|
+
// Pass mergedSchema so checkIfObjectOrFunction can detect nested paths that prove a type is an object
|
|
52
67
|
const resolvedAttributesMap = fillInDirectSchemaGapsAndUnknowns({
|
|
53
68
|
scopeName: entity.name,
|
|
54
69
|
schema: { ...attributesMap },
|
|
70
|
+
mergedSchema: mergedSchemaForTypeLookup,
|
|
55
71
|
});
|
|
56
72
|
|
|
57
73
|
// Use pre-computed conditional usages from metadata, or compute on-the-fly as fallback
|
|
58
74
|
const conditionalUsages: Record<string, ConditionalUsage[]> =
|
|
59
75
|
entity.metadata?.isolatedDataStructure?.conditionalUsages ?? {};
|
|
60
|
-
const
|
|
61
|
-
|
|
76
|
+
const compoundConditionals: CompoundConditional[] =
|
|
77
|
+
entity.metadata?.isolatedDataStructure?.compoundConditionals ?? [];
|
|
78
|
+
const staticAnalysisContext = formatConditionalUsagesForPrompt(
|
|
79
|
+
conditionalUsages,
|
|
80
|
+
compoundConditionals,
|
|
81
|
+
);
|
|
62
82
|
|
|
63
83
|
const prompt = generateEntityKeyAttributesGenerator({
|
|
64
84
|
code: entity.code,
|
|
@@ -133,6 +153,106 @@ export default async function generateEntityKeyAttributes({
|
|
|
133
153
|
]),
|
|
134
154
|
);
|
|
135
155
|
|
|
156
|
+
// Helper to extract source locations from conditional usages for a given path
|
|
157
|
+
const getSourceLocationsForPath = (path: string): SourceLocation[] => {
|
|
158
|
+
const usages = conditionalUsages[path] || [];
|
|
159
|
+
const locations: SourceLocation[] = [];
|
|
160
|
+
|
|
161
|
+
for (const usage of usages.slice(0, 5)) {
|
|
162
|
+
// Limit to 5 locations
|
|
163
|
+
if (usage.sourceLocation) {
|
|
164
|
+
locations.push({
|
|
165
|
+
entityName: entity.name,
|
|
166
|
+
filePath: entity.filePath,
|
|
167
|
+
lineNumber: usage.sourceLocation.lineNumber,
|
|
168
|
+
column: usage.sourceLocation.column,
|
|
169
|
+
codeSnippet: usage.sourceLocation.codeSnippet,
|
|
170
|
+
usageType: 'conditional',
|
|
171
|
+
description: `Used in ${usage.location} statement (${usage.conditionType} check)`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return locations;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// Helper to find source locations by matching sourceDataPath
|
|
180
|
+
// This handles cases where local variables (e.g., displayState.hasError) trace back
|
|
181
|
+
// to data structure paths (e.g., getScenarioDisplayState().functionCallReturnValue.hasError)
|
|
182
|
+
const getSourceLocationsBySourceDataPath = (
|
|
183
|
+
targetPath: string,
|
|
184
|
+
): SourceLocation[] => {
|
|
185
|
+
const locations: SourceLocation[] = [];
|
|
186
|
+
|
|
187
|
+
// Search all conditional usages for ones whose sourceDataPath matches
|
|
188
|
+
for (const [, usages] of Object.entries(conditionalUsages)) {
|
|
189
|
+
for (const usage of usages) {
|
|
190
|
+
const sourceDataPath = (usage as { sourceDataPath?: string })
|
|
191
|
+
.sourceDataPath;
|
|
192
|
+
if (!sourceDataPath || !usage.sourceLocation) continue;
|
|
193
|
+
|
|
194
|
+
// Check if sourceDataPath ends with the target path
|
|
195
|
+
// e.g., "LibraryFunctionPreview.signature[0].isOutdated" ends with "isOutdated"
|
|
196
|
+
// or "getScenarioDisplayState.getScenarioDisplayState(...).functionCallReturnValue.hasError" ends with "hasError"
|
|
197
|
+
const normalizedSourcePath = sourceDataPath
|
|
198
|
+
.replace(/\.functionCallReturnValue/g, '')
|
|
199
|
+
.replace(/\([^)]*\)/g, '()');
|
|
200
|
+
|
|
201
|
+
if (
|
|
202
|
+
normalizedSourcePath.endsWith('.' + targetPath) ||
|
|
203
|
+
normalizedSourcePath.endsWith('.' + targetPath.replace(/\./g, '.'))
|
|
204
|
+
) {
|
|
205
|
+
locations.push({
|
|
206
|
+
entityName: entity.name,
|
|
207
|
+
filePath: entity.filePath,
|
|
208
|
+
lineNumber: usage.sourceLocation.lineNumber,
|
|
209
|
+
column: usage.sourceLocation.column,
|
|
210
|
+
codeSnippet: usage.sourceLocation.codeSnippet,
|
|
211
|
+
usageType: 'conditional',
|
|
212
|
+
description: `Used in ${usage.location} statement (${usage.conditionType} check)`,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return locations.slice(0, 5); // Limit to 5
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// Helper to find source locations from LLM-provided code snippets
|
|
222
|
+
const getSourceLocationsFromSnippets = (
|
|
223
|
+
codeSnippets: string[] | undefined,
|
|
224
|
+
): SourceLocation[] => {
|
|
225
|
+
if (!codeSnippets || !Array.isArray(codeSnippets)) return [];
|
|
226
|
+
|
|
227
|
+
const locations: SourceLocation[] = [];
|
|
228
|
+
const codeLines = entity.code.split('\n');
|
|
229
|
+
|
|
230
|
+
for (const snippet of codeSnippets.slice(0, 3)) {
|
|
231
|
+
// Limit to 3 snippets
|
|
232
|
+
if (!snippet || typeof snippet !== 'string') continue;
|
|
233
|
+
|
|
234
|
+
// Normalize whitespace for matching
|
|
235
|
+
const normalizedSnippet = snippet.trim().replace(/\s+/g, ' ');
|
|
236
|
+
|
|
237
|
+
for (let i = 0; i < codeLines.length; i++) {
|
|
238
|
+
const normalizedLine = codeLines[i].replace(/\s+/g, ' ');
|
|
239
|
+
if (normalizedLine.includes(normalizedSnippet)) {
|
|
240
|
+
locations.push({
|
|
241
|
+
entityName: entity.name,
|
|
242
|
+
filePath: entity.filePath,
|
|
243
|
+
lineNumber: i + 1, // 1-based line numbers
|
|
244
|
+
codeSnippet: codeLines[i].trim(),
|
|
245
|
+
usageType: 'conditional',
|
|
246
|
+
description: `Key usage identified by analysis`,
|
|
247
|
+
});
|
|
248
|
+
break; // Only find first occurrence of each snippet
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return locations;
|
|
254
|
+
};
|
|
255
|
+
|
|
136
256
|
const fullKeyAttributes = keyAttributes
|
|
137
257
|
.filter(Boolean)
|
|
138
258
|
.filter(
|
|
@@ -144,6 +264,46 @@ export default async function generateEntityKeyAttributes({
|
|
|
144
264
|
.filter((keyAttribute) => fullPathToInternalPath[keyAttribute.fullPath])
|
|
145
265
|
.map((keyAttribute) => {
|
|
146
266
|
const internalPath = fullPathToInternalPath[keyAttribute.fullPath];
|
|
267
|
+
|
|
268
|
+
// Get source locations from conditional usages
|
|
269
|
+
// Try multiple path formats since conditionalUsages might use different formats:
|
|
270
|
+
// - internalPath: the short path like "status"
|
|
271
|
+
// - fullPath: the LLM's path like "signature[0].status"
|
|
272
|
+
// - dataStructurePath: the external path like "useStatus().status"
|
|
273
|
+
// - Also try stripping signature[N] prefix since conditional usages use AST paths
|
|
274
|
+
let sourceLocations = getSourceLocationsForPath(internalPath);
|
|
275
|
+
if (sourceLocations.length === 0) {
|
|
276
|
+
sourceLocations = getSourceLocationsForPath(keyAttribute.fullPath);
|
|
277
|
+
}
|
|
278
|
+
if (sourceLocations.length === 0) {
|
|
279
|
+
const dataStructurePath =
|
|
280
|
+
dataStructurePathMap[internalPath] || keyAttribute.fullPath;
|
|
281
|
+
sourceLocations = getSourceLocationsForPath(dataStructurePath);
|
|
282
|
+
}
|
|
283
|
+
// Also try the path without signature[N] prefix since AST uses local variable names
|
|
284
|
+
if (sourceLocations.length === 0) {
|
|
285
|
+
const pathWithoutSignature = internalPath.replace(
|
|
286
|
+
/^signature\[\d+\]\./,
|
|
287
|
+
'',
|
|
288
|
+
);
|
|
289
|
+
if (pathWithoutSignature !== internalPath) {
|
|
290
|
+
sourceLocations = getSourceLocationsForPath(pathWithoutSignature);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Finally, search by sourceDataPath which traces local variables back to data sources
|
|
294
|
+
// This handles cases like displayState.hasError → getScenarioDisplayState().hasError
|
|
295
|
+
if (sourceLocations.length === 0) {
|
|
296
|
+
sourceLocations = getSourceLocationsBySourceDataPath(internalPath);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Last resort: use LLM-provided code snippets to find source locations
|
|
300
|
+
// This ensures every key attribute the LLM identifies has a source location
|
|
301
|
+
if (sourceLocations.length === 0 && keyAttribute.codeSnippets) {
|
|
302
|
+
sourceLocations = getSourceLocationsFromSnippets(
|
|
303
|
+
keyAttribute.codeSnippets,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
147
307
|
return {
|
|
148
308
|
internalPath,
|
|
149
309
|
externalPath: associationMap[internalPath],
|
|
@@ -155,6 +315,9 @@ export default async function generateEntityKeyAttributes({
|
|
|
155
315
|
// Preserve new fields from LLM response
|
|
156
316
|
valueType: keyAttribute.valueType,
|
|
157
317
|
dependencies: keyAttribute.dependencies,
|
|
318
|
+
// Add source locations from static analysis or LLM snippets
|
|
319
|
+
sourceLocations:
|
|
320
|
+
sourceLocations.length > 0 ? sourceLocations : undefined,
|
|
158
321
|
};
|
|
159
322
|
});
|
|
160
323
|
|
|
@@ -184,15 +347,31 @@ NOT key attributes:
|
|
|
184
347
|
|
|
185
348
|
We've provided a list of variables that are used in conditional statements in the code. These are very likely key attributes.
|
|
186
349
|
|
|
187
|
-
Each conditional lists
|
|
350
|
+
Each conditional lists its source and how it is used. This should help you identify which attributes to include and what values to suggest.
|
|
351
|
+
|
|
352
|
+
**IMPORTANT**: Only include attributes with explicit evidence of impact in THIS code:
|
|
353
|
+
- Used directly in a conditional statement (if/ternary/switch)
|
|
354
|
+
- Displayed or rendered directly (e.g., text content, list length)
|
|
355
|
+
- Used in a computation that affects rendering
|
|
356
|
+
|
|
357
|
+
Do NOT include attributes that are only passed as arguments to other functions without direct usage here. We analyze those functions separately and merge their key attributes automatically.
|
|
188
358
|
|
|
189
359
|
## Path Format
|
|
190
360
|
|
|
191
361
|
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[]\`).
|
|
192
362
|
|
|
193
|
-
## Dependencies
|
|
363
|
+
## Dependencies and Compound Conditionals
|
|
364
|
+
|
|
365
|
+
When attributes are used in && chains (compound conditionals), they form dependencies on each other:
|
|
366
|
+
- Each attribute in the chain only has effect when ALL other conditions in the chain are satisfied
|
|
367
|
+
- Include these as dependencies with the required value for the code path to execute
|
|
194
368
|
|
|
195
|
-
|
|
369
|
+
Example: For \`a && b && !c\`:
|
|
370
|
+
- \`a\` has dependencies: \`b\` must be truthy, \`c\` must be falsy
|
|
371
|
+
- \`b\` has dependencies: \`a\` must be truthy, \`c\` must be falsy
|
|
372
|
+
- \`c\` has dependencies: \`a\` must be truthy, \`b\` must be truthy (for the falsy check to matter)
|
|
373
|
+
|
|
374
|
+
The static analysis section may show "Compound Conditionals" that list which conditions must be true together. Use this to populate the \`dependencies\` array with \`{ "path": "...", "requiredValue": "..." }\` entries.
|
|
196
375
|
|
|
197
376
|
## Value Type
|
|
198
377
|
|
|
@@ -218,8 +397,9 @@ List all key attributes in order from most impactful to least impactful regardin
|
|
|
218
397
|
{
|
|
219
398
|
"fullPath": "signature[0].user",
|
|
220
399
|
"description": "Controls whether the main form or redirect screen displays",
|
|
400
|
+
"codeSnippets": ["if (!user) return <Redirect />", "user.name"],
|
|
221
401
|
"dependencies": [
|
|
222
|
-
"signature[0].projectId": "must be a valid project ID for 'user' to have effect"
|
|
402
|
+
{ "path": "signature[0].projectId", "requiredValue": "truthy", "description": "must be a valid project ID for 'user' to have effect" }
|
|
223
403
|
],
|
|
224
404
|
"valueType": "object",
|
|
225
405
|
"validValueOptions": ["an empty object {}", "null/undefined"]
|
|
@@ -227,6 +407,8 @@ List all key attributes in order from most impactful to least impactful regardin
|
|
|
227
407
|
]
|
|
228
408
|
}
|
|
229
409
|
\`\`\`
|
|
410
|
+
|
|
411
|
+
The \`codeSnippets\` field is required - provide 1-3 short code excerpts (under 80 chars each) showing exactly where and how this attribute is used. These snippets must appear verbatim in the code.
|
|
230
412
|
`;
|
|
231
413
|
|
|
232
414
|
const BACKEND_SYSTEM_MESSAGE = `You analyze backend functions to identify key data attributes that significantly impact behavior.
|
|
@@ -248,15 +430,31 @@ NOT key attributes:
|
|
|
248
430
|
|
|
249
431
|
We've provided a list of variables that are used in conditional statements in the code. These are very likely key attributes.
|
|
250
432
|
|
|
251
|
-
Each conditional lists
|
|
433
|
+
Each conditional lists its source and how it is used. This should help you identify which attributes to include and what values to suggest.
|
|
434
|
+
|
|
435
|
+
**IMPORTANT**: Only include attributes with explicit evidence of impact in THIS code:
|
|
436
|
+
- Used directly in a conditional statement (if/ternary/switch)
|
|
437
|
+
- Displayed or rendered directly (e.g., text content, list length)
|
|
438
|
+
- Used in a computation that affects rendering
|
|
439
|
+
|
|
440
|
+
Do NOT include attributes that are only passed as arguments to other functions without direct usage here. We analyze those functions separately and merge their key attributes automatically.
|
|
252
441
|
|
|
253
442
|
## Path Format
|
|
254
443
|
|
|
255
444
|
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[]\`).
|
|
256
445
|
|
|
257
|
-
## Dependencies
|
|
446
|
+
## Dependencies and Compound Conditionals
|
|
258
447
|
|
|
259
|
-
|
|
448
|
+
When attributes are used in && chains (compound conditionals), they form dependencies on each other:
|
|
449
|
+
- Each attribute in the chain only has effect when ALL other conditions in the chain are satisfied
|
|
450
|
+
- Include these as dependencies with the required value for the code path to execute
|
|
451
|
+
|
|
452
|
+
Example: For \`a && b && !c\`:
|
|
453
|
+
- \`a\` has dependencies: \`b\` must be truthy, \`c\` must be falsy
|
|
454
|
+
- \`b\` has dependencies: \`a\` must be truthy, \`c\` must be falsy
|
|
455
|
+
- \`c\` has dependencies: \`a\` must be truthy, \`b\` must be truthy (for the falsy check to matter)
|
|
456
|
+
|
|
457
|
+
The static analysis section may show "Compound Conditionals" that list which conditions must be true together. Use this to populate the \`dependencies\` array with \`{ "path": "...", "requiredValue": "..." }\` entries.
|
|
260
458
|
|
|
261
459
|
## Value Type
|
|
262
460
|
|
|
@@ -282,8 +480,9 @@ List all key attributes in order from most impactful to least impactful using th
|
|
|
282
480
|
{
|
|
283
481
|
"fullPath": "signature[0].config.enabled",
|
|
284
482
|
"description": "Controls whether the main processing logic runs",
|
|
483
|
+
"codeSnippets": ["if (!config.enabled) return", "enabled && processData()"],
|
|
285
484
|
"dependencies": [
|
|
286
|
-
"signature[0].analysisMode": "must be 'full' for 'enabled' to have effect"
|
|
485
|
+
{ "path": "signature[0].analysisMode", "requiredValue": "full", "description": "must be 'full' for 'enabled' to have effect" }
|
|
287
486
|
],
|
|
288
487
|
"valueType": "boolean",
|
|
289
488
|
"validValueOptions": ["true", "false"]
|
|
@@ -291,4 +490,6 @@ List all key attributes in order from most impactful to least impactful using th
|
|
|
291
490
|
]
|
|
292
491
|
}
|
|
293
492
|
\`\`\`
|
|
493
|
+
|
|
494
|
+
The \`codeSnippets\` field is required - provide 1-3 short code excerpts (under 80 chars each) showing exactly where and how this attribute is used. These snippets must appear verbatim in the code.
|
|
294
495
|
`;
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
import validateJson from './validateJson';
|
|
12
12
|
import { awsLog, awsLogDebugLevel } from '~codeyam/utils';
|
|
13
13
|
import { AI, parseJsonSafe } from '~codeyam/ai';
|
|
14
|
+
import convertNullToUndefinedBySchema from './dataStructure/helpers/convertNullToUndefinedBySchema';
|
|
14
15
|
|
|
15
16
|
const DEFAULT_SCENARIO_NAME = 'Default Scenario';
|
|
16
17
|
|
|
@@ -166,6 +167,27 @@ export async function generateDataForScenario({
|
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
|
|
170
|
+
// Convert null values to undefined based on schema type constraints.
|
|
171
|
+
// LLM uses null for "no value" (JSON doesn't support undefined), but TypeScript
|
|
172
|
+
// types like "string | undefined" don't accept null. This converts null→undefined
|
|
173
|
+
// for fields typed as "T | undefined" (but preserves null for "T | null").
|
|
174
|
+
if (structure.dataForMocks && fullScenarioData.data.mockData) {
|
|
175
|
+
convertNullToUndefinedBySchema(
|
|
176
|
+
fullScenarioData.data.mockData,
|
|
177
|
+
structure.dataForMocks,
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
if (structure.arguments && fullScenarioData.data.argumentsData) {
|
|
181
|
+
for (let i = 0; i < fullScenarioData.data.argumentsData.length; i++) {
|
|
182
|
+
if (structure.arguments[i]) {
|
|
183
|
+
convertNullToUndefinedBySchema(
|
|
184
|
+
fullScenarioData.data.argumentsData[i],
|
|
185
|
+
structure.arguments[i],
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
169
191
|
return {
|
|
170
192
|
scenarioData: fullScenarioData,
|
|
171
193
|
llmCall: { name: scenario.name, id: llmCall.id },
|
|
@@ -285,7 +307,7 @@ export const generateSystemMessage = (
|
|
|
285
307
|
? `## Default Scenario
|
|
286
308
|
Generate COMPLETE, robust data for the entire data structure.
|
|
287
309
|
- Fill ALL fields with realistic values (except error attributes and key attributes set to null or undefined)
|
|
288
|
-
- Arrays should have
|
|
310
|
+
- Arrays should have 3-5 items to provide realistic test data variety
|
|
289
311
|
- Don't skip nested attributes unless the key attributes specify a parent attribute should be null or undefined
|
|
290
312
|
- This provides the baseline data for all other scenarios`
|
|
291
313
|
: `## Non-Default Scenario
|
|
@@ -317,30 +339,19 @@ Use for relative dates. Code runs in Node (no browser APIs, no external librarie
|
|
|
317
339
|
\`\`\`
|
|
318
340
|
Use simple elements only (\`<div>\`, \`<span>\`). No custom components.
|
|
319
341
|
|
|
320
|
-
|
|
321
|
-
|
|
342
|
+
### Arrays
|
|
343
|
+
- Arrays should have many items (at least 4) unless specified otherwise
|
|
344
|
+
- Each item must follow the exact structure provided
|
|
345
|
+
- In general we want robust data, not minimal data unless specified otherwise
|
|
322
346
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
\`\`\`
|
|
332
|
-
|
|
333
|
-
### Variable-qualified calls (for multiple calls to the same function)
|
|
334
|
-
When the same function is called multiple times with results stored in different variables, keys use the format \`variableName <- functionName\`:
|
|
335
|
-
\`\`\`json
|
|
336
|
-
{
|
|
337
|
-
"mockData": {
|
|
338
|
-
"entityDiffFetcher <- useFetcher": { "data": null, "state": "idle" },
|
|
339
|
-
"reportFetcher <- useFetcher": { "data": { "reportId": "abc123" }, "state": "idle" }
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
\`\`\`
|
|
343
|
-
This reads as "entityDiffFetcher receives from useFetcher". Each variable gets its own distinct mock data.
|
|
347
|
+
## CRITICAL: Preserve Exact Structure
|
|
348
|
+
Your response MUST mirror the EXACT nested structure provided in mockData Structure.
|
|
349
|
+
- Do NOT reorganize, split, or create duplicate keys
|
|
350
|
+
- The hierarchy of nested objects must match exactly what was provided unless overridden by scenario rules
|
|
351
|
+
- Only change the leaf VALUES (replacing type descriptions like "string" with actual data like "hello")
|
|
352
|
+
- Copy the key strings EXACTLY from the structure
|
|
353
|
+
- Do NOT modify type parameters, arguments, or any part of the key
|
|
354
|
+
- The keys preserve the exact function call as written in the original code
|
|
344
355
|
|
|
345
356
|
## Response Format
|
|
346
357
|
\`\`\`json
|
|
@@ -358,7 +369,7 @@ This reads as "entityDiffFetcher receives from useFetcher". Each variable gets i
|
|
|
358
369
|
## Rules
|
|
359
370
|
- Valid JSON only—no raw code outside markers
|
|
360
371
|
- No \`undefined\`—use \`null\` or omit
|
|
361
|
-
- No data references (can't use \`posts[0]\` elsewhere—duplicate the value)
|
|
372
|
+
- No data references (can't use \`posts[0]\` elsewhere — duplicate the value)
|
|
362
373
|
- Scenario name must match exactly: "${scenarioName}"
|
|
363
374
|
- Empty mockData: \`{}\`, empty argumentsData: \`[]\`
|
|
364
375
|
`;
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
PlaywrightInstruction,
|
|
9
9
|
ReadonlyAnalysisMap,
|
|
10
10
|
Scenario,
|
|
11
|
+
ValueOptionRef,
|
|
11
12
|
} from '~codeyam/types';
|
|
12
13
|
// import findMatchingAttribute from './findMatchingAttribute';
|
|
13
14
|
import { awsLog } from '~codeyam/utils';
|
|
@@ -18,14 +19,20 @@ export interface ScenarioResult {
|
|
|
18
19
|
name: string;
|
|
19
20
|
testName: string;
|
|
20
21
|
description: string;
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Key attribute instructions with structured value references.
|
|
24
|
+
* Format: { dataStructurePath: { localVariable, instruction, valueOptionRef? } }
|
|
25
|
+
*/
|
|
23
26
|
keyAttributeInstructions: {
|
|
24
27
|
[key: string]:
|
|
25
28
|
| string
|
|
26
29
|
| {
|
|
27
30
|
localVariable: string;
|
|
28
31
|
instruction: string;
|
|
32
|
+
/** Reference to validValueOption index for tracking coverage */
|
|
33
|
+
valueOptionRef?: ValueOptionRef;
|
|
34
|
+
/** Reference to errorValueOption index for error scenarios */
|
|
35
|
+
errorOptionRef?: ValueOptionRef;
|
|
29
36
|
};
|
|
30
37
|
};
|
|
31
38
|
codeSnippet: string;
|
|
@@ -212,6 +219,17 @@ Focus scenarios on demonstrating this specific behavior change.
|
|
|
212
219
|
|
|
213
220
|
${contextSection}${scenarioCountText}
|
|
214
221
|
|
|
222
|
+
## Coverage Goals (IMPORTANT)
|
|
223
|
+
Your primary goal is to MAXIMIZE coverage of key attributes across all scenarios:
|
|
224
|
+
|
|
225
|
+
1. **Use ALL validValueOptions**: Each key attribute has indexed \`validValueOptions\`. Across your scenarios, try to use EVERY option at least once. If an attribute has 3 options (indices 0, 1, 2), create scenarios that collectively cover all 3.
|
|
226
|
+
|
|
227
|
+
2. **Prioritize attributes with dependencies**: Key attributes with a \`dependencies\` array are HIGH PRIORITY - they control conditionally-rendered content. Create scenarios that satisfy these dependencies to reveal gated UI/behavior.
|
|
228
|
+
|
|
229
|
+
3. **Cover conditional branches**: Use \`codeUsages\` to identify all conditional paths. If code shows \`status === 'active'\` and \`status === 'pending'\`, ensure scenarios cover BOTH values.
|
|
230
|
+
|
|
231
|
+
4. **Vary values strategically**: Don't repeat the same validValueOption across scenarios unless necessary. Use different indices to maximize coverage.
|
|
232
|
+
|
|
215
233
|
## Default Scenario Rules
|
|
216
234
|
The FIRST scenario MUST be named exactly "${DEFAULT_SCENARIO_NAME}" (case-sensitive).
|
|
217
235
|
- Fill ALL key attributes using values from their \`validValueOptions\` list
|
|
@@ -219,23 +237,69 @@ The FIRST scenario MUST be named exactly "${DEFAULT_SCENARIO_NAME}" (case-sensit
|
|
|
219
237
|
- Ignore error-related attributes (set to null)
|
|
220
238
|
- NEVER include \`playwrightInstructions\` - we need a screenshot BEFORE any user interaction
|
|
221
239
|
- Do NOT add playwrightInstructions even if the component has forms/buttons - default shows initial state only
|
|
240
|
+
- **For attributes WITH dependencies**: The Default scenario should satisfy ALL dependencies so the attribute's effect is visible
|
|
222
241
|
|
|
223
242
|
## Other Scenarios
|
|
224
243
|
- Each produces DISTINCT output (visual: different screenshot; backend: different return/side-effect)
|
|
244
|
+
- **Use DIFFERENT validValueOptions** than the Default scenario - this is how we achieve coverage
|
|
225
245
|
- Only specify attributes that DIFFER from default
|
|
246
|
+
- Target uncovered validValueOptions: check which indices you haven't used yet
|
|
226
247
|
- May include \`playwrightInstructions\` for user interactions (clicks, form fills)
|
|
227
248
|
|
|
249
|
+
## Using codeUsages for Branch Coverage
|
|
250
|
+
Key attributes may include a \`codeUsages\` array showing exactly where they're used in conditionals:
|
|
251
|
+
\`\`\`json
|
|
252
|
+
{
|
|
253
|
+
"codeUsages": [
|
|
254
|
+
{ "line": 45, "code": "if (status === 'active')", "context": "Used in if statement (comparison check)" }
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
\`\`\`
|
|
258
|
+
Use this to ensure scenarios cover all conditional branches. If you see \`status === 'active'\`, create scenarios for both active AND non-active states.
|
|
259
|
+
|
|
260
|
+
## Handling Dependencies (Compound Conditionals) - HIGH PRIORITY
|
|
261
|
+
Key attributes with \`dependencies\` are the MOST IMPORTANT to cover because they reveal conditionally-gated content that only appears when multiple conditions are satisfied together.
|
|
262
|
+
|
|
263
|
+
**Why this matters**: If you see \`items.length > 0 && !isLoading && !hasError\`, the content only renders when ALL THREE conditions are true. Missing even one dependency means the UI won't show.
|
|
264
|
+
|
|
265
|
+
**Strategy for dependent attributes**:
|
|
266
|
+
1. **Default scenario**: MUST satisfy ALL dependencies of the highest-impact key attributes
|
|
267
|
+
2. **Other scenarios**: Can vary the dependent values to show alternative states (e.g., what happens when isLoading=true)
|
|
268
|
+
|
|
269
|
+
When a key attribute has dependencies like:
|
|
270
|
+
\`\`\`json
|
|
271
|
+
{
|
|
272
|
+
"dependencies": [
|
|
273
|
+
{ "path": "signature[0].isLoading", "requiredValue": false },
|
|
274
|
+
{ "path": "signature[0].hasError", "requiredValue": false }
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
\`\`\`
|
|
278
|
+
The Default scenario MUST set BOTH dependent attributes to their required values so the key attribute's effect is visible.
|
|
279
|
+
|
|
280
|
+
**Creating scenarios for dependent pathways**:
|
|
281
|
+
- Create at least one scenario where ALL dependencies are satisfied (usually Default)
|
|
282
|
+
- Consider creating additional scenarios that intentionally break dependencies to show the "hidden" state
|
|
283
|
+
|
|
228
284
|
## keyAttributeInstructions Format
|
|
229
|
-
Use \`dataStructurePath\` as key
|
|
285
|
+
Use \`dataStructurePath\` as key. Include variable name, instruction, AND a valueOptionRef that references which validValueOption you're using:
|
|
230
286
|
\`\`\`json
|
|
231
287
|
{
|
|
232
288
|
"useDiffModal().diffView": {
|
|
233
289
|
"localVariable": "diffView",
|
|
234
|
-
"instruction": "Set to 'split' mode"
|
|
290
|
+
"instruction": "Set to 'split' mode",
|
|
291
|
+
"valueOptionRef": { "index": 0, "refType": "exact" }
|
|
235
292
|
}
|
|
236
293
|
}
|
|
237
294
|
\`\`\`
|
|
238
295
|
|
|
296
|
+
### valueOptionRef Types
|
|
297
|
+
- \`"exact"\`: Uses the validValueOption at this index exactly
|
|
298
|
+
- \`"derived"\`: Based on this validValueOption but modified (include \`derivation\` field explaining how)
|
|
299
|
+
- \`"custom"\`: Value not from validValueOptions list (use sparingly)
|
|
300
|
+
|
|
301
|
+
The \`index\` refers to the validValueOptions array position (0 = first option).
|
|
302
|
+
|
|
239
303
|
## playwrightInstructions (optional, non-default only)
|
|
240
304
|
\`\`\`json
|
|
241
305
|
{
|
|
@@ -263,24 +327,63 @@ Use when: data only appears after user action (button click, form submit), or ke
|
|
|
263
327
|
"dataScenarios": [
|
|
264
328
|
{
|
|
265
329
|
"name": "${DEFAULT_SCENARIO_NAME}",
|
|
266
|
-
"testName": "it(\"displays
|
|
267
|
-
"description": "
|
|
330
|
+
"testName": "it(\"displays items list with data\")",
|
|
331
|
+
"description": "Shows item list when data is loaded and no errors",
|
|
268
332
|
"keyAttributeInstructions": {
|
|
269
|
-
"
|
|
270
|
-
|
|
333
|
+
"useData().items[]": {
|
|
334
|
+
"localVariable": "items[]",
|
|
335
|
+
"instruction": "Array with 3 items",
|
|
336
|
+
"valueOptionRef": { "index": 0, "refType": "exact" }
|
|
337
|
+
},
|
|
338
|
+
"useData().isLoading": {
|
|
339
|
+
"localVariable": "isLoading",
|
|
340
|
+
"instruction": "false - satisfies dependency for items to show",
|
|
341
|
+
"valueOptionRef": { "index": 1, "refType": "exact" }
|
|
342
|
+
},
|
|
343
|
+
"useData().status": {
|
|
344
|
+
"localVariable": "status",
|
|
345
|
+
"instruction": "Set to 'success'",
|
|
346
|
+
"valueOptionRef": { "index": 0, "refType": "exact" }
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"name": "Loading state",
|
|
352
|
+
"testName": "it(\"shows spinner when loading\")",
|
|
353
|
+
"description": "Data is loading - items hidden, spinner shown",
|
|
354
|
+
"keyAttributeInstructions": {
|
|
355
|
+
"useData().isLoading": {
|
|
356
|
+
"localVariable": "isLoading",
|
|
357
|
+
"instruction": "true - breaks dependency, items won't show",
|
|
358
|
+
"valueOptionRef": { "index": 0, "refType": "exact" }
|
|
359
|
+
},
|
|
360
|
+
"useData().status": {
|
|
361
|
+
"localVariable": "status",
|
|
362
|
+
"instruction": "Set to 'loading' for coverage of loading state",
|
|
363
|
+
"valueOptionRef": { "index": 1, "refType": "exact" }
|
|
364
|
+
}
|
|
271
365
|
}
|
|
272
366
|
},
|
|
273
367
|
{
|
|
274
368
|
"name": "Empty state",
|
|
275
|
-
"testName": "it(\"shows
|
|
276
|
-
"description": "
|
|
369
|
+
"testName": "it(\"shows empty message when no items\")",
|
|
370
|
+
"description": "No items to display",
|
|
277
371
|
"keyAttributeInstructions": {
|
|
278
|
-
"
|
|
372
|
+
"useData().items[]": {
|
|
373
|
+
"localVariable": "items[]",
|
|
374
|
+
"instruction": "Empty array [] to show empty state",
|
|
375
|
+
"valueOptionRef": { "index": 1, "refType": "exact" }
|
|
376
|
+
}
|
|
279
377
|
}
|
|
280
378
|
}
|
|
281
379
|
]
|
|
282
380
|
}
|
|
283
381
|
\`\`\`
|
|
382
|
+
Note how the example:
|
|
383
|
+
- Default satisfies ALL dependencies (isLoading=false) so items content shows
|
|
384
|
+
- "Loading state" uses a different valueOptionRef for status to cover that code path
|
|
385
|
+
- "Empty state" covers the empty array case to maximize coverage
|
|
386
|
+
- Instructions describe the VALUE, not the index (e.g., "Empty array []" not "uses index 1")
|
|
284
387
|
`;
|
|
285
388
|
}
|
|
286
389
|
|