@codeyam/codeyam-cli 0.1.0-staging.dbc742d → 0.1.0-staging.df25827
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 +77 -6
- 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/kysely/tables/editorScenariosTable.d.ts +5 -1
- 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 +79 -6
- 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/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 +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 +39 -3
- package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js.map +1 -1
- package/codeyam-cli/src/commands/editor.js +3819 -624
- 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 +22 -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__/analyzerFinalization.test.js +173 -0
- package/codeyam-cli/src/utils/__tests__/analyzerFinalization.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__/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 +75 -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 +73 -1
- 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 +936 -9
- 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 +390 -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 +57 -0
- package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js +373 -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__/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 +11 -1
- 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 +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 +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/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 +40 -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 +375 -16
- 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 +50 -5
- 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 +12 -10
- package/codeyam-cli/src/utils/scenarioCoverage.js.map +1 -1
- package/codeyam-cli/src/utils/scenariosManifest.js +154 -0
- 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/setupClaudeCodeSettings.js +1 -0
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
- 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 +153 -0
- package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js.map +1 -0
- 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 +454 -4
- 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 +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/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-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-b0d69c06.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{memory-9gnxSZlb.js → memory-CEWIUC4t.js} +2 -2
- 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-CLedrjXQ.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-DPUEhrWo.js +16 -0
- package/codeyam-cli/src/webserver/build/server/assets/{index-BWoRb5RY.js → index-oF2amaGI.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/init-C42BvUGp.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-DiCdDL5d.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 +443 -35
- 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 +369 -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/codeyam-editor-claude.md +3 -1
- 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/__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 +88 -40
- package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +1 -1
- package/codeyam-cli/templates/seed-adapters/supabase.ts +475 -0
- package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +106 -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 +79 -6
- 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/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/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-BBAGP_mE.js +0 -10
- package/codeyam-cli/src/webserver/build/client/assets/editorPreview-BLQMSKZa.js +0 -41
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-C7YX6r3H.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-COUSHTyZ.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-9c70d1f3.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-CHOdrM6Y.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/init-DbChSUQP.js +0 -10
- package/codeyam-cli/src/webserver/build/server/assets/server-build-BtbLQkKd.js +0 -433
- 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 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{aG as Z,aH as _,aw as $,ax as rr,aE as tr,ay as or,aA as ir,aB as pr,aD as mr,aC as ar,aF as sr,az as er}from"./assets/server-build-DiCdDL5d.js";import"react/jsx-runtime";import"node:stream";import"@react-router/node";import"react-router";import"isbot";import"react-dom/server";import"react";import"lucide-react";import"fetch-retry";import"better-sqlite3";import"pg";import"fs";import"path";import"kysely";import"kysely/helpers/sqlite";import"kysely/helpers/postgres";import"typescript";import"fs/promises";import"os";import"prompts";import"chalk";import"crypto";import"child_process";import"url";import"util";import"dotenv";import"events";import"uuid";import"http";import"net";import"ws";import"node-pty";import"openai";import"p-queue";import"p-retry";import"@aws-sdk/client-dynamodb";import"lru-cache";import"pluralize";import"piscina";import"json5";import"@aws-sdk/util-dynamodb";import"v8";import"react-syntax-highlighter";import"react-syntax-highlighter/dist/cjs/styles/prism/index.js";import"node:crypto";import"minimatch";import"react-markdown";import"remark-gfm";import"react-diff-viewer-continued";export{Z as allowedActionOrigins,_ as assets,$ as assetsBuildDirectory,rr as basename,tr as entry,or as future,ir as isSpaMode,pr as prerender,mr as publicPath,ar as routeDiscovery,sr as routes,er as ssr};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"buildTimestamp": "2026-
|
|
3
|
-
"buildTime":
|
|
4
|
-
"buildNumber":
|
|
5
|
-
"semanticVersion": "0.1.
|
|
6
|
-
"version": "0.1.
|
|
2
|
+
"buildTimestamp": "2026-04-13T12:41:18.891Z",
|
|
3
|
+
"buildTime": 1776084078891,
|
|
4
|
+
"buildNumber": 1376,
|
|
5
|
+
"semanticVersion": "0.1.1376",
|
|
6
|
+
"version": "0.1.1376 (2026-04-13T12:41)"
|
|
7
7
|
}
|
|
@@ -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
|
*
|
|
@@ -130,16 +131,58 @@ export const PREVIEW_HEALTH_SCRIPT = `<script data-codeyam-health>
|
|
|
130
131
|
}).catch(function(){});
|
|
131
132
|
}, 1000);
|
|
132
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
|
+
});
|
|
133
170
|
})();
|
|
134
171
|
</script>`;
|
|
135
172
|
const CACHE_TTL_MS = 500;
|
|
136
173
|
let scenarioCache = { data: null, timestamp: 0 };
|
|
137
174
|
// Session config extracted from the active scenario — drives cookie injection
|
|
138
175
|
let sessionConfig = undefined;
|
|
176
|
+
/** Session cookies from the seed adapter (e.g. Supabase auth tokens). */
|
|
177
|
+
let seedSessionCookies = undefined;
|
|
139
178
|
// localStorage config extracted from the active scenario — drives HTML injection
|
|
140
179
|
let localStorageConfig = null;
|
|
141
180
|
// Active scenario ID — used to gate localStorage seeding (only re-seed on switch)
|
|
142
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;
|
|
143
186
|
// Max body size to buffer for mock matching (10MB)
|
|
144
187
|
const MAX_BODY_SIZE = 10 * 1024 * 1024;
|
|
145
188
|
function getProxyState() {
|
|
@@ -193,6 +236,8 @@ function readScenarioData() {
|
|
|
193
236
|
const active = JSON.parse(fs.readFileSync(activeScenarioPath, 'utf-8'));
|
|
194
237
|
const scenarioId = active.scenarioId;
|
|
195
238
|
if (!scenarioId) {
|
|
239
|
+
// No active scenario — but may have a prototypeId for localStorage clearing
|
|
240
|
+
currentPrototypeId = active.prototypeId || null;
|
|
196
241
|
scenarioCache = { data: null, timestamp: now };
|
|
197
242
|
return null;
|
|
198
243
|
}
|
|
@@ -205,11 +250,14 @@ function readScenarioData() {
|
|
|
205
250
|
const rawData = JSON.parse(fs.readFileSync(dataFilePath, 'utf-8'));
|
|
206
251
|
// Extract session config for cookie injection
|
|
207
252
|
sessionConfig = rawData.session || null;
|
|
253
|
+
// Extract seed adapter session cookies (e.g. Supabase auth)
|
|
254
|
+
seedSessionCookies = rawData.sessionCookies || undefined;
|
|
208
255
|
// Extract localStorage config for HTML injection
|
|
209
256
|
localStorageConfig = rawData.localStorage || null;
|
|
210
257
|
activeScenarioId = scenarioId;
|
|
211
258
|
// Type-aware: for seed-based scenarios, only serve externalApis via proxy
|
|
212
259
|
const scenarioType = active.type || rawData.type || null;
|
|
260
|
+
currentScenarioType = scenarioType;
|
|
213
261
|
let mockData;
|
|
214
262
|
if ((scenarioType === 'application' || scenarioType === 'user') &&
|
|
215
263
|
rawData.seed) {
|
|
@@ -286,6 +334,10 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
|
|
|
286
334
|
// Remove accept-encoding so the dev server returns uncompressed responses.
|
|
287
335
|
// The proxy injects a health script into HTML — this fails on compressed bodies.
|
|
288
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);
|
|
289
341
|
// Update content-length if we have the body buffer
|
|
290
342
|
if (bodyBuffer) {
|
|
291
343
|
headers['content-length'] = String(bodyBuffer.length);
|
|
@@ -299,6 +351,9 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
|
|
|
299
351
|
};
|
|
300
352
|
const proxyReq = http.request(options, (proxyRes) => {
|
|
301
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
|
+
}
|
|
302
357
|
if (status >= 400) {
|
|
303
358
|
console.warn(`[editorProxy] Target returned ${status} for ${req.method} ${req.url}`);
|
|
304
359
|
}
|
|
@@ -312,27 +367,54 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
|
|
|
312
367
|
proxyRes.on('data', (chunk) => chunks.push(chunk));
|
|
313
368
|
proxyRes.on('end', () => {
|
|
314
369
|
const body = Buffer.concat(chunks).toString('utf-8');
|
|
315
|
-
const lsScript = buildLocalStorageScript(localStorageConfig, activeScenarioId || '');
|
|
316
|
-
const injected = injectHealthScript(body, lsScript);
|
|
317
370
|
delete headers['content-length'];
|
|
318
371
|
delete headers['content-encoding'];
|
|
319
|
-
// Prevent browser from caching HTML responses — scenario switches
|
|
320
|
-
// serve different content from the same URL (seed data changes the
|
|
321
|
-
// rendered page but the proxy URL stays the same).
|
|
322
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);
|
|
323
383
|
res.writeHead(status, headers);
|
|
324
384
|
res.end(injected);
|
|
325
385
|
});
|
|
326
386
|
return;
|
|
327
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
|
+
}
|
|
328
406
|
res.writeHead(status, headers);
|
|
329
407
|
proxyRes.pipe(res, { end: true });
|
|
330
408
|
});
|
|
331
409
|
proxyReq.on('error', (err) => {
|
|
332
410
|
console.warn(`[editorProxy] Forward error for ${req.method} ${req.url}: ${err.message}`);
|
|
333
411
|
if (!res.headersSent) {
|
|
334
|
-
|
|
335
|
-
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);
|
|
336
418
|
}
|
|
337
419
|
});
|
|
338
420
|
if (bodyBuffer && bodyBuffer.length > 0) {
|
|
@@ -353,18 +435,25 @@ function forwardRequest(req, res, targetUrl) {
|
|
|
353
435
|
// Build headers, stripping accept-encoding so the dev server returns uncompressed
|
|
354
436
|
// responses. The proxy injects a health script into HTML — this fails on compressed bodies.
|
|
355
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);
|
|
356
445
|
const options = {
|
|
357
446
|
hostname,
|
|
358
447
|
port: target.port,
|
|
359
448
|
path: req.url,
|
|
360
449
|
method: req.method,
|
|
361
|
-
headers:
|
|
362
|
-
...forwardHeaders,
|
|
363
|
-
host: `${target.hostname}:${target.port}`,
|
|
364
|
-
},
|
|
450
|
+
headers: reqHeaders,
|
|
365
451
|
};
|
|
366
452
|
const proxyReq = http.request(options, (proxyRes) => {
|
|
367
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
|
+
}
|
|
368
457
|
if (status >= 400) {
|
|
369
458
|
console.warn(`[editorProxy] Target returned ${status} for ${req.method} ${req.url}`);
|
|
370
459
|
}
|
|
@@ -379,29 +468,54 @@ function forwardRequest(req, res, targetUrl) {
|
|
|
379
468
|
proxyRes.on('data', (chunk) => chunks.push(chunk));
|
|
380
469
|
proxyRes.on('end', () => {
|
|
381
470
|
const body = Buffer.concat(chunks).toString('utf-8');
|
|
382
|
-
const lsScript = buildLocalStorageScript(localStorageConfig, activeScenarioId || '');
|
|
383
|
-
const injected = injectHealthScript(body, lsScript);
|
|
384
|
-
// Remove content-length since body size changed; use chunked transfer
|
|
385
471
|
delete headers['content-length'];
|
|
386
|
-
// Remove content-encoding since we're serving uncompressed
|
|
387
472
|
delete headers['content-encoding'];
|
|
388
|
-
// Prevent browser from caching HTML responses — scenario switches
|
|
389
|
-
// serve different content from the same URL (seed data changes the
|
|
390
|
-
// rendered page but the proxy URL stays the same).
|
|
391
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);
|
|
392
484
|
res.writeHead(status, headers);
|
|
393
485
|
res.end(injected);
|
|
394
486
|
});
|
|
395
487
|
return;
|
|
396
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
|
+
}
|
|
397
507
|
res.writeHead(status, headers);
|
|
398
508
|
proxyRes.pipe(res, { end: true });
|
|
399
509
|
});
|
|
400
510
|
proxyReq.on('error', (err) => {
|
|
401
511
|
console.warn(`[editorProxy] Forward error for ${req.method} ${req.url}: ${err.message}`);
|
|
402
512
|
if (!res.headersSent) {
|
|
403
|
-
|
|
404
|
-
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);
|
|
405
519
|
}
|
|
406
520
|
});
|
|
407
521
|
req.pipe(proxyReq, { end: true });
|
|
@@ -413,25 +527,94 @@ function forwardRequest(req, res, targetUrl) {
|
|
|
413
527
|
* When sessionConfig is undefined (no scenario loaded yet), does nothing.
|
|
414
528
|
*/
|
|
415
529
|
function injectSessionCookie(headers) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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
|
+
}
|
|
421
539
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
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
|
+
}
|
|
425
547
|
}
|
|
548
|
+
if (cookies.length === 0)
|
|
549
|
+
return;
|
|
426
550
|
const existing = headers['set-cookie'];
|
|
427
551
|
if (existing) {
|
|
428
552
|
headers['set-cookie'] = [
|
|
429
553
|
...(Array.isArray(existing) ? existing : [existing]),
|
|
430
|
-
|
|
554
|
+
...cookies,
|
|
431
555
|
];
|
|
432
556
|
}
|
|
433
557
|
else {
|
|
434
|
-
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('; ');
|
|
435
618
|
}
|
|
436
619
|
}
|
|
437
620
|
/**
|
|
@@ -452,6 +635,23 @@ export function getLocalStorageConfig() {
|
|
|
452
635
|
export function getActiveScenarioId() {
|
|
453
636
|
return activeScenarioId;
|
|
454
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
|
+
}
|
|
455
655
|
/**
|
|
456
656
|
* Build a script tag that seeds localStorage with scenario data on first load.
|
|
457
657
|
* Gated by scenario ID — only seeds when the scenario changes, preserving
|
|
@@ -459,9 +659,36 @@ export function getActiveScenarioId() {
|
|
|
459
659
|
*
|
|
460
660
|
* Returns empty string if no localStorage config is provided.
|
|
461
661
|
*/
|
|
462
|
-
export function buildLocalStorageScript(localStorageConfig, scenarioId) {
|
|
463
|
-
// null/undefined means no localStorage config at all —
|
|
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.
|
|
464
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
|
+
}
|
|
465
692
|
return '';
|
|
466
693
|
}
|
|
467
694
|
// Even an empty object needs a cleanup script — switching from a scenario
|
|
@@ -475,14 +702,78 @@ export function buildLocalStorageScript(localStorageConfig, scenarioId) {
|
|
|
475
702
|
return `localStorage.setItem(${JSON.stringify(key)}, ${JSON.stringify(serialized)});`;
|
|
476
703
|
})
|
|
477
704
|
.join('\n');
|
|
478
|
-
|
|
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>
|
|
479
712
|
(function() {
|
|
480
|
-
if (localStorage.getItem('__codeyam_ls_sid__') === ${JSON.stringify(
|
|
713
|
+
if (localStorage.getItem('__codeyam_ls_sid__') === ${JSON.stringify(guardValue)}) return;
|
|
481
714
|
var prev = JSON.parse(localStorage.getItem('__codeyam_ls_keys__') || '[]');
|
|
482
715
|
for (var i = 0; i < prev.length; i++) localStorage.removeItem(prev[i]);
|
|
483
716
|
${setStatements}
|
|
484
717
|
localStorage.setItem('__codeyam_ls_keys__', ${JSON.stringify(JSON.stringify(keys))});
|
|
485
|
-
localStorage.setItem('__codeyam_ls_sid__', ${JSON.stringify(
|
|
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
|
+
});
|
|
486
777
|
})();
|
|
487
778
|
</script>`;
|
|
488
779
|
}
|
|
@@ -502,6 +793,116 @@ export function injectHealthScript(html, localStorageScript) {
|
|
|
502
793
|
}
|
|
503
794
|
return html + scripts;
|
|
504
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
|
+
}
|
|
505
906
|
/**
|
|
506
907
|
* Handle POST /__codeyam__/preview-health — store health data in globalThis.
|
|
507
908
|
*/
|
|
@@ -698,6 +1099,11 @@ export async function startEditorProxy(options) {
|
|
|
698
1099
|
return;
|
|
699
1100
|
}
|
|
700
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
|
+
}
|
|
701
1107
|
forwardBufferedRequest(req, res, targetUrl, bodyBuffer);
|
|
702
1108
|
return;
|
|
703
1109
|
}
|
|
@@ -781,8 +1187,10 @@ export async function stopEditorProxy() {
|
|
|
781
1187
|
export function invalidateScenarioCache() {
|
|
782
1188
|
scenarioCache = { data: null, timestamp: 0 };
|
|
783
1189
|
sessionConfig = undefined;
|
|
1190
|
+
seedSessionCookies = undefined;
|
|
784
1191
|
localStorageConfig = null;
|
|
785
1192
|
activeScenarioId = null;
|
|
1193
|
+
currentPrototypeId = null;
|
|
786
1194
|
}
|
|
787
1195
|
/**
|
|
788
1196
|
* Verify that the proxy can successfully forward a request to the target dev server.
|