@codeyam/codeyam-cli 0.1.0-staging.9574237 → 0.1.0-staging.a2f381a
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 +8 -8
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +4 -4
- package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +135 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/nodeToSource.ts +19 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/paths.ts +11 -4
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +36 -9
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.ts +10 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +16 -6
- package/analyzer-template/packages/analyze/index.ts +4 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +28 -2
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +5 -36
- package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +10 -6
- package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +9 -12
- package/analyzer-template/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.ts +21 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +82 -10
- package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +4 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +4 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyzeNextRoute.ts +8 -3
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +239 -58
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +1684 -1462
- package/analyzer-template/packages/aws/package.json +6 -6
- package/analyzer-template/packages/database/package.json +2 -2
- package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +25 -15
- package/analyzer-template/packages/database/src/lib/loadEntity.ts +19 -8
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +7 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.d.ts +4 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.js +5 -5
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts +3 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +22 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
- package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +27 -0
- package/analyzer-template/project/analyzeFileEntities.ts +26 -0
- package/analyzer-template/project/runMultiScenarioServer.ts +26 -3
- package/background/src/lib/virtualized/project/analyzeFileEntities.js +22 -0
- package/background/src/lib/virtualized/project/analyzeFileEntities.js.map +1 -1
- package/background/src/lib/virtualized/project/runMultiScenarioServer.js +23 -3
- package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
- package/codeyam-cli/src/cli.js +24 -0
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/commands/__tests__/editor.analyzeImportsArgs.test.js +47 -0
- package/codeyam-cli/src/commands/__tests__/editor.analyzeImportsArgs.test.js.map +1 -0
- package/codeyam-cli/src/commands/__tests__/editor.auditNoAutoAnalysis.test.js +71 -0
- package/codeyam-cli/src/commands/__tests__/editor.auditNoAutoAnalysis.test.js.map +1 -0
- package/codeyam-cli/src/commands/__tests__/editor.designSystem.test.js +30 -0
- package/codeyam-cli/src/commands/__tests__/editor.designSystem.test.js.map +1 -0
- package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js +51 -0
- package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js.map +1 -0
- package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js +55 -0
- package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js.map +1 -0
- package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js +9 -9
- package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js +39 -3
- package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js.map +1 -1
- package/codeyam-cli/src/commands/editor.js +2497 -467
- package/codeyam-cli/src/commands/editor.js.map +1 -1
- package/codeyam-cli/src/commands/editorAnalyzeImportsArgs.js +23 -0
- package/codeyam-cli/src/commands/editorAnalyzeImportsArgs.js.map +1 -0
- package/codeyam-cli/src/commands/editorIsolateArgs.js +25 -0
- package/codeyam-cli/src/commands/editorIsolateArgs.js.map +1 -0
- package/codeyam-cli/src/commands/init.js +21 -0
- package/codeyam-cli/src/commands/init.js.map +1 -1
- package/codeyam-cli/src/commands/telemetry.js +37 -0
- package/codeyam-cli/src/commands/telemetry.js.map +1 -0
- package/codeyam-cli/src/data/designSystems.js +27 -0
- package/codeyam-cli/src/data/designSystems.js.map +1 -0
- package/codeyam-cli/src/data/techStacks.js +1 -1
- package/codeyam-cli/src/utils/__tests__/devServerState.test.js +93 -1
- package/codeyam-cli/src/utils/__tests__/devServerState.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorApi.test.js +44 -0
- package/codeyam-cli/src/utils/__tests__/editorApi.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +3174 -1
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorCaptureScenarioSeeding.test.js +137 -0
- package/codeyam-cli/src/utils/__tests__/editorCaptureScenarioSeeding.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js +70 -0
- package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js +163 -4
- package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorGuardMiddleware.test.js +67 -0
- package/codeyam-cli/src/utils/__tests__/editorGuardMiddleware.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/editorPreview.test.js +11 -3
- package/codeyam-cli/src/utils/__tests__/editorPreview.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js +98 -1
- package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js +1108 -0
- package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js +190 -0
- package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +344 -7
- package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js +134 -1
- package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +294 -2
- package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/envFile.test.js +125 -0
- package/codeyam-cli/src/utils/__tests__/envFile.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/glossaryAdd.test.js +177 -0
- package/codeyam-cli/src/utils/__tests__/glossaryAdd.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/handoffContext.test.js +500 -0
- package/codeyam-cli/src/utils/__tests__/handoffContext.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js +16 -1
- package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/manualEntityAnalysis.test.js +302 -0
- package/codeyam-cli/src/utils/__tests__/manualEntityAnalysis.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/registerScenarioResult.test.js +127 -0
- package/codeyam-cli/src/utils/__tests__/registerScenarioResult.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js +57 -0
- package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js +180 -1
- package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/screenshotHash.test.js +84 -0
- package/codeyam-cli/src/utils/__tests__/screenshotHash.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/telemetry.test.js +159 -0
- package/codeyam-cli/src/utils/__tests__/telemetry.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/testRunner.test.js +216 -0
- package/codeyam-cli/src/utils/__tests__/testRunner.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/webappDetection.test.js +6 -0
- package/codeyam-cli/src/utils/__tests__/webappDetection.test.js.map +1 -1
- package/codeyam-cli/src/utils/analysisRunner.js +36 -7
- package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
- package/codeyam-cli/src/utils/analyzer.js +11 -1
- package/codeyam-cli/src/utils/analyzer.js.map +1 -1
- package/codeyam-cli/src/utils/backgroundServer.js +1 -1
- package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/utils/designSystemShowcase.js +810 -0
- package/codeyam-cli/src/utils/designSystemShowcase.js.map +1 -0
- package/codeyam-cli/src/utils/devServerState.js +32 -0
- package/codeyam-cli/src/utils/devServerState.js.map +1 -1
- package/codeyam-cli/src/utils/editorApi.js +16 -0
- package/codeyam-cli/src/utils/editorApi.js.map +1 -1
- package/codeyam-cli/src/utils/editorAudit.js +649 -10
- package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
- package/codeyam-cli/src/utils/editorEntityChangeStatus.js +13 -7
- package/codeyam-cli/src/utils/editorEntityChangeStatus.js.map +1 -1
- package/codeyam-cli/src/utils/editorEntityHelpers.js +18 -3
- package/codeyam-cli/src/utils/editorEntityHelpers.js.map +1 -1
- package/codeyam-cli/src/utils/editorGuard.js +36 -0
- package/codeyam-cli/src/utils/editorGuard.js.map +1 -0
- package/codeyam-cli/src/utils/editorPreview.js +5 -3
- package/codeyam-cli/src/utils/editorPreview.js.map +1 -1
- package/codeyam-cli/src/utils/editorRecapture.js +109 -0
- package/codeyam-cli/src/utils/editorRecapture.js.map +1 -0
- package/codeyam-cli/src/utils/editorRoadmap.js +574 -0
- package/codeyam-cli/src/utils/editorRoadmap.js.map +1 -0
- package/codeyam-cli/src/utils/editorScenarioSwitch.js +39 -2
- package/codeyam-cli/src/utils/editorScenarioSwitch.js.map +1 -1
- package/codeyam-cli/src/utils/editorScenarios.js +181 -17
- package/codeyam-cli/src/utils/editorScenarios.js.map +1 -1
- package/codeyam-cli/src/utils/editorSeedAdapter.js +69 -16
- package/codeyam-cli/src/utils/editorSeedAdapter.js.map +1 -1
- package/codeyam-cli/src/utils/entityChangeStatus.js +39 -5
- package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -1
- package/codeyam-cli/src/utils/entityChangeStatus.server.js +31 -0
- package/codeyam-cli/src/utils/entityChangeStatus.server.js.map +1 -1
- package/codeyam-cli/src/utils/envFile.js +90 -0
- package/codeyam-cli/src/utils/envFile.js.map +1 -0
- package/codeyam-cli/src/utils/fileWatcher.js +38 -0
- package/codeyam-cli/src/utils/fileWatcher.js.map +1 -1
- package/codeyam-cli/src/utils/glossaryAdd.js +74 -0
- package/codeyam-cli/src/utils/glossaryAdd.js.map +1 -0
- package/codeyam-cli/src/utils/handoffContext.js +257 -0
- package/codeyam-cli/src/utils/handoffContext.js.map +1 -0
- package/codeyam-cli/src/utils/install-skills.js +41 -6
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/manualEntityAnalysis.js +196 -0
- package/codeyam-cli/src/utils/manualEntityAnalysis.js.map +1 -0
- package/codeyam-cli/src/utils/queue/__tests__/job.interactiveStart.test.js +159 -0
- package/codeyam-cli/src/utils/queue/__tests__/job.interactiveStart.test.js.map +1 -0
- package/codeyam-cli/src/utils/queue/job.js +35 -6
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/registerScenarioResult.js +52 -0
- package/codeyam-cli/src/utils/registerScenarioResult.js.map +1 -0
- package/codeyam-cli/src/utils/scenarioCoverage.js +4 -1
- package/codeyam-cli/src/utils/scenarioCoverage.js.map +1 -1
- package/codeyam-cli/src/utils/scenariosManifest.js +66 -2
- package/codeyam-cli/src/utils/scenariosManifest.js.map +1 -1
- package/codeyam-cli/src/utils/screenshotHash.js +26 -0
- package/codeyam-cli/src/utils/screenshotHash.js.map +1 -0
- package/codeyam-cli/src/utils/simulationGateMiddleware.js +9 -0
- package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -1
- package/codeyam-cli/src/utils/techStackConfig.js +38 -0
- package/codeyam-cli/src/utils/techStackConfig.js.map +1 -0
- package/codeyam-cli/src/utils/techStackConfig.test.js +85 -0
- package/codeyam-cli/src/utils/techStackConfig.test.js.map +1 -0
- package/codeyam-cli/src/utils/telemetry.js +106 -0
- package/codeyam-cli/src/utils/telemetry.js.map +1 -0
- package/codeyam-cli/src/utils/telemetryMiddleware.js +22 -0
- package/codeyam-cli/src/utils/telemetryMiddleware.js.map +1 -0
- package/codeyam-cli/src/utils/testResultCache.js +53 -0
- package/codeyam-cli/src/utils/testResultCache.js.map +1 -0
- package/codeyam-cli/src/utils/testResultCache.server.js +81 -0
- package/codeyam-cli/src/utils/testResultCache.server.js.map +1 -0
- package/codeyam-cli/src/utils/testResultCache.server.test.js +187 -0
- package/codeyam-cli/src/utils/testResultCache.server.test.js.map +1 -0
- package/codeyam-cli/src/utils/testResultCache.test.js +230 -0
- package/codeyam-cli/src/utils/testResultCache.test.js.map +1 -0
- package/codeyam-cli/src/utils/testRunner.js +193 -1
- package/codeyam-cli/src/utils/testRunner.js.map +1 -1
- package/codeyam-cli/src/utils/webappDetection.js +4 -2
- package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
- package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js +99 -0
- package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js.map +1 -0
- package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js +119 -1
- package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js.map +1 -1
- package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js +68 -1
- package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js.map +1 -1
- package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +442 -9
- package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -1
- package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js +190 -21
- package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js.map +1 -1
- package/codeyam-cli/src/webserver/__tests__/stripClaudeCommand.test.js +135 -0
- package/codeyam-cli/src/webserver/__tests__/stripClaudeCommand.test.js.map +1 -0
- package/codeyam-cli/src/webserver/app/lib/clientErrors.js +22 -1
- package/codeyam-cli/src/webserver/app/lib/clientErrors.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/app/routes/api.interactive-switch-scenario.js +34 -0
- package/codeyam-cli/src/webserver/app/routes/api.interactive-switch-scenario.js.map +1 -0
- package/codeyam-cli/src/webserver/backgroundServer.js +42 -57
- package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-CzTDWkF2.js → CopyButton-DTBZZfSk.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-BFbq6iFk.js → EntityItem-BxclONWq.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-B6OMi58N.js → EntityTypeIcon-BsnEOJZ_.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-DuYodzo1.js → InlineSpinner-ByaELMbv.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CXo9EeCl.js → InteractivePreview-6WjVfhxX.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-DYCNb2It.js → LibraryFunctionPreview-ChX-Hp7W.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-CZgY3sxX.js → LogViewer-C-9zQdXg.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/MiniClaudeChat-Bs2_Oua4.js +36 -0
- package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-CnYYwRDw.js → ReportIssueModal-DQsceHVv.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-CDoF7ZpU.js → SafeScreenshot-DThcm_9M.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DrnfvaLL.js → ScenarioViewer-Cl4oOA3A.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/Spinner-CIil5-gb.js +34 -0
- package/codeyam-cli/src/webserver/build/client/assets/{ViewportInspectBar-DRKR9T0U.js → ViewportInspectBar-BqkA9zyZ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{_index-ClR-g3tY.js → _index-DnOgyseQ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-DTH6ydEA.js → activity.(_tab)-DqM9hbNE.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{addon-web-links-74hnHF59.js → addon-web-links-C58dYPwR.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-B8CYhCO9.js → agent-transcripts-B8NCeOrm.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-database-verify-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-github-verify-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-handoff-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-hosting-verify-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-recapture-stale-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-roadmap-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-save-scenario-data-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-schema-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-verify-routes-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.interactive-switch-scenario-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{book-open-CLaoh4ac.js → book-open-BFSIqZgO.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-BZ2DZxbW.js → chevron-down-B9fDzFVh.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-UVKPFVEO-Bmq2apuh.js +43 -0
- package/codeyam-cli/src/webserver/build/client/assets/{circle-check-CT4unAk-.js → circle-check-DLPObLUx.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{copy-zK0B6Nu-.js → copy-DXEmO0TD.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-DJB0YQJL.js → createLucideIcon-BwyFiRot.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-Coe5NhbS.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{cy-logo-cli-CCKUIm0S.svg → cy-logo-cli-DoA97ML3.svg} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-CkXFP_i-.js → dev.empty-iRhRIFlp.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/editor._tab-BZPBzV73.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DhtVC4aI.js +161 -0
- package/codeyam-cli/src/webserver/build/client/assets/editorPreview-C6fEYHrh.js +41 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BqAN7hyG.js → entity._sha._-pc-vc6wO.js} +13 -12
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.dev-BOi8kpwd.js → entity._sha.scenarios._scenarioId.dev-C8AyYgYT.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-Dg1NhIms.js → entity._sha.scenarios._scenarioId.fullscreen-DziaVQX1.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-CJX6kkkV.js → entity._sha_.create-scenario-BTcpgIpC.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-BhVjZhKg.js → entity._sha_.edit._scenarioId-D_O_ajfZ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entry.client-_gzKltPN.js → entry.client-j1Vi0bco.js} +6 -6
- package/codeyam-cli/src/webserver/build/client/assets/{files-CV_17tZS.js → files-kuny2Q_s.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{git-D-YXmMbR.js → git-DgCZPMie.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-L-aUIeux.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-CCrgCshv.js → index-BliGSSpl.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-Blo6EK8G.js → index-SqjQKTdH.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-BsX0F-9C.js → index-vyrZD2g4.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{labs-Byazq8Pv.js → labs-c3yLxSEp.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-DVQ0oHR7.js → loader-circle-D-q28GLF.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-79d0d81a.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{memory-b-VmA2Vj.js → memory-CEWIUC4t.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{pause-DGcndCAa.js → pause-BP6fitdh.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-L2V0jea7.js +80 -0
- package/codeyam-cli/src/webserver/build/client/assets/{search-C0Uw0bcK.js → search-BooqacKS.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{settings-OoNgHIfW.js → settings-BM0nbryO.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{simulations-Bcemfu8a.js → simulations-ovy6FjRY.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{terminal-BgMmG7R9.js → terminal-DHemCJIs.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-Cs87hJYK.js → triangle-alert-D87ekDl8.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-BR3Rs7JY.js → useCustomSizes-Dk0Tciqg.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C8QvIe05.js +2 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-BermyNU5.js → useReportContext-jkCytuYz.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-a_QN_W9_.js → useToast-BgqkixU9.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/analysisRunner-QgInFGdU.js +16 -0
- package/codeyam-cli/src/webserver/build/server/assets/{index-CHSrVJtC.js → index-zblh9auj.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/init-DaE0CBjk.js +14 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-CNvgz1cC.js +853 -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/editorProxy.js +388 -26
- package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
- package/codeyam-cli/src/webserver/idleDetector.js +65 -8
- package/codeyam-cli/src/webserver/idleDetector.js.map +1 -1
- package/codeyam-cli/src/webserver/scripts/journalCapture.ts +53 -0
- package/codeyam-cli/src/webserver/server.js +151 -14
- package/codeyam-cli/src/webserver/server.js.map +1 -1
- package/codeyam-cli/src/webserver/terminalServer.js +253 -41
- package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
- package/codeyam-cli/templates/__tests__/editor-step-hook.prompt-capture.test.ts +118 -0
- package/codeyam-cli/templates/codeyam-editor-claude.md +2 -0
- package/codeyam-cli/templates/codeyam-editor-codex.md +61 -0
- package/codeyam-cli/templates/codeyam-editor-gemini.md +59 -0
- package/codeyam-cli/templates/codeyam-editor-reference.md +216 -0
- package/codeyam-cli/templates/design-systems/clean-dashboard-design-system.md +255 -0
- package/codeyam-cli/templates/design-systems/editorial-design-system.md +267 -0
- package/codeyam-cli/templates/design-systems/mono-brutalist-design-system.md +256 -0
- package/codeyam-cli/templates/design-systems/neo-brutalist-design-system.md +294 -0
- package/codeyam-cli/templates/editor-step-hook.py +93 -46
- package/codeyam-cli/templates/expo-react-native/MOBILE_SETUP.md +204 -5
- package/codeyam-cli/templates/expo-react-native/__tests__/.gitkeep +0 -0
- package/codeyam-cli/templates/expo-react-native/app/_layout.tsx +6 -3
- package/codeyam-cli/templates/expo-react-native/app/index.tsx +36 -0
- package/codeyam-cli/templates/expo-react-native/app.json +11 -0
- package/codeyam-cli/templates/expo-react-native/babel.config.js +1 -0
- package/codeyam-cli/templates/expo-react-native/gitignore +2 -0
- package/codeyam-cli/templates/expo-react-native/global.css +7 -0
- package/codeyam-cli/templates/expo-react-native/lib/theme.ts +73 -0
- package/codeyam-cli/templates/expo-react-native/package.json +32 -16
- package/codeyam-cli/templates/expo-react-native/patches/expo-modules-autolinking+3.0.24.patch +29 -0
- package/codeyam-cli/templates/isolation-route/expo-router.tsx.template +54 -0
- package/codeyam-cli/templates/nextjs-prisma-sqlite/gitignore +1 -0
- package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +1 -1
- package/codeyam-cli/templates/nextjs-prisma-sqlite/seed-adapter.ts +47 -34
- package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +1 -1
- package/codeyam-cli/templates/seed-adapters/supabase.ts +271 -78
- package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +34 -1
- package/package.json +2 -1
- package/packages/ai/src/lib/astScopes/methodSemantics.js +99 -0
- package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
- package/packages/ai/src/lib/astScopes/nodeToSource.js +16 -0
- package/packages/ai/src/lib/astScopes/nodeToSource.js.map +1 -1
- package/packages/ai/src/lib/astScopes/paths.js +12 -3
- package/packages/ai/src/lib/astScopes/paths.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +27 -10
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.js +9 -2
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +14 -4
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
- package/packages/analyze/index.js +1 -1
- package/packages/analyze/index.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +16 -2
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +6 -26
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +3 -2
- package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +9 -7
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js +14 -0
- package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +44 -11
- package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeChange.js +1 -0
- package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeInitial.js +1 -0
- package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeNextRoute.js +5 -1
- package/packages/analyze/src/lib/files/analyzeNextRoute.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +120 -28
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +1368 -1193
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/database/src/lib/loadAnalysis.js +7 -1
- package/packages/database/src/lib/loadAnalysis.js.map +1 -1
- package/packages/database/src/lib/loadEntity.js +5 -5
- package/packages/database/src/lib/loadEntity.js.map +1 -1
- package/packages/utils/src/lib/fs/rsyncCopy.js +22 -1
- package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/Spinner-Df3UCi8k.js +0 -34
- package/codeyam-cli/src/webserver/build/client/assets/chunk-JZWAC4HX-BBXArFPl.js +0 -43
- package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-DcX-ZS3p.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/editor._tab-DPw7NZHc.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-Dmg9cGK3.js +0 -58
- package/codeyam-cli/src/webserver/build/client/assets/editorPreview-DBa7T2FK.js +0 -41
- package/codeyam-cli/src/webserver/build/client/assets/globals-Bqg9V6XV.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-422a3551.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-ue8uWVRS.js +0 -67
- package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-BxxP_XF9.js +0 -2
- package/codeyam-cli/src/webserver/build/server/assets/analysisRunner-DXQyOV0G.js +0 -13
- package/codeyam-cli/src/webserver/build/server/assets/init-DL8vWZ6m.js +0 -10
- package/codeyam-cli/src/webserver/build/server/assets/server-build-BUKVjBSZ.js +0 -501
- package/codeyam-cli/templates/expo-react-native/app/(tabs)/_layout.tsx +0 -33
- package/codeyam-cli/templates/expo-react-native/app/(tabs)/index.tsx +0 -12
- package/codeyam-cli/templates/expo-react-native/app/(tabs)/settings.tsx +0 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import http from 'http';
|
|
2
2
|
import zlib from 'zlib';
|
|
3
|
-
import { injectHealthScript, PREVIEW_HEALTH_SCRIPT, getPreviewHealthReport, resetPreviewHealth, } from "../editorProxy.js";
|
|
3
|
+
import { injectHealthScript, PREVIEW_HEALTH_SCRIPT, getPreviewHealthReport, resetPreviewHealth, buildErrorPage, escapeHtml, } from "../editorProxy.js";
|
|
4
4
|
describe('editorProxy', () => {
|
|
5
5
|
describe('normalizeTargetUrl', () => {
|
|
6
6
|
it('should leave localhost as-is (no longer normalizes to 127.0.0.1)', () => {
|
|
@@ -198,6 +198,14 @@ describe('editorProxy', () => {
|
|
|
198
198
|
const result = injectHealthScript(html);
|
|
199
199
|
expect(result).toContain('data-codeyam-health');
|
|
200
200
|
});
|
|
201
|
+
it('should use 100ms settle delay for network-idle detection', () => {
|
|
202
|
+
// The settle delay determines how long after all fetch() calls complete
|
|
203
|
+
// before the preview is shown. 100ms is enough for React to re-render.
|
|
204
|
+
expect(PREVIEW_HEALTH_SCRIPT).toContain('}, 100)');
|
|
205
|
+
});
|
|
206
|
+
it('should use 200ms fallback for static pages with no fetches', () => {
|
|
207
|
+
expect(PREVIEW_HEALTH_SCRIPT).toContain('}, 200)');
|
|
208
|
+
});
|
|
201
209
|
});
|
|
202
210
|
describe('preview health endpoint', () => {
|
|
203
211
|
let targetServer;
|
|
@@ -352,10 +360,20 @@ describe('editorProxy', () => {
|
|
|
352
360
|
});
|
|
353
361
|
});
|
|
354
362
|
describe('buildLocalStorageScript', () => {
|
|
355
|
-
it('should
|
|
363
|
+
it('should clean up previous keys when no localStorage config but scenarioId is present', () => {
|
|
364
|
+
const { buildLocalStorageScript } = require('../editorProxy');
|
|
365
|
+
// When switching to a scenario WITHOUT localStorage from one that HAD it,
|
|
366
|
+
// the script must clean up the previous scenario's keys so stale filters
|
|
367
|
+
// don't persist and hide data.
|
|
368
|
+
const script = buildLocalStorageScript(null, 'scenario-123');
|
|
369
|
+
expect(script).toContain('__codeyam_ls_keys__');
|
|
370
|
+
expect(script).toContain('removeItem');
|
|
371
|
+
expect(script).toContain('clear:scenario-123');
|
|
372
|
+
});
|
|
373
|
+
it('should return empty string when no localStorage config and no scenarioId', () => {
|
|
356
374
|
const { buildLocalStorageScript } = require('../editorProxy');
|
|
357
|
-
expect(buildLocalStorageScript(null, '
|
|
358
|
-
expect(buildLocalStorageScript(undefined, '
|
|
375
|
+
expect(buildLocalStorageScript(null, '')).toBe('');
|
|
376
|
+
expect(buildLocalStorageScript(undefined, '')).toBe('');
|
|
359
377
|
});
|
|
360
378
|
it('should emit cleanup script when localStorage config is empty object', () => {
|
|
361
379
|
// BUG FIX: When switching from a scenario with localStorage data to one
|
|
@@ -401,12 +419,13 @@ describe('editorProxy', () => {
|
|
|
401
419
|
expect(script).toContain('__codeyam_proto__');
|
|
402
420
|
expect(script).toContain('proto-abc');
|
|
403
421
|
});
|
|
404
|
-
it('should
|
|
422
|
+
it('should clean up previous keys when prototypeId is absent but scenarioId is present', () => {
|
|
405
423
|
const { buildLocalStorageScript } = require('../editorProxy');
|
|
406
|
-
// No prototypeId —
|
|
407
|
-
|
|
408
|
-
expect(
|
|
409
|
-
|
|
424
|
+
// No prototypeId but scenarioId — cleanup previous scenario's keys
|
|
425
|
+
const script1 = buildLocalStorageScript(null, 'scenario-123');
|
|
426
|
+
expect(script1).toContain('removeItem');
|
|
427
|
+
const script2 = buildLocalStorageScript(null, 'scenario-123', null);
|
|
428
|
+
expect(script2).toContain('removeItem');
|
|
410
429
|
});
|
|
411
430
|
it('should clean up keys from previous scenario before setting new ones', () => {
|
|
412
431
|
const { buildLocalStorageScript } = require('../editorProxy');
|
|
@@ -432,6 +451,67 @@ describe('editorProxy', () => {
|
|
|
432
451
|
expect(script).toContain('array_key');
|
|
433
452
|
expect(script).toContain('[1,2,3]');
|
|
434
453
|
});
|
|
454
|
+
it('should include localStorage mutation watcher that sends postMessage on changes', () => {
|
|
455
|
+
const { buildLocalStorageScript } = require('../editorProxy');
|
|
456
|
+
const config = { my_key: 'my_value' };
|
|
457
|
+
const script = buildLocalStorageScript(config, 'scenario-1');
|
|
458
|
+
// Should hook setItem, removeItem, and clear
|
|
459
|
+
expect(script).toContain('__codeyam_orig_setItem__');
|
|
460
|
+
expect(script).toContain('__codeyam_orig_removeItem__');
|
|
461
|
+
expect(script).toContain('__codeyam_orig_clear__');
|
|
462
|
+
// Should send postMessage to parent
|
|
463
|
+
expect(script).toContain('codeyam-localstorage-changed');
|
|
464
|
+
expect(script).toContain('postMessage');
|
|
465
|
+
// Should filter out internal codeyam keys
|
|
466
|
+
expect(script).toContain('__codeyam_');
|
|
467
|
+
});
|
|
468
|
+
it('should include localStorage mutation watcher even for empty localStorage config', () => {
|
|
469
|
+
const { buildLocalStorageScript } = require('../editorProxy');
|
|
470
|
+
const script = buildLocalStorageScript({}, 'scenario-1');
|
|
471
|
+
// Empty config still needs the watcher since the app may write to localStorage
|
|
472
|
+
expect(script).toContain('codeyam-localstorage-changed');
|
|
473
|
+
});
|
|
474
|
+
it('should include a listener for codeyam-get-localstorage requests', () => {
|
|
475
|
+
const { buildLocalStorageScript } = require('../editorProxy');
|
|
476
|
+
const config = { my_key: 'my_value' };
|
|
477
|
+
const script = buildLocalStorageScript(config, 'scenario-1');
|
|
478
|
+
// Should listen for get-localstorage requests from parent
|
|
479
|
+
expect(script).toContain('codeyam-get-localstorage');
|
|
480
|
+
expect(script).toContain('codeyam-localstorage-state');
|
|
481
|
+
});
|
|
482
|
+
it('should not include mutation watcher when no localStorage config and no scenarioId', () => {
|
|
483
|
+
const { buildLocalStorageScript } = require('../editorProxy');
|
|
484
|
+
// No config AND no scenarioId — returns empty string
|
|
485
|
+
expect(buildLocalStorageScript(null, '')).toBe('');
|
|
486
|
+
});
|
|
487
|
+
it('should re-seed localStorage when scenario data changes even if ID is the same', () => {
|
|
488
|
+
// BUG: When a scenario is re-registered with updated data (e.g., adding
|
|
489
|
+
// collections to articles), the scenario ID stays the same. The guard
|
|
490
|
+
// checked only the ID, so the browser skipped re-seeding and showed stale
|
|
491
|
+
// data. The screenshot (captured by Playwright with a fresh browser)
|
|
492
|
+
// showed the new data, but the live preview didn't.
|
|
493
|
+
const { buildLocalStorageScript } = require('../editorProxy');
|
|
494
|
+
const originalData = {
|
|
495
|
+
articles: '[{"id":"a1","title":"Test"}]',
|
|
496
|
+
};
|
|
497
|
+
const updatedData = {
|
|
498
|
+
articles: '[{"id":"a1","title":"Test","collectionIds":["c1"]}]',
|
|
499
|
+
collections: '[{"id":"c1","name":"Dev"}]',
|
|
500
|
+
};
|
|
501
|
+
const script1 = buildLocalStorageScript(originalData, 'scenario-abc');
|
|
502
|
+
const script2 = buildLocalStorageScript(updatedData, 'scenario-abc');
|
|
503
|
+
// Both scripts use the same scenario ID
|
|
504
|
+
expect(script1).toContain('scenario-abc');
|
|
505
|
+
expect(script2).toContain('scenario-abc');
|
|
506
|
+
// The guard values must be DIFFERENT so the browser re-seeds
|
|
507
|
+
// Extract the guard comparison value from each script
|
|
508
|
+
const guardPattern = /__codeyam_ls_sid__.*?===\s*([^\)]+)\)/;
|
|
509
|
+
const guard1 = script1.match(guardPattern)?.[1];
|
|
510
|
+
const guard2 = script2.match(guardPattern)?.[1];
|
|
511
|
+
expect(guard1).toBeDefined();
|
|
512
|
+
expect(guard2).toBeDefined();
|
|
513
|
+
expect(guard1).not.toEqual(guard2);
|
|
514
|
+
});
|
|
435
515
|
});
|
|
436
516
|
describe('localStorage injection in HTML responses', () => {
|
|
437
517
|
it('should inject localStorage script before health script in HTML', () => {
|
|
@@ -510,6 +590,121 @@ describe('editorProxy', () => {
|
|
|
510
590
|
expect(response.headers.get('content-encoding')).toBeNull();
|
|
511
591
|
});
|
|
512
592
|
});
|
|
593
|
+
describe('session cookie injection into requests', () => {
|
|
594
|
+
let targetServer;
|
|
595
|
+
let targetPort;
|
|
596
|
+
let tempDir;
|
|
597
|
+
let receivedCookies;
|
|
598
|
+
let originalProjectRoot;
|
|
599
|
+
beforeEach(() => {
|
|
600
|
+
const fs = require('fs');
|
|
601
|
+
const path = require('path');
|
|
602
|
+
const os = require('os');
|
|
603
|
+
const { getProjectRoot } = require('../../state');
|
|
604
|
+
const { setProjectRoot } = require('../../state');
|
|
605
|
+
originalProjectRoot = getProjectRoot();
|
|
606
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'proxy-req-cookie-'));
|
|
607
|
+
setProjectRoot(tempDir);
|
|
608
|
+
receivedCookies = undefined;
|
|
609
|
+
});
|
|
610
|
+
afterEach(async () => {
|
|
611
|
+
const { stopEditorProxy, invalidateScenarioCache, } = require('../editorProxy');
|
|
612
|
+
const { setProjectRoot } = require('../../state');
|
|
613
|
+
invalidateScenarioCache();
|
|
614
|
+
await stopEditorProxy();
|
|
615
|
+
if (targetServer?.listening) {
|
|
616
|
+
await new Promise((resolve) => targetServer.close(() => resolve()));
|
|
617
|
+
}
|
|
618
|
+
if (originalProjectRoot) {
|
|
619
|
+
setProjectRoot(originalProjectRoot);
|
|
620
|
+
}
|
|
621
|
+
const fs = require('fs');
|
|
622
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
623
|
+
resetPreviewHealth();
|
|
624
|
+
});
|
|
625
|
+
it('should forward seed adapter session cookies in the request Cookie header', async () => {
|
|
626
|
+
const fs = require('fs');
|
|
627
|
+
const path = require('path');
|
|
628
|
+
const { startEditorProxy, invalidateScenarioCache, } = require('../editorProxy');
|
|
629
|
+
// Set up scenario files
|
|
630
|
+
const scenarioId = 'integration-auth-test';
|
|
631
|
+
const codeyamDir = path.join(tempDir, '.codeyam');
|
|
632
|
+
const scenariosDir = path.join(codeyamDir, 'editor-scenarios');
|
|
633
|
+
fs.mkdirSync(scenariosDir, { recursive: true });
|
|
634
|
+
fs.writeFileSync(path.join(codeyamDir, 'active-scenario.json'), JSON.stringify({ scenarioId, type: 'application' }));
|
|
635
|
+
fs.writeFileSync(path.join(scenariosDir, `${scenarioId}.json`), JSON.stringify({
|
|
636
|
+
type: 'application',
|
|
637
|
+
seed: { user: [{ id: '1' }] },
|
|
638
|
+
sessionCookies: [
|
|
639
|
+
{
|
|
640
|
+
name: 'sb-test-auth-token',
|
|
641
|
+
value: '{"access_token":"test-jwt","refresh_token":"test-ref"}',
|
|
642
|
+
path: '/',
|
|
643
|
+
sameSite: 'Lax',
|
|
644
|
+
},
|
|
645
|
+
],
|
|
646
|
+
}));
|
|
647
|
+
// Target server that captures the request Cookie header
|
|
648
|
+
targetServer = http.createServer((req, res) => {
|
|
649
|
+
receivedCookies = req.headers.cookie;
|
|
650
|
+
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
651
|
+
res.end('OK');
|
|
652
|
+
});
|
|
653
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
654
|
+
targetPort = targetServer.address().port;
|
|
655
|
+
// Invalidate to force re-read of scenario data
|
|
656
|
+
invalidateScenarioCache();
|
|
657
|
+
const result = await startEditorProxy({
|
|
658
|
+
port: 0,
|
|
659
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
660
|
+
});
|
|
661
|
+
expect(result).not.toBeNull();
|
|
662
|
+
// Make request WITHOUT any cookies (simulates first iframe load after scenario switch)
|
|
663
|
+
await fetch(`http://127.0.0.1:${result.port}/library`);
|
|
664
|
+
// The target server should have received the injected auth cookie
|
|
665
|
+
expect(receivedCookies).toBeDefined();
|
|
666
|
+
expect(receivedCookies).toContain('sb-test-auth-token=');
|
|
667
|
+
expect(receivedCookies).toContain('test-jwt');
|
|
668
|
+
});
|
|
669
|
+
it('should merge injected cookies with existing browser cookies', async () => {
|
|
670
|
+
const fs = require('fs');
|
|
671
|
+
const path = require('path');
|
|
672
|
+
const { startEditorProxy, invalidateScenarioCache, } = require('../editorProxy');
|
|
673
|
+
const scenarioId = 'integration-merge-test';
|
|
674
|
+
const codeyamDir = path.join(tempDir, '.codeyam');
|
|
675
|
+
const scenariosDir = path.join(codeyamDir, 'editor-scenarios');
|
|
676
|
+
fs.mkdirSync(scenariosDir, { recursive: true });
|
|
677
|
+
fs.writeFileSync(path.join(codeyamDir, 'active-scenario.json'), JSON.stringify({ scenarioId, type: 'application' }));
|
|
678
|
+
fs.writeFileSync(path.join(scenariosDir, `${scenarioId}.json`), JSON.stringify({
|
|
679
|
+
type: 'application',
|
|
680
|
+
seed: {},
|
|
681
|
+
session: { cookieValue: 'sess_alice' },
|
|
682
|
+
sessionCookies: [
|
|
683
|
+
{ name: 'sb-auth', value: 'supabase-jwt', path: '/' },
|
|
684
|
+
],
|
|
685
|
+
}));
|
|
686
|
+
targetServer = http.createServer((req, res) => {
|
|
687
|
+
receivedCookies = req.headers.cookie;
|
|
688
|
+
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
689
|
+
res.end('OK');
|
|
690
|
+
});
|
|
691
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
692
|
+
targetPort = targetServer.address().port;
|
|
693
|
+
invalidateScenarioCache();
|
|
694
|
+
const result = await startEditorProxy({
|
|
695
|
+
port: 0,
|
|
696
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
697
|
+
});
|
|
698
|
+
// Make request WITH an existing cookie (simulates browser that already has cookies)
|
|
699
|
+
await fetch(`http://127.0.0.1:${result.port}/library`, {
|
|
700
|
+
headers: { Cookie: 'other-cookie=existing-value' },
|
|
701
|
+
});
|
|
702
|
+
// Should have both the existing cookie and the injected ones
|
|
703
|
+
expect(receivedCookies).toContain('other-cookie=existing-value');
|
|
704
|
+
expect(receivedCookies).toContain('session-token=sess_alice');
|
|
705
|
+
expect(receivedCookies).toContain('sb-auth=supabase-jwt');
|
|
706
|
+
});
|
|
707
|
+
});
|
|
513
708
|
describe('Cache-Control on HTML responses', () => {
|
|
514
709
|
let targetServer;
|
|
515
710
|
let targetPort;
|
|
@@ -563,5 +758,243 @@ describe('editorProxy', () => {
|
|
|
563
758
|
expect(response.headers.get('cache-control')).toBeNull();
|
|
564
759
|
});
|
|
565
760
|
});
|
|
761
|
+
describe('escapeHtml', () => {
|
|
762
|
+
it('should escape ampersands, angle brackets, and quotes', () => {
|
|
763
|
+
expect(escapeHtml('<script>alert("xss")</script>')).toBe('<script>alert("xss")</script>');
|
|
764
|
+
});
|
|
765
|
+
it('should escape single quotes', () => {
|
|
766
|
+
expect(escapeHtml("it's")).toBe('it's');
|
|
767
|
+
});
|
|
768
|
+
it('should return empty string for empty input', () => {
|
|
769
|
+
expect(escapeHtml('')).toBe('');
|
|
770
|
+
});
|
|
771
|
+
it('should leave safe text unchanged', () => {
|
|
772
|
+
expect(escapeHtml('Hello world 123')).toBe('Hello world 123');
|
|
773
|
+
});
|
|
774
|
+
});
|
|
775
|
+
describe('buildErrorPage', () => {
|
|
776
|
+
it('should generate a complete HTML document', () => {
|
|
777
|
+
const page = buildErrorPage(500, 'Internal Server Error', 'something broke');
|
|
778
|
+
expect(page).toContain('<!DOCTYPE html>');
|
|
779
|
+
expect(page).toContain('<html');
|
|
780
|
+
expect(page).toContain('</html>');
|
|
781
|
+
});
|
|
782
|
+
it('should include the status code and title', () => {
|
|
783
|
+
const page = buildErrorPage(502, 'Dev Server Unreachable', 'details here');
|
|
784
|
+
expect(page).toContain('502');
|
|
785
|
+
expect(page).toContain('Dev Server Unreachable');
|
|
786
|
+
});
|
|
787
|
+
it('should include the error detail text', () => {
|
|
788
|
+
const page = buildErrorPage(500, 'Error', 'Connection refused on port 3000');
|
|
789
|
+
expect(page).toContain('Connection refused on port 3000');
|
|
790
|
+
});
|
|
791
|
+
it('should escape HTML in the detail to prevent XSS', () => {
|
|
792
|
+
const page = buildErrorPage(500, 'Error', '<script>alert("xss")</script>');
|
|
793
|
+
expect(page).not.toContain('<script>alert("xss")</script>');
|
|
794
|
+
expect(page).toContain('<script>alert("xss")</script>');
|
|
795
|
+
});
|
|
796
|
+
it('should include codeyam-server-error postMessage', () => {
|
|
797
|
+
const page = buildErrorPage(500, 'Error', 'detail');
|
|
798
|
+
expect(page).toContain('codeyam-server-error');
|
|
799
|
+
expect(page).toContain('postMessage');
|
|
800
|
+
});
|
|
801
|
+
it('should NOT include codeyam-preview-ready postMessage', () => {
|
|
802
|
+
const page = buildErrorPage(500, 'Error', 'detail');
|
|
803
|
+
expect(page).not.toContain('codeyam-preview-ready');
|
|
804
|
+
});
|
|
805
|
+
it('should include a retry button that sends codeyam-server-error-retry', () => {
|
|
806
|
+
const page = buildErrorPage(500, 'Error', 'detail');
|
|
807
|
+
expect(page).toContain('codeyam-server-error-retry');
|
|
808
|
+
// Should have a button element
|
|
809
|
+
expect(page).toMatch(/<button[^>]*>/i);
|
|
810
|
+
});
|
|
811
|
+
it('should include the status code in the postMessage data', () => {
|
|
812
|
+
const page = buildErrorPage(502, 'Unreachable', 'detail');
|
|
813
|
+
// The postMessage should include statusCode: 502
|
|
814
|
+
expect(page).toContain('502');
|
|
815
|
+
});
|
|
816
|
+
it('should escape HTML in the title to prevent XSS', () => {
|
|
817
|
+
const page = buildErrorPage(500, '<img onerror=alert(1)>', 'detail');
|
|
818
|
+
expect(page).not.toContain('<img onerror=alert(1)>');
|
|
819
|
+
expect(page).toContain('<img onerror=alert(1)>');
|
|
820
|
+
});
|
|
821
|
+
it('should handle multiline error detail', () => {
|
|
822
|
+
const detail = 'Error on line 1\nStack trace line 2\nStack trace line 3';
|
|
823
|
+
const page = buildErrorPage(500, 'Error', detail);
|
|
824
|
+
expect(page).toContain('Error on line 1');
|
|
825
|
+
expect(page).toContain('Stack trace line 3');
|
|
826
|
+
});
|
|
827
|
+
it('should handle empty detail', () => {
|
|
828
|
+
const page = buildErrorPage(500, 'Error', '');
|
|
829
|
+
expect(page).toContain('<!DOCTYPE html>');
|
|
830
|
+
expect(page).toContain('codeyam-server-error');
|
|
831
|
+
});
|
|
832
|
+
});
|
|
833
|
+
describe('5xx error page serving', () => {
|
|
834
|
+
let targetServer;
|
|
835
|
+
let targetPort;
|
|
836
|
+
afterEach(async () => {
|
|
837
|
+
const { stopEditorProxy } = require('../editorProxy');
|
|
838
|
+
await stopEditorProxy();
|
|
839
|
+
if (targetServer?.listening) {
|
|
840
|
+
await new Promise((resolve) => targetServer.close(() => resolve()));
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
it('should serve an error page instead of raw HTML for 500 responses', async () => {
|
|
844
|
+
const { startEditorProxy } = require('../editorProxy');
|
|
845
|
+
targetServer = http.createServer((_req, res) => {
|
|
846
|
+
res.writeHead(500, { 'Content-Type': 'text/html' });
|
|
847
|
+
res.end('<html><body>Internal Server Error</body></html>');
|
|
848
|
+
});
|
|
849
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
850
|
+
targetPort = targetServer.address().port;
|
|
851
|
+
const result = await startEditorProxy({
|
|
852
|
+
port: 0,
|
|
853
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
854
|
+
});
|
|
855
|
+
expect(result).not.toBeNull();
|
|
856
|
+
const response = await fetch(`http://127.0.0.1:${result.port}/`);
|
|
857
|
+
expect(response.status).toBe(500);
|
|
858
|
+
const body = await response.text();
|
|
859
|
+
// Should contain the friendly error page, not the raw error
|
|
860
|
+
expect(body).toContain('codeyam-server-error');
|
|
861
|
+
expect(body).toContain('Internal Server Error');
|
|
862
|
+
});
|
|
863
|
+
it('should NOT replace non-HTML 500 responses', async () => {
|
|
864
|
+
const { startEditorProxy } = require('../editorProxy');
|
|
865
|
+
targetServer = http.createServer((_req, res) => {
|
|
866
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
867
|
+
res.end(JSON.stringify({ error: 'server error' }));
|
|
868
|
+
});
|
|
869
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
870
|
+
targetPort = targetServer.address().port;
|
|
871
|
+
const result = await startEditorProxy({
|
|
872
|
+
port: 0,
|
|
873
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
874
|
+
});
|
|
875
|
+
expect(result).not.toBeNull();
|
|
876
|
+
const response = await fetch(`http://127.0.0.1:${result.port}/api/data`);
|
|
877
|
+
expect(response.status).toBe(500);
|
|
878
|
+
const body = await response.text();
|
|
879
|
+
// JSON responses should pass through unchanged
|
|
880
|
+
expect(body).toContain('"error":"server error"');
|
|
881
|
+
expect(body).not.toContain('codeyam-server-error');
|
|
882
|
+
});
|
|
883
|
+
it('should serve an error page for 500 responses with no content type', async () => {
|
|
884
|
+
const { startEditorProxy } = require('../editorProxy');
|
|
885
|
+
// Simulates Next.js returning bare "Internal Server Error" with no Content-Type
|
|
886
|
+
targetServer = http.createServer((_req, res) => {
|
|
887
|
+
res.writeHead(500);
|
|
888
|
+
res.end('Internal Server Error');
|
|
889
|
+
});
|
|
890
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
891
|
+
targetPort = targetServer.address().port;
|
|
892
|
+
const result = await startEditorProxy({
|
|
893
|
+
port: 0,
|
|
894
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
895
|
+
});
|
|
896
|
+
expect(result).not.toBeNull();
|
|
897
|
+
const response = await fetch(`http://127.0.0.1:${result.port}/`);
|
|
898
|
+
expect(response.status).toBe(500);
|
|
899
|
+
const body = await response.text();
|
|
900
|
+
expect(body).toContain('codeyam-server-error');
|
|
901
|
+
expect(body).toContain('<!DOCTYPE html>');
|
|
902
|
+
expect(body).toContain('Internal Server Error');
|
|
903
|
+
});
|
|
904
|
+
it('should serve an error page for 500 text/plain responses', async () => {
|
|
905
|
+
const { startEditorProxy } = require('../editorProxy');
|
|
906
|
+
targetServer = http.createServer((_req, res) => {
|
|
907
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
908
|
+
res.end('Something went wrong');
|
|
909
|
+
});
|
|
910
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
911
|
+
targetPort = targetServer.address().port;
|
|
912
|
+
const result = await startEditorProxy({
|
|
913
|
+
port: 0,
|
|
914
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
915
|
+
});
|
|
916
|
+
expect(result).not.toBeNull();
|
|
917
|
+
const response = await fetch(`http://127.0.0.1:${result.port}/`);
|
|
918
|
+
expect(response.status).toBe(500);
|
|
919
|
+
const body = await response.text();
|
|
920
|
+
expect(body).toContain('codeyam-server-error');
|
|
921
|
+
expect(body).toContain('Something went wrong');
|
|
922
|
+
});
|
|
923
|
+
it('should serve an error page for 503 responses', async () => {
|
|
924
|
+
const { startEditorProxy } = require('../editorProxy');
|
|
925
|
+
targetServer = http.createServer((_req, res) => {
|
|
926
|
+
res.writeHead(503, { 'Content-Type': 'text/html' });
|
|
927
|
+
res.end('<html><body>Service Unavailable</body></html>');
|
|
928
|
+
});
|
|
929
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
930
|
+
targetPort = targetServer.address().port;
|
|
931
|
+
const result = await startEditorProxy({
|
|
932
|
+
port: 0,
|
|
933
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
934
|
+
});
|
|
935
|
+
expect(result).not.toBeNull();
|
|
936
|
+
const response = await fetch(`http://127.0.0.1:${result.port}/`);
|
|
937
|
+
expect(response.status).toBe(503);
|
|
938
|
+
const body = await response.text();
|
|
939
|
+
expect(body).toContain('codeyam-server-error');
|
|
940
|
+
});
|
|
941
|
+
it('should serve an error page for POST requests returning 500', async () => {
|
|
942
|
+
const { startEditorProxy } = require('../editorProxy');
|
|
943
|
+
targetServer = http.createServer((_req, res) => {
|
|
944
|
+
res.writeHead(500, { 'Content-Type': 'text/html' });
|
|
945
|
+
res.end('<html><body>POST Error</body></html>');
|
|
946
|
+
});
|
|
947
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
948
|
+
targetPort = targetServer.address().port;
|
|
949
|
+
const result = await startEditorProxy({
|
|
950
|
+
port: 0,
|
|
951
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
952
|
+
});
|
|
953
|
+
expect(result).not.toBeNull();
|
|
954
|
+
const response = await fetch(`http://127.0.0.1:${result.port}/api/action`, {
|
|
955
|
+
method: 'POST',
|
|
956
|
+
headers: { 'Content-Type': 'application/json' },
|
|
957
|
+
body: JSON.stringify({ test: true }),
|
|
958
|
+
});
|
|
959
|
+
expect(response.status).toBe(500);
|
|
960
|
+
const body = await response.text();
|
|
961
|
+
expect(body).toContain('codeyam-server-error');
|
|
962
|
+
expect(body).toContain('POST Error');
|
|
963
|
+
});
|
|
964
|
+
it('should NOT serve an error page for 4xx responses', async () => {
|
|
965
|
+
const { startEditorProxy } = require('../editorProxy');
|
|
966
|
+
targetServer = http.createServer((_req, res) => {
|
|
967
|
+
res.writeHead(404, { 'Content-Type': 'text/html' });
|
|
968
|
+
res.end('<html><body>Not Found</body></html>');
|
|
969
|
+
});
|
|
970
|
+
await new Promise((resolve) => targetServer.listen(0, '127.0.0.1', () => resolve()));
|
|
971
|
+
targetPort = targetServer.address().port;
|
|
972
|
+
const result = await startEditorProxy({
|
|
973
|
+
port: 0,
|
|
974
|
+
targetUrl: `http://localhost:${targetPort}`,
|
|
975
|
+
});
|
|
976
|
+
expect(result).not.toBeNull();
|
|
977
|
+
const response = await fetch(`http://127.0.0.1:${result.port}/missing`);
|
|
978
|
+
expect(response.status).toBe(404);
|
|
979
|
+
const body = await response.text();
|
|
980
|
+
// 4xx should pass through normally (with health script injected, not error page)
|
|
981
|
+
expect(body).not.toContain('codeyam-server-error');
|
|
982
|
+
expect(body).toContain('Not Found');
|
|
983
|
+
});
|
|
984
|
+
it('should serve an HTML error page for 502 connection failures', async () => {
|
|
985
|
+
const { startEditorProxy } = require('../editorProxy');
|
|
986
|
+
// No target server — connection will fail
|
|
987
|
+
const result = await startEditorProxy({
|
|
988
|
+
port: 0,
|
|
989
|
+
targetUrl: 'http://127.0.0.1:19999',
|
|
990
|
+
});
|
|
991
|
+
expect(result).not.toBeNull();
|
|
992
|
+
const response = await fetch(`http://127.0.0.1:${result.port}/`);
|
|
993
|
+
expect(response.status).toBe(502);
|
|
994
|
+
const body = await response.text();
|
|
995
|
+
expect(body).toContain('codeyam-server-error');
|
|
996
|
+
expect(body).toContain('<!DOCTYPE html>');
|
|
997
|
+
});
|
|
998
|
+
});
|
|
566
999
|
});
|
|
567
1000
|
//# sourceMappingURL=editorProxy.test.js.map
|