@codeyam/codeyam-cli 0.1.0-staging.ad88eeb → 0.1.0-staging.afbbaae
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 +6 -6
- package/analyzer-template/packages/ai/package.json +1 -1
- 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 +7 -7
- package/analyzer-template/packages/database/package.json +3 -3
- package/analyzer-template/packages/database/src/lib/kysely/tables/editorScenariosTable.ts +82 -0
- package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +25 -15
- package/analyzer-template/packages/database/src/lib/loadEntities.ts +0 -6
- package/analyzer-template/packages/database/src/lib/loadEntity.ts +19 -8
- package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +0 -65
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts +5 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js +84 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -1
- 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/loadEntities.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +0 -6
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.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/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +0 -25
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.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 +56 -0
- package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js.map +1 -0
- package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js +137 -47
- package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js.map +1 -1
- package/codeyam-cli/src/commands/editor.js +4254 -656
- 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 +89 -34
- 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 +3 -8
- package/codeyam-cli/src/data/techStacks.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js +173 -0
- package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js +46 -0
- package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js.map +1 -0
- 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 +62 -8
- package/codeyam-cli/src/utils/__tests__/editorApi.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +3526 -1
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorBroadcastViewport.test.js +76 -0
- package/codeyam-cli/src/utils/__tests__/editorBroadcastViewport.test.js.map +1 -0
- 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__/editorDeleteScenario.test.js +100 -0
- package/codeyam-cli/src/utils/__tests__/editorDeleteScenario.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js +27 -2
- package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js +76 -3
- package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js +381 -0
- package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js.map +1 -0
- 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__/editorLoaderHelpers.test.js +202 -1
- package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorMigration.test.js +435 -0
- package/codeyam-cli/src/utils/__tests__/editorMigration.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/editorPreview.test.js +96 -1
- package/codeyam-cli/src/utils/__tests__/editorPreview.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js +144 -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 +1548 -1
- package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js +201 -1
- package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorSeedAdapterPrismaValidation.test.js +143 -0
- package/codeyam-cli/src/utils/__tests__/editorSeedAdapterPrismaValidation.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/editorSessionFilter.test.js +66 -0
- package/codeyam-cli/src/utils/__tests__/editorSessionFilter.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/editorShouldRevalidate.test.js +53 -0
- package/codeyam-cli/src/utils/__tests__/editorShouldRevalidate.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +395 -11
- 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__/parseRegisterArg.test.js +30 -2
- package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js.map +1 -1
- 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__/routePatternMatching.test.js +118 -0
- package/codeyam-cli/src/utils/__tests__/routePatternMatching.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js +284 -0
- package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js +649 -223
- 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__/setupClaudeCodeSettings.test.js +1 -0
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
- 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 +39 -8
- package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
- package/codeyam-cli/src/utils/analyzer.js +19 -0
- package/codeyam-cli/src/utils/analyzer.js.map +1 -1
- package/codeyam-cli/src/utils/analyzerFinalization.js +100 -0
- package/codeyam-cli/src/utils/analyzerFinalization.js.map +1 -0
- package/codeyam-cli/src/utils/backgroundServer.js +93 -17
- package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/utils/database.js +37 -2
- package/codeyam-cli/src/utils/database.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 +27 -5
- package/codeyam-cli/src/utils/editorApi.js.map +1 -1
- package/codeyam-cli/src/utils/editorAudit.js +700 -10
- package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
- package/codeyam-cli/src/utils/editorBroadcastViewport.js +26 -0
- package/codeyam-cli/src/utils/editorBroadcastViewport.js.map +1 -0
- package/codeyam-cli/src/utils/editorDeleteScenario.js +67 -0
- package/codeyam-cli/src/utils/editorDeleteScenario.js.map +1 -0
- package/codeyam-cli/src/utils/editorDevServer.js +5 -1
- package/codeyam-cli/src/utils/editorDevServer.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 +144 -0
- package/codeyam-cli/src/utils/editorEntityHelpers.js.map +1 -0
- package/codeyam-cli/src/utils/editorGuard.js +36 -0
- package/codeyam-cli/src/utils/editorGuard.js.map +1 -0
- package/codeyam-cli/src/utils/editorLoaderHelpers.js +72 -1
- package/codeyam-cli/src/utils/editorLoaderHelpers.js.map +1 -1
- package/codeyam-cli/src/utils/editorMigration.js +224 -0
- package/codeyam-cli/src/utils/editorMigration.js.map +1 -0
- package/codeyam-cli/src/utils/editorPreview.js +33 -0
- 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 +591 -0
- package/codeyam-cli/src/utils/editorScenarios.js.map +1 -1
- package/codeyam-cli/src/utils/editorSeedAdapter.js +308 -6
- package/codeyam-cli/src/utils/editorSeedAdapter.js.map +1 -1
- package/codeyam-cli/src/utils/editorShouldRevalidate.js +21 -0
- package/codeyam-cli/src/utils/editorShouldRevalidate.js.map +1 -0
- package/codeyam-cli/src/utils/entityChangeStatus.js +53 -6
- package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -1
- package/codeyam-cli/src/utils/entityChangeStatus.server.js +72 -3
- 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 +50 -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/parseRegisterArg.js.map +1 -1
- package/codeyam-cli/src/utils/progress.js +2 -2
- package/codeyam-cli/src/utils/progress.js.map +1 -1
- 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/routePatternMatching.js +129 -0
- package/codeyam-cli/src/utils/routePatternMatching.js.map +1 -0
- package/codeyam-cli/src/utils/scenarioCoverage.js +77 -0
- package/codeyam-cli/src/utils/scenarioCoverage.js.map +1 -0
- package/codeyam-cli/src/utils/scenariosManifest.js +275 -74
- 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/serverState.js +30 -0
- package/codeyam-cli/src/utils/serverState.js.map +1 -1
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +1 -0
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
- package/codeyam-cli/src/utils/simulationGateMiddleware.js +17 -1
- package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -1
- package/codeyam-cli/src/utils/slugUtils.js +25 -0
- package/codeyam-cli/src/utils/slugUtils.js.map +1 -0
- package/codeyam-cli/src/utils/syncMocksMiddleware.js +2 -2
- package/codeyam-cli/src/utils/syncMocksMiddleware.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 +153 -0
- package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js.map +1 -0
- package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js +107 -0
- package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js.map +1 -0
- package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +822 -0
- package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -1
- package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js +315 -0
- package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js.map +1 -0
- 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 +86 -0
- package/codeyam-cli/src/webserver/app/lib/clientErrors.js.map +1 -0
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/git.js +3 -2
- package/codeyam-cli/src/webserver/app/lib/git.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/app/types/editor.js +8 -0
- package/codeyam-cli/src/webserver/app/types/editor.js.map +1 -0
- package/codeyam-cli/src/webserver/backgroundServer.js +60 -61
- package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/CopyButton-DTBZZfSk.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-BcgbViKV.js → EntityItem-BxclONWq.js} +3 -3
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeBadge-CQgyEGV-.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-CQIG2qda.js → EntityTypeIcon-BsnEOJZ_.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-ByaELMbv.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-6WjVfhxX.js +25 -0
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-ChX-Hp7W.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-BU_OAEMP.js → LoadingDots-By5zI316.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-ceAyBX-H.js → LogViewer-C-9zQdXg.js} +3 -3
- package/codeyam-cli/src/webserver/build/client/assets/MiniClaudeChat-Bs2_Oua4.js +36 -0
- package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-BzHcG7SE.js → ReportIssueModal-DQsceHVv.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-DThcm_9M.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-0DY_NKil.js → ScenarioViewer-Cl4oOA3A.js} +3 -3
- package/codeyam-cli/src/webserver/build/client/assets/Spinner-CIil5-gb.js +34 -0
- package/codeyam-cli/src/webserver/build/client/assets/TruncatedFilePath-CK7-NaPZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/ViewportInspectBar-BqkA9zyZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{_index-DLxKhri3.js → _index-DnOgyseQ.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BcY3q6nt.js → activity.(_tab)-DqM9hbNE.js} +3 -3
- package/codeyam-cli/src/webserver/build/client/assets/{addon-web-links-Duc5hnl7.js → addon-web-links-C58dYPwR.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-Bni3iiUj.js → agent-transcripts-B8NCeOrm.js} +3 -3
- 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-rename-scenario-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-save-seed-state-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-coverage-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-prompt-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-session-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-BYOypzCa.js → book-open-BFSIqZgO.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-C_Pmso5S.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-BVMi9VA5.js → circle-check-DLPObLUx.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{copy-n2FB0_Sw.js → copy-DXEmO0TD.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-CC6AbExI.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-iRhRIFlp.js +1 -0
- 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._-BF4oLwaE.js → entity._sha._-pc-vc6wO.js} +13 -12
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-C8AyYgYT.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DziaVQX1.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-BTcpgIpC.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-BMvVHNXU.js → entity._sha_.edit._scenarioId-D_O_ajfZ.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{entry.client-DTvKq3TY.js → entry.client-j1Vi0bco.js} +6 -6
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-Daa96Fr1.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/files-kuny2Q_s.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/git-DgCZPMie.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/globals-L-aUIeux.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-BcvgDzbZ.js → index-BliGSSpl.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-yHOVb4rc.js → index-SqjQKTdH.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-10oVnAAH.js → index-vyrZD2g4.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/jsx-runtime-D_zvdyIk.js +9 -0
- package/codeyam-cli/src/webserver/build/client/assets/labs-c3yLxSEp.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-DaAZ_H2w.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-CEWIUC4t.js +101 -0
- package/codeyam-cli/src/webserver/build/client/assets/{pause-f5-1lKBt.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-Di64LWVb.js → search-BooqacKS.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-BM0nbryO.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/simulations-ovy6FjRY.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{terminal-Br7MOqts.js → terminal-DHemCJIs.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-BLdiCuG-.js → triangle-alert-D87ekDl8.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-Dk0Tciqg.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C8QvIe05.js +2 -0
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-jkCytuYz.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/useToast-BgqkixU9.js +1 -0
- package/codeyam-cli/src/webserver/build/client/sound-test.html +98 -0
- package/codeyam-cli/src/webserver/build/server/assets/analysisRunner-QgInFGdU.js +16 -0
- package/codeyam-cli/src/webserver/build/server/assets/index-zblh9auj.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/init-DaE0CBjk.js +14 -0
- package/codeyam-cli/src/webserver/build/server/assets/progress-CHTtrxFG.js +1 -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 +675 -17
- package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
- package/codeyam-cli/src/webserver/idleDetector.js +130 -0
- package/codeyam-cli/src/webserver/idleDetector.js.map +1 -0
- package/codeyam-cli/src/webserver/mockStateEvents.js +28 -0
- package/codeyam-cli/src/webserver/mockStateEvents.js.map +1 -0
- package/codeyam-cli/src/webserver/public/sound-test.html +98 -0
- package/codeyam-cli/src/webserver/scripts/journalCapture.ts +53 -0
- package/codeyam-cli/src/webserver/server.js +192 -4
- package/codeyam-cli/src/webserver/server.js.map +1 -1
- package/codeyam-cli/src/webserver/terminalServer.js +389 -52
- 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/chrome-extension-react/README.md +46 -0
- package/codeyam-cli/templates/chrome-extension-react/package.json +1 -0
- package/codeyam-cli/templates/chrome-extension-react/vite.config.ts +6 -0
- package/codeyam-cli/templates/codeyam-editor-claude.md +86 -5
- 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 +193 -56
- package/codeyam-cli/templates/expo-react-native/MOBILE_SETUP.md +204 -5
- package/codeyam-cli/templates/expo-react-native/README.md +41 -0
- 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 +33 -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/DATABASE.md +14 -0
- package/codeyam-cli/templates/nextjs-prisma-sqlite/README.md +53 -0
- package/codeyam-cli/templates/nextjs-prisma-sqlite/gitignore +1 -0
- package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +2 -1
- package/codeyam-cli/templates/nextjs-prisma-sqlite/seed-adapter.ts +88 -40
- package/codeyam-cli/templates/nextjs-prisma-supabase/README.md +52 -0
- package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +2 -1
- package/codeyam-cli/templates/seed-adapters/supabase.ts +475 -0
- package/codeyam-cli/templates/skills/codeyam-dev-mode/SKILL.md +1 -1
- package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +109 -10
- 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/kysely/tables/editorScenariosTable.js +84 -0
- package/packages/database/src/lib/kysely/tables/editorScenariosTable.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/loadEntities.js +0 -6
- package/packages/database/src/lib/loadEntities.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/database/src/lib/updateCommitMetadata.js +0 -25
- package/packages/database/src/lib/updateCommitMetadata.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/CopyButton-BPXZwM4t.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeBadge-g3saevPb.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-Bu6c6aDe.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-DYFW3lDD.js +0 -25
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-DLeucoVX.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BED4B6sP.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/Spinner-Bb5uFQ5V.js +0 -34
- package/codeyam-cli/src/webserver/build/client/assets/TruncatedFilePath-C8OKAR5x.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ViewportInspectBar-oAf2Kqsf.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-JZWAC4HX-C4pqxYJB.js +0 -51
- package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-DcX-ZS3p.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-Csi0_PMl.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/editor-BuT_Huj0.js +0 -10
- package/codeyam-cli/src/webserver/build/client/assets/editorPreview-B7ztwLut.js +0 -41
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-D5rYBT5x.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-CF164ouH.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-p9hhkjJM.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-cPo8LiG3.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-BZrlFE1F.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-DdZcvjGh.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-BkWJ_UNc.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/labs-Zk7ryIM1.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-b0f1372e.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/memory-Bl2rpw8u.js +0 -96
- package/codeyam-cli/src/webserver/build/client/assets/root-B_X8HS1x.js +0 -67
- package/codeyam-cli/src/webserver/build/client/assets/settings-0OrEMU6J.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-DWT-CvLy.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-CrAK28Bc.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C14nCb1q.js +0 -2
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-O-jkvSPx.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-9FIWuYfK.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-CbF6h3dj.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-DRFwTJqO.js +0 -367
- 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
|
@@ -5,6 +5,7 @@ import path from 'path';
|
|
|
5
5
|
import { getProjectRoot } from "../state.js";
|
|
6
6
|
import { createMockStateManager, } from "../utils/editorMockState.js";
|
|
7
7
|
import { computeEditorPorts } from "../utils/editorDevServer.js";
|
|
8
|
+
import { mockStateEventEmitter } from "./mockStateEvents.js";
|
|
8
9
|
/**
|
|
9
10
|
* Normalize a target URL by stripping trailing slashes for consistency.
|
|
10
11
|
*
|
|
@@ -60,10 +61,128 @@ export async function resolveLoopbackAddress(port) {
|
|
|
60
61
|
}
|
|
61
62
|
// Global key so the proxy survives HMR
|
|
62
63
|
const GLOBAL_KEY = '__codeyam_editor_proxy__';
|
|
64
|
+
// ─── Live Preview Health ─────────────────────────────────────────────
|
|
65
|
+
const PREVIEW_HEALTH_KEY = '__codeyam_preview_health__';
|
|
66
|
+
function getPreviewHealth() {
|
|
67
|
+
return globalThis[PREVIEW_HEALTH_KEY] ?? null;
|
|
68
|
+
}
|
|
69
|
+
function setPreviewHealth(report) {
|
|
70
|
+
globalThis[PREVIEW_HEALTH_KEY] = report;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the current live preview health report (read by API endpoint).
|
|
74
|
+
*/
|
|
75
|
+
export function getPreviewHealthReport() {
|
|
76
|
+
return getPreviewHealth();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Reset preview health state (called when a new HTML page is served).
|
|
80
|
+
*/
|
|
81
|
+
export function resetPreviewHealth() {
|
|
82
|
+
setPreviewHealth(null);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Error-catching script injected into HTML responses.
|
|
86
|
+
* Uses vanilla JS for maximum compatibility.
|
|
87
|
+
*/
|
|
88
|
+
export const PREVIEW_HEALTH_SCRIPT = `<script data-codeyam-health>
|
|
89
|
+
(function() {
|
|
90
|
+
var errors = [];
|
|
91
|
+
var reported = false;
|
|
92
|
+
function report(type, msg, stack) {
|
|
93
|
+
errors.push({ type: type, message: msg, stack: stack, timestamp: Date.now() });
|
|
94
|
+
if (!reported) {
|
|
95
|
+
reported = true;
|
|
96
|
+
setTimeout(function() { flush(); }, 500);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function flush() {
|
|
100
|
+
fetch('/__codeyam__/preview-health', {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers: { 'Content-Type': 'application/json' },
|
|
103
|
+
body: JSON.stringify({ errors: errors, url: location.href })
|
|
104
|
+
}).catch(function(){});
|
|
105
|
+
reported = false;
|
|
106
|
+
errors = [];
|
|
107
|
+
}
|
|
108
|
+
window.addEventListener('error', function(e) {
|
|
109
|
+
report('error', e.message, e.error && e.error.stack);
|
|
110
|
+
});
|
|
111
|
+
window.addEventListener('unhandledrejection', function(e) {
|
|
112
|
+
report('unhandledrejection', String(e.reason), e.reason && e.reason.stack);
|
|
113
|
+
});
|
|
114
|
+
var origError = console.error;
|
|
115
|
+
console.error = function() {
|
|
116
|
+
report('console.error', Array.prototype.join.call(arguments, ' '));
|
|
117
|
+
origError.apply(console, arguments);
|
|
118
|
+
};
|
|
119
|
+
window.addEventListener('load', function() {
|
|
120
|
+
setTimeout(function() {
|
|
121
|
+
var hasContent = document.body && document.body.innerText.trim().length > 0;
|
|
122
|
+
fetch('/__codeyam__/preview-health', {
|
|
123
|
+
method: 'POST',
|
|
124
|
+
headers: { 'Content-Type': 'application/json' },
|
|
125
|
+
body: JSON.stringify({
|
|
126
|
+
loaded: true,
|
|
127
|
+
hasContent: hasContent,
|
|
128
|
+
url: location.href,
|
|
129
|
+
errorCount: errors.length
|
|
130
|
+
})
|
|
131
|
+
}).catch(function(){});
|
|
132
|
+
}, 1000);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Network-idle detection: notify the parent editor when all initial
|
|
136
|
+
// fetch requests have completed, so it can show the preview after
|
|
137
|
+
// client-side data (API calls) has arrived — not just when the DOM loads.
|
|
138
|
+
var inflight = 0;
|
|
139
|
+
var settled = false;
|
|
140
|
+
var settleTimer = null;
|
|
141
|
+
var origFetch = window.fetch;
|
|
142
|
+
window.fetch = function() {
|
|
143
|
+
if (!settled) inflight++;
|
|
144
|
+
return origFetch.apply(this, arguments).then(function(resp) {
|
|
145
|
+
if (!settled) { inflight--; checkSettle(); }
|
|
146
|
+
return resp;
|
|
147
|
+
}, function(err) {
|
|
148
|
+
if (!settled) { inflight--; checkSettle(); }
|
|
149
|
+
throw err;
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
function checkSettle() {
|
|
153
|
+
if (inflight <= 0 && !settled) {
|
|
154
|
+
clearTimeout(settleTimer);
|
|
155
|
+
// Small delay to allow React to re-render with the fetched data
|
|
156
|
+
settleTimer = setTimeout(function() {
|
|
157
|
+
if (inflight <= 0) {
|
|
158
|
+
settled = true;
|
|
159
|
+
try {
|
|
160
|
+
window.parent.postMessage({ type: 'codeyam-preview-ready' }, '*');
|
|
161
|
+
} catch(e) {}
|
|
162
|
+
}
|
|
163
|
+
}, 100);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Fallback: if no fetches happen (static page), settle after load
|
|
167
|
+
window.addEventListener('load', function() {
|
|
168
|
+
setTimeout(function() { checkSettle(); }, 200);
|
|
169
|
+
});
|
|
170
|
+
})();
|
|
171
|
+
</script>`;
|
|
63
172
|
const CACHE_TTL_MS = 500;
|
|
64
173
|
let scenarioCache = { data: null, timestamp: 0 };
|
|
65
174
|
// Session config extracted from the active scenario — drives cookie injection
|
|
66
175
|
let sessionConfig = undefined;
|
|
176
|
+
/** Session cookies from the seed adapter (e.g. Supabase auth tokens). */
|
|
177
|
+
let seedSessionCookies = undefined;
|
|
178
|
+
// localStorage config extracted from the active scenario — drives HTML injection
|
|
179
|
+
let localStorageConfig = null;
|
|
180
|
+
// Active scenario ID — used to gate localStorage seeding (only re-seed on switch)
|
|
181
|
+
let activeScenarioId = null;
|
|
182
|
+
// Prototype ID — used to gate a one-time localStorage.clear() when a new project is scaffolded
|
|
183
|
+
let currentPrototypeId = null;
|
|
184
|
+
// Current scenario type — 'application'/'user' for seed-based, 'component' for mock-based
|
|
185
|
+
let currentScenarioType = null;
|
|
67
186
|
// Max body size to buffer for mock matching (10MB)
|
|
68
187
|
const MAX_BODY_SIZE = 10 * 1024 * 1024;
|
|
69
188
|
function getProxyState() {
|
|
@@ -117,6 +236,8 @@ function readScenarioData() {
|
|
|
117
236
|
const active = JSON.parse(fs.readFileSync(activeScenarioPath, 'utf-8'));
|
|
118
237
|
const scenarioId = active.scenarioId;
|
|
119
238
|
if (!scenarioId) {
|
|
239
|
+
// No active scenario — but may have a prototypeId for localStorage clearing
|
|
240
|
+
currentPrototypeId = active.prototypeId || null;
|
|
120
241
|
scenarioCache = { data: null, timestamp: now };
|
|
121
242
|
return null;
|
|
122
243
|
}
|
|
@@ -129,8 +250,14 @@ function readScenarioData() {
|
|
|
129
250
|
const rawData = JSON.parse(fs.readFileSync(dataFilePath, 'utf-8'));
|
|
130
251
|
// Extract session config for cookie injection
|
|
131
252
|
sessionConfig = rawData.session || null;
|
|
253
|
+
// Extract seed adapter session cookies (e.g. Supabase auth)
|
|
254
|
+
seedSessionCookies = rawData.sessionCookies || undefined;
|
|
255
|
+
// Extract localStorage config for HTML injection
|
|
256
|
+
localStorageConfig = rawData.localStorage || null;
|
|
257
|
+
activeScenarioId = scenarioId;
|
|
132
258
|
// Type-aware: for seed-based scenarios, only serve externalApis via proxy
|
|
133
259
|
const scenarioType = active.type || rawData.type || null;
|
|
260
|
+
currentScenarioType = scenarioType;
|
|
134
261
|
let mockData;
|
|
135
262
|
if ((scenarioType === 'application' || scenarioType === 'user') &&
|
|
136
263
|
rawData.seed) {
|
|
@@ -204,6 +331,13 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
|
|
|
204
331
|
const target = new URL(targetUrl);
|
|
205
332
|
const hostname = stripIPv6Brackets(target.hostname);
|
|
206
333
|
const headers = { ...req.headers, host: `${target.hostname}:${target.port}` };
|
|
334
|
+
// Remove accept-encoding so the dev server returns uncompressed responses.
|
|
335
|
+
// The proxy injects a health script into HTML — this fails on compressed bodies.
|
|
336
|
+
delete headers['accept-encoding'];
|
|
337
|
+
// Inject session cookies into the request so the dev server sees auth
|
|
338
|
+
// on the first request after a scenario switch (before the browser has
|
|
339
|
+
// stored them from Set-Cookie responses).
|
|
340
|
+
injectRequestCookies(headers);
|
|
207
341
|
// Update content-length if we have the body buffer
|
|
208
342
|
if (bodyBuffer) {
|
|
209
343
|
headers['content-length'] = String(bodyBuffer.length);
|
|
@@ -217,19 +351,70 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
|
|
|
217
351
|
};
|
|
218
352
|
const proxyReq = http.request(options, (proxyRes) => {
|
|
219
353
|
const status = proxyRes.statusCode || 200;
|
|
354
|
+
if (status >= 300 && status < 400) {
|
|
355
|
+
console.log(`[editorProxy] Target redirect ${status} for ${req.method} ${req.url} → ${proxyRes.headers.location}`);
|
|
356
|
+
}
|
|
220
357
|
if (status >= 400) {
|
|
221
358
|
console.warn(`[editorProxy] Target returned ${status} for ${req.method} ${req.url}`);
|
|
222
359
|
}
|
|
223
360
|
const headers = { ...proxyRes.headers };
|
|
224
361
|
injectSessionCookie(headers);
|
|
362
|
+
// Check if response is HTML — if so, buffer and inject health script
|
|
363
|
+
const contentType = proxyRes.headers['content-type'] || '';
|
|
364
|
+
if (contentType.includes('text/html')) {
|
|
365
|
+
resetPreviewHealth();
|
|
366
|
+
const chunks = [];
|
|
367
|
+
proxyRes.on('data', (chunk) => chunks.push(chunk));
|
|
368
|
+
proxyRes.on('end', () => {
|
|
369
|
+
const body = Buffer.concat(chunks).toString('utf-8');
|
|
370
|
+
delete headers['content-length'];
|
|
371
|
+
delete headers['content-encoding'];
|
|
372
|
+
headers['cache-control'] = 'no-store, must-revalidate';
|
|
373
|
+
// Serve a friendly error page for 5xx responses instead of
|
|
374
|
+
// forwarding the raw error HTML (e.g. Next.js "Internal Server Error")
|
|
375
|
+
if (status >= 500) {
|
|
376
|
+
const errorPage = buildErrorPage(status, 'Internal Server Error', body);
|
|
377
|
+
res.writeHead(status, headers);
|
|
378
|
+
res.end(errorPage);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const lsScript = buildLocalStorageScript(localStorageConfig, activeScenarioId || '', currentPrototypeId);
|
|
382
|
+
const injected = injectHealthScript(body, lsScript);
|
|
383
|
+
res.writeHead(status, headers);
|
|
384
|
+
res.end(injected);
|
|
385
|
+
});
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
// For 5xx responses without a content type or with text/plain,
|
|
389
|
+
// serve a friendly error page. These are typically broken dev servers
|
|
390
|
+
// (e.g. Next.js returning bare "Internal Server Error" with no headers).
|
|
391
|
+
// JSON API errors are left alone — they're legitimate responses.
|
|
392
|
+
if (status >= 500 && !contentType.includes('application/json')) {
|
|
393
|
+
const chunks = [];
|
|
394
|
+
proxyRes.on('data', (chunk) => chunks.push(chunk));
|
|
395
|
+
proxyRes.on('end', () => {
|
|
396
|
+
const body = Buffer.concat(chunks).toString('utf-8');
|
|
397
|
+
const errorPage = buildErrorPage(status, 'Internal Server Error', body);
|
|
398
|
+
res.writeHead(status, {
|
|
399
|
+
'Content-Type': 'text/html',
|
|
400
|
+
'Cache-Control': 'no-store',
|
|
401
|
+
});
|
|
402
|
+
res.end(errorPage);
|
|
403
|
+
});
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
225
406
|
res.writeHead(status, headers);
|
|
226
407
|
proxyRes.pipe(res, { end: true });
|
|
227
408
|
});
|
|
228
409
|
proxyReq.on('error', (err) => {
|
|
229
410
|
console.warn(`[editorProxy] Forward error for ${req.method} ${req.url}: ${err.message}`);
|
|
230
411
|
if (!res.headersSent) {
|
|
231
|
-
|
|
232
|
-
res.
|
|
412
|
+
const errorPage = buildErrorPage(502, 'Dev Server Unreachable', `The proxy could not connect to the dev server. It may be starting up, restarting, or crashed.\n\n${err.message}`);
|
|
413
|
+
res.writeHead(502, {
|
|
414
|
+
'Content-Type': 'text/html',
|
|
415
|
+
'Cache-Control': 'no-store',
|
|
416
|
+
});
|
|
417
|
+
res.end(errorPage);
|
|
233
418
|
}
|
|
234
419
|
});
|
|
235
420
|
if (bodyBuffer && bodyBuffer.length > 0) {
|
|
@@ -240,33 +425,97 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
|
|
|
240
425
|
}
|
|
241
426
|
}
|
|
242
427
|
/**
|
|
243
|
-
* Forward an HTTP request to the target dev server
|
|
428
|
+
* Forward an HTTP request to the target dev server.
|
|
429
|
+
* For HTML responses: buffers body to inject health-check script.
|
|
430
|
+
* For non-HTML responses: pipes directly (no buffering).
|
|
244
431
|
*/
|
|
245
432
|
function forwardRequest(req, res, targetUrl) {
|
|
246
433
|
const target = new URL(targetUrl);
|
|
247
434
|
const hostname = stripIPv6Brackets(target.hostname);
|
|
435
|
+
// Build headers, stripping accept-encoding so the dev server returns uncompressed
|
|
436
|
+
// responses. The proxy injects a health script into HTML — this fails on compressed bodies.
|
|
437
|
+
const { 'accept-encoding': _ae, ...forwardHeaders } = req.headers;
|
|
438
|
+
const reqHeaders = {
|
|
439
|
+
...forwardHeaders,
|
|
440
|
+
host: `${target.hostname}:${target.port}`,
|
|
441
|
+
};
|
|
442
|
+
// Inject session cookies into the request so the dev server sees auth
|
|
443
|
+
// on the first request after a scenario switch.
|
|
444
|
+
injectRequestCookies(reqHeaders);
|
|
248
445
|
const options = {
|
|
249
446
|
hostname,
|
|
250
447
|
port: target.port,
|
|
251
448
|
path: req.url,
|
|
252
449
|
method: req.method,
|
|
253
|
-
headers:
|
|
450
|
+
headers: reqHeaders,
|
|
254
451
|
};
|
|
255
452
|
const proxyReq = http.request(options, (proxyRes) => {
|
|
256
453
|
const status = proxyRes.statusCode || 200;
|
|
454
|
+
if (status >= 300 && status < 400) {
|
|
455
|
+
console.log(`[editorProxy] Target redirect ${status} for ${req.method} ${req.url} → ${proxyRes.headers.location}`);
|
|
456
|
+
}
|
|
257
457
|
if (status >= 400) {
|
|
258
458
|
console.warn(`[editorProxy] Target returned ${status} for ${req.method} ${req.url}`);
|
|
259
459
|
}
|
|
260
460
|
const headers = { ...proxyRes.headers };
|
|
261
461
|
injectSessionCookie(headers);
|
|
462
|
+
// Check if response is HTML — if so, buffer and inject health script
|
|
463
|
+
const contentType = proxyRes.headers['content-type'] || '';
|
|
464
|
+
if (contentType.includes('text/html')) {
|
|
465
|
+
// Reset health state for new page loads
|
|
466
|
+
resetPreviewHealth();
|
|
467
|
+
const chunks = [];
|
|
468
|
+
proxyRes.on('data', (chunk) => chunks.push(chunk));
|
|
469
|
+
proxyRes.on('end', () => {
|
|
470
|
+
const body = Buffer.concat(chunks).toString('utf-8');
|
|
471
|
+
delete headers['content-length'];
|
|
472
|
+
delete headers['content-encoding'];
|
|
473
|
+
headers['cache-control'] = 'no-store, must-revalidate';
|
|
474
|
+
// Serve a friendly error page for 5xx responses instead of
|
|
475
|
+
// forwarding the raw error HTML (e.g. Next.js "Internal Server Error")
|
|
476
|
+
if (status >= 500) {
|
|
477
|
+
const errorPage = buildErrorPage(status, 'Internal Server Error', body);
|
|
478
|
+
res.writeHead(status, headers);
|
|
479
|
+
res.end(errorPage);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
const lsScript = buildLocalStorageScript(localStorageConfig, activeScenarioId || '', currentPrototypeId);
|
|
483
|
+
const injected = injectHealthScript(body, lsScript);
|
|
484
|
+
res.writeHead(status, headers);
|
|
485
|
+
res.end(injected);
|
|
486
|
+
});
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
// For 5xx responses without a content type or with text/plain,
|
|
490
|
+
// serve a friendly error page. These are typically broken dev servers
|
|
491
|
+
// (e.g. Next.js returning bare "Internal Server Error" with no headers).
|
|
492
|
+
// JSON API errors are left alone — they're legitimate responses.
|
|
493
|
+
if (status >= 500 && !contentType.includes('application/json')) {
|
|
494
|
+
const chunks = [];
|
|
495
|
+
proxyRes.on('data', (chunk) => chunks.push(chunk));
|
|
496
|
+
proxyRes.on('end', () => {
|
|
497
|
+
const body = Buffer.concat(chunks).toString('utf-8');
|
|
498
|
+
const errorPage = buildErrorPage(status, 'Internal Server Error', body);
|
|
499
|
+
res.writeHead(status, {
|
|
500
|
+
'Content-Type': 'text/html',
|
|
501
|
+
'Cache-Control': 'no-store',
|
|
502
|
+
});
|
|
503
|
+
res.end(errorPage);
|
|
504
|
+
});
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
262
507
|
res.writeHead(status, headers);
|
|
263
508
|
proxyRes.pipe(res, { end: true });
|
|
264
509
|
});
|
|
265
510
|
proxyReq.on('error', (err) => {
|
|
266
511
|
console.warn(`[editorProxy] Forward error for ${req.method} ${req.url}: ${err.message}`);
|
|
267
512
|
if (!res.headersSent) {
|
|
268
|
-
|
|
269
|
-
res.
|
|
513
|
+
const errorPage = buildErrorPage(502, 'Dev Server Unreachable', `The proxy could not connect to the dev server. It may be starting up, restarting, or crashed.\n\n${err.message}`);
|
|
514
|
+
res.writeHead(502, {
|
|
515
|
+
'Content-Type': 'text/html',
|
|
516
|
+
'Cache-Control': 'no-store',
|
|
517
|
+
});
|
|
518
|
+
res.end(errorPage);
|
|
270
519
|
}
|
|
271
520
|
});
|
|
272
521
|
req.pipe(proxyReq, { end: true });
|
|
@@ -278,25 +527,94 @@ function forwardRequest(req, res, targetUrl) {
|
|
|
278
527
|
* When sessionConfig is undefined (no scenario loaded yet), does nothing.
|
|
279
528
|
*/
|
|
280
529
|
function injectSessionCookie(headers) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
530
|
+
const cookies = [];
|
|
531
|
+
// Dev auth cookie (built-in session-token)
|
|
532
|
+
if (sessionConfig !== undefined) {
|
|
533
|
+
if (sessionConfig?.cookieValue) {
|
|
534
|
+
cookies.push(`session-token=${sessionConfig.cookieValue}; Path=/; SameSite=Lax`);
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
cookies.push(`session-token=; Path=/; Max-Age=0`);
|
|
538
|
+
}
|
|
286
539
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
540
|
+
// Seed adapter session cookies (e.g. Supabase auth tokens)
|
|
541
|
+
if (seedSessionCookies && seedSessionCookies.length > 0) {
|
|
542
|
+
for (const sc of seedSessionCookies) {
|
|
543
|
+
const cookiePath = sc.path || '/';
|
|
544
|
+
const sameSite = sc.sameSite || 'Lax';
|
|
545
|
+
cookies.push(`${sc.name}=${sc.value}; Path=${cookiePath}; SameSite=${sameSite}`);
|
|
546
|
+
}
|
|
290
547
|
}
|
|
548
|
+
if (cookies.length === 0)
|
|
549
|
+
return;
|
|
291
550
|
const existing = headers['set-cookie'];
|
|
292
551
|
if (existing) {
|
|
293
552
|
headers['set-cookie'] = [
|
|
294
553
|
...(Array.isArray(existing) ? existing : [existing]),
|
|
295
|
-
|
|
554
|
+
...cookies,
|
|
296
555
|
];
|
|
297
556
|
}
|
|
298
557
|
else {
|
|
299
|
-
headers['set-cookie'] =
|
|
558
|
+
headers['set-cookie'] = cookies;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Get session cookies that should be injected into requests forwarded to the
|
|
563
|
+
* dev server. Returns an array of {name, value} pairs, or null if no session
|
|
564
|
+
* cookies are configured.
|
|
565
|
+
*
|
|
566
|
+
* This is the counterpart to `injectSessionCookie()` (which adds Set-Cookie
|
|
567
|
+
* to responses). Without request-side injection, the first request after a
|
|
568
|
+
* scenario switch has no cookies — the dev server's auth middleware sees no
|
|
569
|
+
* session and redirects to the login page before the browser ever receives
|
|
570
|
+
* the Set-Cookie response.
|
|
571
|
+
*/
|
|
572
|
+
export function getRequestCookieInjection() {
|
|
573
|
+
const cookies = [];
|
|
574
|
+
if (sessionConfig?.cookieValue) {
|
|
575
|
+
cookies.push({ name: 'session-token', value: sessionConfig.cookieValue });
|
|
576
|
+
}
|
|
577
|
+
if (seedSessionCookies && seedSessionCookies.length > 0) {
|
|
578
|
+
for (const sc of seedSessionCookies) {
|
|
579
|
+
cookies.push({ name: sc.name, value: sc.value });
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return cookies.length > 0 ? cookies : null;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Inject session cookies into the request's Cookie header before forwarding
|
|
586
|
+
* to the dev server. This ensures the dev server sees auth cookies on the
|
|
587
|
+
* very first request after a scenario switch (before the browser has stored
|
|
588
|
+
* them from Set-Cookie responses).
|
|
589
|
+
*/
|
|
590
|
+
function injectRequestCookies(headers) {
|
|
591
|
+
const injection = getRequestCookieInjection();
|
|
592
|
+
if (!injection)
|
|
593
|
+
return;
|
|
594
|
+
// Parse existing cookies from the request
|
|
595
|
+
const existing = typeof headers.cookie === 'string' ? headers.cookie : '';
|
|
596
|
+
const existingPairs = existing
|
|
597
|
+
? existing.split(';').map((s) => s.trim())
|
|
598
|
+
: [];
|
|
599
|
+
// Build a map of existing cookies for deduplication
|
|
600
|
+
const cookieMap = new Map();
|
|
601
|
+
for (const pair of existingPairs) {
|
|
602
|
+
const eqIdx = pair.indexOf('=');
|
|
603
|
+
if (eqIdx !== -1) {
|
|
604
|
+
cookieMap.set(pair.slice(0, eqIdx), pair.slice(eqIdx + 1));
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
// Override with injected cookies
|
|
608
|
+
for (const { name, value } of injection) {
|
|
609
|
+
cookieMap.set(name, value);
|
|
610
|
+
}
|
|
611
|
+
// Reassemble
|
|
612
|
+
const parts = [];
|
|
613
|
+
for (const [k, v] of cookieMap) {
|
|
614
|
+
parts.push(`${k}=${v}`);
|
|
615
|
+
}
|
|
616
|
+
if (parts.length > 0) {
|
|
617
|
+
headers.cookie = parts.join('; ');
|
|
300
618
|
}
|
|
301
619
|
}
|
|
302
620
|
/**
|
|
@@ -305,6 +623,324 @@ function injectSessionCookie(headers) {
|
|
|
305
623
|
export function getSessionConfig() {
|
|
306
624
|
return sessionConfig;
|
|
307
625
|
}
|
|
626
|
+
/**
|
|
627
|
+
* Get the current localStorage config (for testing and script generation).
|
|
628
|
+
*/
|
|
629
|
+
export function getLocalStorageConfig() {
|
|
630
|
+
return localStorageConfig;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Get the active scenario ID (for testing and script generation).
|
|
634
|
+
*/
|
|
635
|
+
export function getActiveScenarioId() {
|
|
636
|
+
return activeScenarioId;
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Get the current prototype ID (for testing).
|
|
640
|
+
*/
|
|
641
|
+
export function getCurrentPrototypeId() {
|
|
642
|
+
return currentPrototypeId;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Simple djb2 hash — fast, deterministic, good enough for cache busting.
|
|
646
|
+
* Not cryptographic — just detects when localStorage config content changes.
|
|
647
|
+
*/
|
|
648
|
+
function simpleHash(str) {
|
|
649
|
+
let hash = 5381;
|
|
650
|
+
for (let i = 0; i < str.length; i++) {
|
|
651
|
+
hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;
|
|
652
|
+
}
|
|
653
|
+
return (hash >>> 0).toString(36);
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Build a script tag that seeds localStorage with scenario data on first load.
|
|
657
|
+
* Gated by scenario ID — only seeds when the scenario changes, preserving
|
|
658
|
+
* interactive modifications across page reloads / HMR.
|
|
659
|
+
*
|
|
660
|
+
* Returns empty string if no localStorage config is provided.
|
|
661
|
+
*/
|
|
662
|
+
export function buildLocalStorageScript(localStorageConfig, scenarioId, prototypeId) {
|
|
663
|
+
// null/undefined means no localStorage config at all — clean up keys
|
|
664
|
+
// that were set by a previous scenario so stale filter/sort state
|
|
665
|
+
// doesn't bleed through and hide data in the new scenario.
|
|
666
|
+
if (!localStorageConfig || typeof localStorageConfig !== 'object') {
|
|
667
|
+
// Always clean up previous scenario's keys, gated by scenarioId
|
|
668
|
+
// so it only runs once per switch (not on every HMR reload).
|
|
669
|
+
const guardValue = scenarioId ? `clear:${scenarioId}` : '';
|
|
670
|
+
if (prototypeId) {
|
|
671
|
+
return `<script data-codeyam-ls>
|
|
672
|
+
(function() {
|
|
673
|
+
if (localStorage.getItem('__codeyam_proto__') === ${JSON.stringify(prototypeId)}) return;
|
|
674
|
+
localStorage.clear();
|
|
675
|
+
localStorage.setItem('__codeyam_proto__', ${JSON.stringify(prototypeId)});
|
|
676
|
+
})();
|
|
677
|
+
</script>`;
|
|
678
|
+
}
|
|
679
|
+
if (scenarioId) {
|
|
680
|
+
// No prototypeId but we do have a scenarioId — clean up keys
|
|
681
|
+
// from the previous scenario without doing a full clear.
|
|
682
|
+
return `<script data-codeyam-ls>
|
|
683
|
+
(function() {
|
|
684
|
+
if (localStorage.getItem('__codeyam_ls_sid__') === ${JSON.stringify(guardValue)}) return;
|
|
685
|
+
var prev = JSON.parse(localStorage.getItem('__codeyam_ls_keys__') || '[]');
|
|
686
|
+
for (var i = 0; i < prev.length; i++) localStorage.removeItem(prev[i]);
|
|
687
|
+
localStorage.removeItem('__codeyam_ls_keys__');
|
|
688
|
+
localStorage.setItem('__codeyam_ls_sid__', ${JSON.stringify(guardValue)});
|
|
689
|
+
})();
|
|
690
|
+
</script>`;
|
|
691
|
+
}
|
|
692
|
+
return '';
|
|
693
|
+
}
|
|
694
|
+
// Even an empty object needs a cleanup script — switching from a scenario
|
|
695
|
+
// with localStorage data to one without must clear the previous keys.
|
|
696
|
+
const entries = Object.entries(localStorageConfig);
|
|
697
|
+
const keys = entries.map(([k]) => k);
|
|
698
|
+
// Build setItem calls — stringify non-string values
|
|
699
|
+
const setStatements = entries
|
|
700
|
+
.map(([key, value]) => {
|
|
701
|
+
const serialized = typeof value === 'string' ? value : JSON.stringify(value);
|
|
702
|
+
return `localStorage.setItem(${JSON.stringify(key)}, ${JSON.stringify(serialized)});`;
|
|
703
|
+
})
|
|
704
|
+
.join('\n');
|
|
705
|
+
// Guard value includes a content hash so re-registering a scenario with
|
|
706
|
+
// updated data (same ID, different content) busts the cache. Without this,
|
|
707
|
+
// the browser skips re-seeding because the scenario ID hasn't changed,
|
|
708
|
+
// causing stale data in the live preview while screenshots show fresh data.
|
|
709
|
+
const contentHash = simpleHash(JSON.stringify(localStorageConfig));
|
|
710
|
+
const guardValue = `${scenarioId}:${contentHash}`;
|
|
711
|
+
return (`<script data-codeyam-ls>
|
|
712
|
+
(function() {
|
|
713
|
+
if (localStorage.getItem('__codeyam_ls_sid__') === ${JSON.stringify(guardValue)}) return;
|
|
714
|
+
var prev = JSON.parse(localStorage.getItem('__codeyam_ls_keys__') || '[]');
|
|
715
|
+
for (var i = 0; i < prev.length; i++) localStorage.removeItem(prev[i]);
|
|
716
|
+
${setStatements}
|
|
717
|
+
localStorage.setItem('__codeyam_ls_keys__', ${JSON.stringify(JSON.stringify(keys))});
|
|
718
|
+
localStorage.setItem('__codeyam_ls_sid__', ${JSON.stringify(guardValue)});
|
|
719
|
+
})();
|
|
720
|
+
</script>` + buildLocalStorageWatcherScript());
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Build a script that watches for localStorage mutations and notifies the parent
|
|
724
|
+
* frame via postMessage. Also responds to `codeyam-get-localstorage` requests so
|
|
725
|
+
* the editor can read the current localStorage state when saving.
|
|
726
|
+
*/
|
|
727
|
+
function buildLocalStorageWatcherScript() {
|
|
728
|
+
return `<script data-codeyam-ls-watcher>
|
|
729
|
+
(function() {
|
|
730
|
+
if (window.__codeyam_ls_watcher_installed__) return;
|
|
731
|
+
window.__codeyam_ls_watcher_installed__ = true;
|
|
732
|
+
|
|
733
|
+
var origSet = localStorage.setItem.bind(localStorage);
|
|
734
|
+
var origRemove = localStorage.removeItem.bind(localStorage);
|
|
735
|
+
var origClear = localStorage.clear.bind(localStorage);
|
|
736
|
+
window.__codeyam_orig_setItem__ = origSet;
|
|
737
|
+
window.__codeyam_orig_removeItem__ = origRemove;
|
|
738
|
+
window.__codeyam_orig_clear__ = origClear;
|
|
739
|
+
|
|
740
|
+
function isInternal(key) {
|
|
741
|
+
return typeof key === 'string' && key.indexOf('__codeyam_') === 0;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
localStorage.setItem = function(key, value) {
|
|
745
|
+
origSet(key, value);
|
|
746
|
+
if (!isInternal(key) && window.parent !== window) {
|
|
747
|
+
window.parent.postMessage({ type: 'codeyam-localstorage-changed', action: 'set', key: key }, '*');
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
localStorage.removeItem = function(key) {
|
|
752
|
+
origRemove(key);
|
|
753
|
+
if (!isInternal(key) && window.parent !== window) {
|
|
754
|
+
window.parent.postMessage({ type: 'codeyam-localstorage-changed', action: 'remove', key: key }, '*');
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
localStorage.clear = function() {
|
|
759
|
+
origClear();
|
|
760
|
+
if (window.parent !== window) {
|
|
761
|
+
window.parent.postMessage({ type: 'codeyam-localstorage-changed', action: 'clear' }, '*');
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
window.addEventListener('message', function(event) {
|
|
766
|
+
if (event.data && event.data.type === 'codeyam-get-localstorage') {
|
|
767
|
+
var data = {};
|
|
768
|
+
for (var i = 0; i < localStorage.length; i++) {
|
|
769
|
+
var k = localStorage.key(i);
|
|
770
|
+
if (k && !isInternal(k)) {
|
|
771
|
+
data[k] = localStorage.getItem(k);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
event.source.postMessage({ type: 'codeyam-localstorage-state', data: data }, '*');
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
})();
|
|
778
|
+
</script>`;
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Inject the health-check script (and optional localStorage script) into an HTML response body.
|
|
782
|
+
* Inserts before </head> if present, otherwise before </body>, otherwise appends.
|
|
783
|
+
* When a localStorageScript is provided, it's injected BEFORE the health script
|
|
784
|
+
* so localStorage is populated before the app loads.
|
|
785
|
+
*/
|
|
786
|
+
export function injectHealthScript(html, localStorageScript) {
|
|
787
|
+
const scripts = (localStorageScript || '') + PREVIEW_HEALTH_SCRIPT;
|
|
788
|
+
if (html.includes('</head>')) {
|
|
789
|
+
return html.replace('</head>', scripts + '</head>');
|
|
790
|
+
}
|
|
791
|
+
if (html.includes('</body>')) {
|
|
792
|
+
return html.replace('</body>', scripts + '</body>');
|
|
793
|
+
}
|
|
794
|
+
return html + scripts;
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Escape HTML special characters to prevent XSS when embedding
|
|
798
|
+
* dev server error output into the error page.
|
|
799
|
+
*/
|
|
800
|
+
export function escapeHtml(str) {
|
|
801
|
+
return str
|
|
802
|
+
.replace(/&/g, '&')
|
|
803
|
+
.replace(/</g, '<')
|
|
804
|
+
.replace(/>/g, '>')
|
|
805
|
+
.replace(/"/g, '"')
|
|
806
|
+
.replace(/'/g, ''');
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Build a self-contained HTML error page for display in the preview iframe.
|
|
810
|
+
*
|
|
811
|
+
* - Sends `codeyam-server-error` postMessage to the parent editor on load
|
|
812
|
+
* so the editor can auto-restart the dev server.
|
|
813
|
+
* - Includes a "Retry" button that sends `codeyam-server-error-retry`.
|
|
814
|
+
* - Does NOT send `codeyam-preview-ready` (so the editor doesn't
|
|
815
|
+
* mistake the error page for a successful load).
|
|
816
|
+
*/
|
|
817
|
+
export function buildErrorPage(statusCode, title, detail) {
|
|
818
|
+
const escapedDetail = escapeHtml(detail);
|
|
819
|
+
const escapedTitle = escapeHtml(title);
|
|
820
|
+
return `<!DOCTYPE html>
|
|
821
|
+
<html lang="en">
|
|
822
|
+
<head>
|
|
823
|
+
<meta charset="utf-8" />
|
|
824
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
825
|
+
<title>${escapedTitle}</title>
|
|
826
|
+
<style>
|
|
827
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
828
|
+
body {
|
|
829
|
+
background: #1e1e1e;
|
|
830
|
+
color: #e0e0e0;
|
|
831
|
+
font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, sans-serif;
|
|
832
|
+
display: flex;
|
|
833
|
+
align-items: center;
|
|
834
|
+
justify-content: center;
|
|
835
|
+
min-height: 100vh;
|
|
836
|
+
padding: 24px;
|
|
837
|
+
}
|
|
838
|
+
.container {
|
|
839
|
+
max-width: 560px;
|
|
840
|
+
width: 100%;
|
|
841
|
+
text-align: center;
|
|
842
|
+
}
|
|
843
|
+
.status-code {
|
|
844
|
+
font-size: 48px;
|
|
845
|
+
font-weight: 600;
|
|
846
|
+
color: #f87171;
|
|
847
|
+
line-height: 1;
|
|
848
|
+
margin-bottom: 8px;
|
|
849
|
+
}
|
|
850
|
+
.title {
|
|
851
|
+
font-size: 18px;
|
|
852
|
+
font-weight: 500;
|
|
853
|
+
color: #f87171;
|
|
854
|
+
margin-bottom: 16px;
|
|
855
|
+
}
|
|
856
|
+
.detail {
|
|
857
|
+
background: #2a2a2a;
|
|
858
|
+
border: 1px solid #3a3a3a;
|
|
859
|
+
border-radius: 6px;
|
|
860
|
+
padding: 16px;
|
|
861
|
+
margin-bottom: 20px;
|
|
862
|
+
max-height: 240px;
|
|
863
|
+
overflow: auto;
|
|
864
|
+
text-align: left;
|
|
865
|
+
}
|
|
866
|
+
.detail pre {
|
|
867
|
+
font-family: 'IBM Plex Mono', monospace;
|
|
868
|
+
font-size: 12px;
|
|
869
|
+
color: #b0b0b0;
|
|
870
|
+
white-space: pre-wrap;
|
|
871
|
+
word-break: break-word;
|
|
872
|
+
}
|
|
873
|
+
.message {
|
|
874
|
+
font-size: 13px;
|
|
875
|
+
color: #888;
|
|
876
|
+
margin-bottom: 16px;
|
|
877
|
+
}
|
|
878
|
+
button {
|
|
879
|
+
background: #005c75;
|
|
880
|
+
color: white;
|
|
881
|
+
border: none;
|
|
882
|
+
border-radius: 4px;
|
|
883
|
+
padding: 8px 20px;
|
|
884
|
+
font-size: 14px;
|
|
885
|
+
font-weight: 500;
|
|
886
|
+
cursor: pointer;
|
|
887
|
+
transition: background 0.15s;
|
|
888
|
+
}
|
|
889
|
+
button:hover { background: #004d63; }
|
|
890
|
+
</style>
|
|
891
|
+
</head>
|
|
892
|
+
<body>
|
|
893
|
+
<div class="container">
|
|
894
|
+
<div class="status-code">${statusCode}</div>
|
|
895
|
+
<div class="title">${escapedTitle}</div>
|
|
896
|
+
<div class="detail"><pre>${escapedDetail}</pre></div>
|
|
897
|
+
<p class="message">Attempting to restart the dev server...</p>
|
|
898
|
+
<button onclick="window.parent.postMessage({type:'codeyam-server-error-retry'},'*')">Retry</button>
|
|
899
|
+
</div>
|
|
900
|
+
<script>
|
|
901
|
+
try { window.parent.postMessage({type:'codeyam-server-error',statusCode:${statusCode}},'*'); } catch(e) {}
|
|
902
|
+
</script>
|
|
903
|
+
</body>
|
|
904
|
+
</html>`;
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Handle POST /__codeyam__/preview-health — store health data in globalThis.
|
|
908
|
+
*/
|
|
909
|
+
function handlePreviewHealthPost(req, res) {
|
|
910
|
+
const chunks = [];
|
|
911
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
912
|
+
req.on('end', () => {
|
|
913
|
+
try {
|
|
914
|
+
const body = JSON.parse(Buffer.concat(chunks).toString('utf-8'));
|
|
915
|
+
const current = getPreviewHealth() || {
|
|
916
|
+
errors: [],
|
|
917
|
+
loaded: false,
|
|
918
|
+
hasContent: false,
|
|
919
|
+
url: '',
|
|
920
|
+
lastUpdated: 0,
|
|
921
|
+
};
|
|
922
|
+
if (body.errors && Array.isArray(body.errors)) {
|
|
923
|
+
current.errors = current.errors.concat(body.errors);
|
|
924
|
+
}
|
|
925
|
+
if (body.loaded !== undefined) {
|
|
926
|
+
current.loaded = body.loaded;
|
|
927
|
+
}
|
|
928
|
+
if (body.hasContent !== undefined) {
|
|
929
|
+
current.hasContent = body.hasContent;
|
|
930
|
+
}
|
|
931
|
+
if (body.url) {
|
|
932
|
+
current.url = body.url;
|
|
933
|
+
}
|
|
934
|
+
current.lastUpdated = Date.now();
|
|
935
|
+
setPreviewHealth(current);
|
|
936
|
+
}
|
|
937
|
+
catch {
|
|
938
|
+
// Ignore malformed JSON
|
|
939
|
+
}
|
|
940
|
+
res.writeHead(204);
|
|
941
|
+
res.end();
|
|
942
|
+
});
|
|
943
|
+
}
|
|
308
944
|
/**
|
|
309
945
|
* Handle WebSocket upgrade by piping to the target dev server.
|
|
310
946
|
*/
|
|
@@ -375,7 +1011,13 @@ function removeProxyConfig() {
|
|
|
375
1011
|
* Supports all HTTP methods (GET, POST, PUT, DELETE, PATCH) with body buffering.
|
|
376
1012
|
*/
|
|
377
1013
|
export async function startEditorProxy(options) {
|
|
378
|
-
//
|
|
1014
|
+
// If proxy is already running, reuse it (prevents second tab from killing first tab's proxy)
|
|
1015
|
+
const existing = getProxyState();
|
|
1016
|
+
if (existing) {
|
|
1017
|
+
console.log(`[editorProxy] Proxy already running on port ${existing.port} → ${existing.targetUrl}`);
|
|
1018
|
+
return { port: existing.port };
|
|
1019
|
+
}
|
|
1020
|
+
// Stop any leftover state (shouldn't happen, but defensive)
|
|
379
1021
|
await stopEditorProxy();
|
|
380
1022
|
let targetUrl = normalizeTargetUrl(options.targetUrl);
|
|
381
1023
|
let port = options.port;
|
|
@@ -415,6 +1057,11 @@ export async function startEditorProxy(options) {
|
|
|
415
1057
|
res.end();
|
|
416
1058
|
return;
|
|
417
1059
|
}
|
|
1060
|
+
// Intercept preview health reports from the injected script
|
|
1061
|
+
if (method === 'POST' && pathname === '/__codeyam__/preview-health') {
|
|
1062
|
+
handlePreviewHealthPost(req, res);
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
418
1065
|
// Load scenario data (also feeds MockStateManager)
|
|
419
1066
|
readScenarioData();
|
|
420
1067
|
// For methods that may carry a body, buffer it first
|
|
@@ -446,11 +1093,17 @@ export async function startEditorProxy(options) {
|
|
|
446
1093
|
'Content-Type': 'application/json',
|
|
447
1094
|
'Access-Control-Allow-Origin': '*',
|
|
448
1095
|
'X-CodeYam-Proxy': 'scenario-data',
|
|
1096
|
+
'Cache-Control': 'no-store',
|
|
449
1097
|
});
|
|
450
1098
|
res.end(match.body != null ? JSON.stringify(match.body) : '');
|
|
451
1099
|
return;
|
|
452
1100
|
}
|
|
453
1101
|
// No mock match — forward with buffered body
|
|
1102
|
+
if ((currentScenarioType === 'application' ||
|
|
1103
|
+
currentScenarioType === 'user') &&
|
|
1104
|
+
pathname.startsWith('/api/')) {
|
|
1105
|
+
mockStateEventEmitter.emitDataMutationForwarded(method, pathname);
|
|
1106
|
+
}
|
|
454
1107
|
forwardBufferedRequest(req, res, targetUrl, bodyBuffer);
|
|
455
1108
|
return;
|
|
456
1109
|
}
|
|
@@ -462,6 +1115,7 @@ export async function startEditorProxy(options) {
|
|
|
462
1115
|
'Content-Type': 'application/json',
|
|
463
1116
|
'Access-Control-Allow-Origin': '*',
|
|
464
1117
|
'X-CodeYam-Proxy': 'scenario-data',
|
|
1118
|
+
'Cache-Control': 'no-store',
|
|
465
1119
|
});
|
|
466
1120
|
res.end(match.body != null ? JSON.stringify(match.body) : '');
|
|
467
1121
|
return;
|
|
@@ -533,6 +1187,10 @@ export async function stopEditorProxy() {
|
|
|
533
1187
|
export function invalidateScenarioCache() {
|
|
534
1188
|
scenarioCache = { data: null, timestamp: 0 };
|
|
535
1189
|
sessionConfig = undefined;
|
|
1190
|
+
seedSessionCookies = undefined;
|
|
1191
|
+
localStorageConfig = null;
|
|
1192
|
+
activeScenarioId = null;
|
|
1193
|
+
currentPrototypeId = null;
|
|
536
1194
|
}
|
|
537
1195
|
/**
|
|
538
1196
|
* Verify that the proxy can successfully forward a request to the target dev server.
|