hammoc 1.5.0 → 1.7.0
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/README.md +12 -4
- package/package.json +2 -2
- package/packages/client/dist/assets/{agentExampleHighlight-BgwTm15v.js → agentExampleHighlight-7Olvqdpf.js} +1 -1
- package/packages/client/dist/assets/{commandTokenHighlight-BljHwnrK.js → commandTokenHighlight-DtKwh4lx.js} +1 -1
- package/packages/client/dist/assets/index-B09doO8H.js +139 -0
- package/packages/client/dist/assets/index-Bee52CKG.js +1569 -0
- package/packages/client/dist/assets/index-CVy582lU.css +32 -0
- package/packages/client/dist/assets/{index-D3LxqW3f.js → index-DLHBUw8c.js} +1 -1
- package/packages/client/dist/assets/{snippetTokenHighlight-DWsaQXX0.js → snippetTokenHighlight-C8O688f4.js} +1 -1
- package/packages/client/dist/index.html +2 -2
- package/packages/client/dist/sw.js +2 -2
- package/packages/server/dist/_dbg_agent_rows.d.ts +2 -0
- package/packages/server/dist/_dbg_agent_rows.d.ts.map +1 -0
- package/packages/server/dist/_dbg_agent_rows.js +60 -0
- package/packages/server/dist/_dbg_agent_rows.js.map +1 -0
- package/packages/server/dist/_dbg_flicker.d.ts +2 -0
- package/packages/server/dist/_dbg_flicker.d.ts.map +1 -0
- package/packages/server/dist/_dbg_flicker.js +38 -0
- package/packages/server/dist/_dbg_flicker.js.map +1 -0
- package/packages/server/dist/_harness_cli.d.ts +2 -0
- package/packages/server/dist/_harness_cli.d.ts.map +1 -0
- package/packages/server/dist/_harness_cli.js +81 -0
- package/packages/server/dist/_harness_cli.js.map +1 -0
- package/packages/server/dist/_harness_provcard.d.ts +2 -0
- package/packages/server/dist/_harness_provcard.d.ts.map +1 -0
- package/packages/server/dist/_harness_provcard.js +67 -0
- package/packages/server/dist/_harness_provcard.js.map +1 -0
- package/packages/server/dist/_replay_dump.d.ts +2 -0
- package/packages/server/dist/_replay_dump.d.ts.map +1 -0
- package/packages/server/dist/_replay_dump.js +62 -0
- package/packages/server/dist/_replay_dump.js.map +1 -0
- package/packages/server/dist/app.d.ts.map +1 -1
- package/packages/server/dist/app.js +6 -0
- package/packages/server/dist/app.js.map +1 -1
- package/packages/server/dist/config/index.d.ts.map +1 -1
- package/packages/server/dist/config/index.js.map +1 -1
- package/packages/server/dist/controllers/bmadCoreConfigController.d.ts +41 -0
- package/packages/server/dist/controllers/bmadCoreConfigController.d.ts.map +1 -0
- package/packages/server/dist/controllers/bmadCoreConfigController.js +172 -0
- package/packages/server/dist/controllers/bmadCoreConfigController.js.map +1 -0
- package/packages/server/dist/controllers/contextBuilderController.d.ts +43 -0
- package/packages/server/dist/controllers/contextBuilderController.d.ts.map +1 -0
- package/packages/server/dist/controllers/contextBuilderController.js +159 -0
- package/packages/server/dist/controllers/contextBuilderController.js.map +1 -0
- package/packages/server/dist/controllers/harnessAgentController.d.ts +7 -0
- package/packages/server/dist/controllers/harnessAgentController.d.ts.map +1 -1
- package/packages/server/dist/controllers/harnessAgentController.js +33 -0
- package/packages/server/dist/controllers/harnessAgentController.js.map +1 -1
- package/packages/server/dist/controllers/harnessBundleController.d.ts +37 -0
- package/packages/server/dist/controllers/harnessBundleController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessBundleController.js +312 -0
- package/packages/server/dist/controllers/harnessBundleController.js.map +1 -0
- package/packages/server/dist/controllers/harnessCommandController.d.ts +7 -0
- package/packages/server/dist/controllers/harnessCommandController.d.ts.map +1 -1
- package/packages/server/dist/controllers/harnessCommandController.js +33 -0
- package/packages/server/dist/controllers/harnessCommandController.js.map +1 -1
- package/packages/server/dist/controllers/harnessHookController.d.ts.map +1 -1
- package/packages/server/dist/controllers/harnessHookController.js +44 -1
- package/packages/server/dist/controllers/harnessHookController.js.map +1 -1
- package/packages/server/dist/controllers/harnessMcpController.d.ts.map +1 -1
- package/packages/server/dist/controllers/harnessMcpController.js +62 -1
- package/packages/server/dist/controllers/harnessMcpController.js.map +1 -1
- package/packages/server/dist/controllers/harnessShareScopeController.d.ts +9 -0
- package/packages/server/dist/controllers/harnessShareScopeController.d.ts.map +1 -1
- package/packages/server/dist/controllers/harnessShareScopeController.js +48 -1
- package/packages/server/dist/controllers/harnessShareScopeController.js.map +1 -1
- package/packages/server/dist/controllers/marketplaceController.d.ts +19 -0
- package/packages/server/dist/controllers/marketplaceController.d.ts.map +1 -0
- package/packages/server/dist/controllers/marketplaceController.js +74 -0
- package/packages/server/dist/controllers/marketplaceController.js.map +1 -0
- package/packages/server/dist/controllers/observabilityController.d.ts +32 -0
- package/packages/server/dist/controllers/observabilityController.d.ts.map +1 -0
- package/packages/server/dist/controllers/observabilityController.js +148 -0
- package/packages/server/dist/controllers/observabilityController.js.map +1 -0
- package/packages/server/dist/controllers/projectController.d.ts.map +1 -1
- package/packages/server/dist/controllers/projectController.js +7 -1
- package/packages/server/dist/controllers/projectController.js.map +1 -1
- package/packages/server/dist/controllers/sessionController.d.ts.map +1 -1
- package/packages/server/dist/controllers/sessionController.js +16 -4
- package/packages/server/dist/controllers/sessionController.js.map +1 -1
- package/packages/server/dist/controllers/systemBrowseController.d.ts +33 -0
- package/packages/server/dist/controllers/systemBrowseController.d.ts.map +1 -0
- package/packages/server/dist/controllers/systemBrowseController.js +105 -0
- package/packages/server/dist/controllers/systemBrowseController.js.map +1 -0
- package/packages/server/dist/handlers/streamCallbacks.d.ts +10 -0
- package/packages/server/dist/handlers/streamCallbacks.d.ts.map +1 -1
- package/packages/server/dist/handlers/streamCallbacks.js +25 -4
- package/packages/server/dist/handlers/streamCallbacks.js.map +1 -1
- package/packages/server/dist/handlers/websocket.d.ts +43 -3
- package/packages/server/dist/handlers/websocket.d.ts.map +1 -1
- package/packages/server/dist/handlers/websocket.js +385 -93
- package/packages/server/dist/handlers/websocket.js.map +1 -1
- package/packages/server/dist/index.js +2 -0
- package/packages/server/dist/index.js.map +1 -1
- package/packages/server/dist/locales/en/server.json +17 -0
- package/packages/server/dist/locales/es/server.json +17 -0
- package/packages/server/dist/locales/ja/server.json +17 -0
- package/packages/server/dist/locales/ko/server.json +17 -0
- package/packages/server/dist/locales/pt/server.json +17 -0
- package/packages/server/dist/locales/zh-CN/server.json +17 -0
- package/packages/server/dist/routes/harness.d.ts.map +1 -1
- package/packages/server/dist/routes/harness.js +58 -0
- package/packages/server/dist/routes/harness.js.map +1 -1
- package/packages/server/dist/routes/preferences.d.ts.map +1 -1
- package/packages/server/dist/routes/preferences.js +12 -2
- package/packages/server/dist/routes/preferences.js.map +1 -1
- package/packages/server/dist/routes/systemBrowse.d.ts +17 -0
- package/packages/server/dist/routes/systemBrowse.d.ts.map +1 -0
- package/packages/server/dist/routes/systemBrowse.js +22 -0
- package/packages/server/dist/routes/systemBrowse.js.map +1 -0
- package/packages/server/dist/services/bmadCoreConfigService.d.ts +86 -0
- package/packages/server/dist/services/bmadCoreConfigService.d.ts.map +1 -0
- package/packages/server/dist/services/bmadCoreConfigService.js +175 -0
- package/packages/server/dist/services/bmadCoreConfigService.js.map +1 -0
- package/packages/server/dist/services/bmadStatusService.d.ts +9 -0
- package/packages/server/dist/services/bmadStatusService.d.ts.map +1 -1
- package/packages/server/dist/services/bmadStatusService.js +77 -13
- package/packages/server/dist/services/bmadStatusService.js.map +1 -1
- package/packages/server/dist/services/chatEngine.d.ts +81 -0
- package/packages/server/dist/services/chatEngine.d.ts.map +1 -0
- package/packages/server/dist/services/chatEngine.js +2 -0
- package/packages/server/dist/services/chatEngine.js.map +1 -0
- package/packages/server/dist/services/chatEngineFactory.d.ts +15 -0
- package/packages/server/dist/services/chatEngineFactory.d.ts.map +1 -0
- package/packages/server/dist/services/chatEngineFactory.js +28 -0
- package/packages/server/dist/services/chatEngineFactory.js.map +1 -0
- package/packages/server/dist/services/chatService.d.ts +34 -26
- package/packages/server/dist/services/chatService.d.ts.map +1 -1
- package/packages/server/dist/services/chatService.js +44 -104
- package/packages/server/dist/services/chatService.js.map +1 -1
- package/packages/server/dist/services/cliChatEngine.d.ts +198 -0
- package/packages/server/dist/services/cliChatEngine.d.ts.map +1 -0
- package/packages/server/dist/services/cliChatEngine.js +2977 -0
- package/packages/server/dist/services/cliChatEngine.js.map +1 -0
- package/packages/server/dist/services/cliGridCards.d.ts +87 -0
- package/packages/server/dist/services/cliGridCards.d.ts.map +1 -0
- package/packages/server/dist/services/cliGridCards.js +298 -0
- package/packages/server/dist/services/cliGridCards.js.map +1 -0
- package/packages/server/dist/services/cliGridRegion.d.ts +44 -0
- package/packages/server/dist/services/cliGridRegion.d.ts.map +1 -0
- package/packages/server/dist/services/cliGridRegion.js +94 -0
- package/packages/server/dist/services/cliGridRegion.js.map +1 -0
- package/packages/server/dist/services/cliModalDetect.d.ts +299 -0
- package/packages/server/dist/services/cliModalDetect.d.ts.map +1 -0
- package/packages/server/dist/services/cliModalDetect.js +583 -0
- package/packages/server/dist/services/cliModalDetect.js.map +1 -0
- package/packages/server/dist/services/cliScreenCache.d.ts +33 -0
- package/packages/server/dist/services/cliScreenCache.d.ts.map +1 -0
- package/packages/server/dist/services/cliScreenCache.js +48 -0
- package/packages/server/dist/services/cliScreenCache.js.map +1 -0
- package/packages/server/dist/services/cliScreenModel.d.ts +141 -0
- package/packages/server/dist/services/cliScreenModel.d.ts.map +1 -0
- package/packages/server/dist/services/cliScreenModel.js +196 -0
- package/packages/server/dist/services/cliScreenModel.js.map +1 -0
- package/packages/server/dist/services/cliScreenStallWatchdog.d.ts +41 -0
- package/packages/server/dist/services/cliScreenStallWatchdog.d.ts.map +1 -0
- package/packages/server/dist/services/cliScreenStallWatchdog.js +45 -0
- package/packages/server/dist/services/cliScreenStallWatchdog.js.map +1 -0
- package/packages/server/dist/services/cliSessionPool.d.ts +97 -0
- package/packages/server/dist/services/cliSessionPool.d.ts.map +1 -0
- package/packages/server/dist/services/cliSessionPool.js +278 -0
- package/packages/server/dist/services/cliSessionPool.js.map +1 -0
- package/packages/server/dist/services/cliSpinnerProgress.d.ts +41 -0
- package/packages/server/dist/services/cliSpinnerProgress.d.ts.map +1 -0
- package/packages/server/dist/services/cliSpinnerProgress.js +131 -0
- package/packages/server/dist/services/cliSpinnerProgress.js.map +1 -0
- package/packages/server/dist/services/contextBuilderScriptTemplate.d.ts +24 -0
- package/packages/server/dist/services/contextBuilderScriptTemplate.d.ts.map +1 -0
- package/packages/server/dist/services/contextBuilderScriptTemplate.js +181 -0
- package/packages/server/dist/services/contextBuilderScriptTemplate.js.map +1 -0
- package/packages/server/dist/services/contextBuilderService.d.ts +68 -0
- package/packages/server/dist/services/contextBuilderService.d.ts.map +1 -0
- package/packages/server/dist/services/contextBuilderService.js +345 -0
- package/packages/server/dist/services/contextBuilderService.js.map +1 -0
- package/packages/server/dist/services/fileRewind.d.ts +46 -0
- package/packages/server/dist/services/fileRewind.d.ts.map +1 -0
- package/packages/server/dist/services/fileRewind.js +77 -0
- package/packages/server/dist/services/fileRewind.js.map +1 -0
- package/packages/server/dist/services/fileWatcherService.d.ts.map +1 -1
- package/packages/server/dist/services/fileWatcherService.js +40 -0
- package/packages/server/dist/services/fileWatcherService.js.map +1 -1
- package/packages/server/dist/services/harnessAgentService.d.ts +18 -0
- package/packages/server/dist/services/harnessAgentService.d.ts.map +1 -1
- package/packages/server/dist/services/harnessAgentService.js +55 -0
- package/packages/server/dist/services/harnessAgentService.js.map +1 -1
- package/packages/server/dist/services/harnessBundleService.d.ts +145 -0
- package/packages/server/dist/services/harnessBundleService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessBundleService.js +1318 -0
- package/packages/server/dist/services/harnessBundleService.js.map +1 -0
- package/packages/server/dist/services/harnessCommandService.d.ts +21 -0
- package/packages/server/dist/services/harnessCommandService.d.ts.map +1 -1
- package/packages/server/dist/services/harnessCommandService.js +64 -0
- package/packages/server/dist/services/harnessCommandService.js.map +1 -1
- package/packages/server/dist/services/harnessHookService.d.ts +27 -0
- package/packages/server/dist/services/harnessHookService.d.ts.map +1 -1
- package/packages/server/dist/services/harnessHookService.js +52 -0
- package/packages/server/dist/services/harnessHookService.js.map +1 -1
- package/packages/server/dist/services/harnessMcpService.d.ts +24 -1
- package/packages/server/dist/services/harnessMcpService.d.ts.map +1 -1
- package/packages/server/dist/services/harnessMcpService.js +70 -0
- package/packages/server/dist/services/harnessMcpService.js.map +1 -1
- package/packages/server/dist/services/harnessShareScopeService.d.ts +19 -0
- package/packages/server/dist/services/harnessShareScopeService.d.ts.map +1 -1
- package/packages/server/dist/services/harnessShareScopeService.js +65 -0
- package/packages/server/dist/services/harnessShareScopeService.js.map +1 -1
- package/packages/server/dist/services/historyParser.d.ts +11 -0
- package/packages/server/dist/services/historyParser.d.ts.map +1 -1
- package/packages/server/dist/services/historyParser.js +10 -8
- package/packages/server/dist/services/historyParser.js.map +1 -1
- package/packages/server/dist/services/imageStorageService.d.ts +12 -0
- package/packages/server/dist/services/imageStorageService.d.ts.map +1 -1
- package/packages/server/dist/services/imageStorageService.js +22 -0
- package/packages/server/dist/services/imageStorageService.js.map +1 -1
- package/packages/server/dist/services/issueService.d.ts.map +1 -1
- package/packages/server/dist/services/issueService.js +1 -0
- package/packages/server/dist/services/issueService.js.map +1 -1
- package/packages/server/dist/services/marketplaceService.d.ts +50 -0
- package/packages/server/dist/services/marketplaceService.d.ts.map +1 -0
- package/packages/server/dist/services/marketplaceService.js +326 -0
- package/packages/server/dist/services/marketplaceService.js.map +1 -0
- package/packages/server/dist/services/observabilityService.d.ts +87 -0
- package/packages/server/dist/services/observabilityService.d.ts.map +1 -0
- package/packages/server/dist/services/observabilityService.js +0 -0
- package/packages/server/dist/services/observabilityService.js.map +1 -0
- package/packages/server/dist/services/projectService.d.ts +13 -1
- package/packages/server/dist/services/projectService.d.ts.map +1 -1
- package/packages/server/dist/services/projectService.js +32 -0
- package/packages/server/dist/services/projectService.js.map +1 -1
- package/packages/server/dist/services/queueService.d.ts.map +1 -1
- package/packages/server/dist/services/queueService.js +12 -3
- package/packages/server/dist/services/queueService.js.map +1 -1
- package/packages/server/dist/services/rateLimitProbeService.d.ts +15 -0
- package/packages/server/dist/services/rateLimitProbeService.d.ts.map +1 -1
- package/packages/server/dist/services/rateLimitProbeService.js +48 -19
- package/packages/server/dist/services/rateLimitProbeService.js.map +1 -1
- package/packages/server/dist/services/sessionService.d.ts +16 -0
- package/packages/server/dist/services/sessionService.d.ts.map +1 -1
- package/packages/server/dist/services/sessionService.js +125 -0
- package/packages/server/dist/services/sessionService.js.map +1 -1
- package/packages/server/dist/services/streamHandler.d.ts +8 -1
- package/packages/server/dist/services/streamHandler.d.ts.map +1 -1
- package/packages/server/dist/services/streamHandler.js +12 -5
- package/packages/server/dist/services/streamHandler.js.map +1 -1
- package/packages/server/dist/services/systemBrowseService.d.ts +91 -0
- package/packages/server/dist/services/systemBrowseService.d.ts.map +1 -0
- package/packages/server/dist/services/systemBrowseService.js +372 -0
- package/packages/server/dist/services/systemBrowseService.js.map +1 -0
- package/packages/server/dist/services/tokenCountService.d.ts +71 -0
- package/packages/server/dist/services/tokenCountService.d.ts.map +1 -0
- package/packages/server/dist/services/tokenCountService.js +313 -0
- package/packages/server/dist/services/tokenCountService.js.map +1 -0
- package/packages/server/dist/services/workspaceContext.d.ts +24 -0
- package/packages/server/dist/services/workspaceContext.d.ts.map +1 -0
- package/packages/server/dist/services/workspaceContext.js +109 -0
- package/packages/server/dist/services/workspaceContext.js.map +1 -0
- package/packages/server/dist/snippets/apply-qa-fixes +7 -5
- package/packages/server/dist/snippets/qa-review +7 -1
- package/packages/server/dist/utils/assertSafeBundlePath.d.ts +29 -0
- package/packages/server/dist/utils/assertSafeBundlePath.d.ts.map +1 -0
- package/packages/server/dist/utils/assertSafeBundlePath.js +53 -0
- package/packages/server/dist/utils/assertSafeBundlePath.js.map +1 -0
- package/packages/server/dist/utils/backgroundBlock.d.ts +29 -0
- package/packages/server/dist/utils/backgroundBlock.d.ts.map +1 -0
- package/packages/server/dist/utils/backgroundBlock.js +33 -0
- package/packages/server/dist/utils/backgroundBlock.js.map +1 -0
- package/packages/server/dist/utils/backgroundTaskTracker.d.ts +20 -0
- package/packages/server/dist/utils/backgroundTaskTracker.d.ts.map +1 -0
- package/packages/server/dist/utils/backgroundTaskTracker.js +40 -0
- package/packages/server/dist/utils/backgroundTaskTracker.js.map +1 -0
- package/packages/server/dist/utils/bundledBinaryModelSupport.d.ts +14 -0
- package/packages/server/dist/utils/bundledBinaryModelSupport.d.ts.map +1 -0
- package/packages/server/dist/utils/bundledBinaryModelSupport.js +112 -0
- package/packages/server/dist/utils/bundledBinaryModelSupport.js.map +1 -0
- package/packages/server/dist/utils/cliDebugLog.d.ts +38 -0
- package/packages/server/dist/utils/cliDebugLog.d.ts.map +1 -0
- package/packages/server/dist/utils/cliDebugLog.js +65 -0
- package/packages/server/dist/utils/cliDebugLog.js.map +1 -0
- package/packages/server/dist/utils/cliEngineUtils.d.ts +35 -0
- package/packages/server/dist/utils/cliEngineUtils.d.ts.map +1 -0
- package/packages/server/dist/utils/cliEngineUtils.js +38 -0
- package/packages/server/dist/utils/cliEngineUtils.js.map +1 -0
- package/packages/server/dist/utils/effortUtils.d.ts +2 -2
- package/packages/server/dist/utils/effortUtils.d.ts.map +1 -1
- package/packages/server/dist/utils/effortUtils.js +7 -5
- package/packages/server/dist/utils/effortUtils.js.map +1 -1
- package/packages/server/dist/utils/errors.d.ts +1 -0
- package/packages/server/dist/utils/errors.d.ts.map +1 -1
- package/packages/server/dist/utils/errors.js +17 -0
- package/packages/server/dist/utils/errors.js.map +1 -1
- package/packages/server/dist/utils/harnessBundleSchema.d.ts +14 -12
- package/packages/server/dist/utils/harnessBundleSchema.d.ts.map +1 -1
- package/packages/server/dist/utils/harnessBundleSchema.js +11 -1
- package/packages/server/dist/utils/harnessBundleSchema.js.map +1 -1
- package/packages/server/dist/utils/harnessPaths.d.ts +40 -0
- package/packages/server/dist/utils/harnessPaths.d.ts.map +1 -1
- package/packages/server/dist/utils/harnessPaths.js +123 -0
- package/packages/server/dist/utils/harnessPaths.js.map +1 -1
- package/packages/server/dist/utils/trailingThrottle.d.ts +21 -0
- package/packages/server/dist/utils/trailingThrottle.d.ts.map +1 -0
- package/packages/server/dist/utils/trailingThrottle.js +36 -0
- package/packages/server/dist/utils/trailingThrottle.js.map +1 -0
- package/packages/server/package.json +61 -58
- package/packages/server/resources/internals/INDEX.md +3 -1
- package/packages/server/resources/internals/bmad-qa-fix-marker.md +32 -0
- package/packages/server/resources/internals/harness-files.md +22 -0
- package/packages/server/resources/internals/image-storage.md +9 -0
- package/packages/server/resources/internals/observability-storage.md +23 -0
- package/packages/server/resources/manual/02-chat.md +23 -4
- package/packages/server/resources/manual/03-sessions.md +1 -0
- package/packages/server/resources/manual/05-projects.md +15 -2
- package/packages/server/resources/manual/10-project-board.md +4 -3
- package/packages/server/resources/manual/11-bmad-method-integration.md +12 -8
- package/packages/server/resources/manual/12-harness-workbench.md +82 -1
- package/packages/server/resources/manual/13-settings.md +61 -9
- package/packages/shared/dist/index.d.ts +7 -0
- package/packages/shared/dist/index.d.ts.map +1 -1
- package/packages/shared/dist/index.js +14 -0
- package/packages/shared/dist/index.js.map +1 -1
- package/packages/shared/dist/types/bmadCoreConfig.d.ts +71 -0
- package/packages/shared/dist/types/bmadCoreConfig.d.ts.map +1 -0
- package/packages/shared/dist/types/bmadCoreConfig.js +30 -0
- package/packages/shared/dist/types/bmadCoreConfig.js.map +1 -0
- package/packages/shared/dist/types/bmadStatus.d.ts +26 -0
- package/packages/shared/dist/types/bmadStatus.d.ts.map +1 -1
- package/packages/shared/dist/types/bmadStatus.js.map +1 -1
- package/packages/shared/dist/types/board.d.ts +6 -0
- package/packages/shared/dist/types/board.d.ts.map +1 -1
- package/packages/shared/dist/types/contextBuilder.d.ts +102 -0
- package/packages/shared/dist/types/contextBuilder.d.ts.map +1 -0
- package/packages/shared/dist/types/contextBuilder.js +55 -0
- package/packages/shared/dist/types/contextBuilder.js.map +1 -0
- package/packages/shared/dist/types/harnessBundle.d.ts +35 -0
- package/packages/shared/dist/types/harnessBundle.d.ts.map +1 -1
- package/packages/shared/dist/types/marketplace.d.ts +83 -0
- package/packages/shared/dist/types/marketplace.d.ts.map +1 -0
- package/packages/shared/dist/types/marketplace.js +18 -0
- package/packages/shared/dist/types/marketplace.js.map +1 -0
- package/packages/shared/dist/types/observability.d.ts +148 -0
- package/packages/shared/dist/types/observability.d.ts.map +1 -0
- package/packages/shared/dist/types/observability.js +24 -0
- package/packages/shared/dist/types/observability.js.map +1 -0
- package/packages/shared/dist/types/preferences.d.ts +16 -2
- package/packages/shared/dist/types/preferences.d.ts.map +1 -1
- package/packages/shared/dist/types/preferences.js +1 -0
- package/packages/shared/dist/types/preferences.js.map +1 -1
- package/packages/shared/dist/types/project.d.ts +7 -1
- package/packages/shared/dist/types/project.d.ts.map +1 -1
- package/packages/shared/dist/types/project.js.map +1 -1
- package/packages/shared/dist/types/sdk.d.ts +124 -12
- package/packages/shared/dist/types/sdk.d.ts.map +1 -1
- package/packages/shared/dist/types/sdk.js +64 -19
- package/packages/shared/dist/types/sdk.js.map +1 -1
- package/packages/shared/dist/types/streaming.d.ts +2 -2
- package/packages/shared/dist/types/streaming.d.ts.map +1 -1
- package/packages/shared/dist/types/streaming.js.map +1 -1
- package/packages/shared/dist/types/systemBrowse.d.ts +120 -0
- package/packages/shared/dist/types/systemBrowse.d.ts.map +1 -0
- package/packages/shared/dist/types/systemBrowse.js +57 -0
- package/packages/shared/dist/types/systemBrowse.js.map +1 -0
- package/packages/shared/dist/types/websocket.d.ts +38 -0
- package/packages/shared/dist/types/websocket.d.ts.map +1 -1
- package/packages/shared/dist/utils/interruptFiller.d.ts +30 -0
- package/packages/shared/dist/utils/interruptFiller.d.ts.map +1 -0
- package/packages/shared/dist/utils/interruptFiller.js +38 -0
- package/packages/shared/dist/utils/interruptFiller.js.map +1 -0
- package/packages/shared/dist/utils/toolResultContent.d.ts +22 -0
- package/packages/shared/dist/utils/toolResultContent.d.ts.map +1 -0
- package/packages/shared/dist/utils/toolResultContent.js +29 -0
- package/packages/shared/dist/utils/toolResultContent.js.map +1 -0
- package/scripts/run-integration-test.mjs +362 -362
- package/packages/client/dist/assets/index-CjyjnXB8.css +0 -32
- package/packages/client/dist/assets/index-NqJdhlek.js +0 -1498
|
@@ -107,6 +107,23 @@
|
|
|
107
107
|
"nameError": "セッション名の更新でエラーが発生しました。"
|
|
108
108
|
}
|
|
109
109
|
},
|
|
110
|
+
"systemBrowse": {
|
|
111
|
+
"validation": {
|
|
112
|
+
"pathRequired": "path が必要です。",
|
|
113
|
+
"parentPathRequired": "parentPath が必要です。",
|
|
114
|
+
"nameRequired": "name が必要です。",
|
|
115
|
+
"newNameRequired": "newName が必要です。"
|
|
116
|
+
},
|
|
117
|
+
"error": {
|
|
118
|
+
"invalidPath": "無効なパスです。",
|
|
119
|
+
"notFound": "パスが見つかりません。",
|
|
120
|
+
"notADirectory": "ディレクトリではありません。",
|
|
121
|
+
"permissionDenied": "アクセスが拒否されました。",
|
|
122
|
+
"alreadyExists": "同じ名前のフォルダーが既に存在します。",
|
|
123
|
+
"invalidName": "無効なフォルダー名です。",
|
|
124
|
+
"browseError": "ファイルシステムの参照中にエラーが発生しました。"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
110
127
|
"fs": {
|
|
111
128
|
"validation": {
|
|
112
129
|
"slugRequired": "プロジェクト識別子が必要です。",
|
|
@@ -107,6 +107,23 @@
|
|
|
107
107
|
"nameError": "세션 이름 업데이트 중 오류가 발생했습니다."
|
|
108
108
|
}
|
|
109
109
|
},
|
|
110
|
+
"systemBrowse": {
|
|
111
|
+
"validation": {
|
|
112
|
+
"pathRequired": "path가 필요합니다.",
|
|
113
|
+
"parentPathRequired": "parentPath가 필요합니다.",
|
|
114
|
+
"nameRequired": "name이 필요합니다.",
|
|
115
|
+
"newNameRequired": "newName이 필요합니다."
|
|
116
|
+
},
|
|
117
|
+
"error": {
|
|
118
|
+
"invalidPath": "잘못된 경로입니다.",
|
|
119
|
+
"notFound": "경로를 찾을 수 없습니다.",
|
|
120
|
+
"notADirectory": "디렉토리가 아닙니다.",
|
|
121
|
+
"permissionDenied": "권한이 거부되었습니다.",
|
|
122
|
+
"alreadyExists": "같은 이름의 폴더가 이미 존재합니다.",
|
|
123
|
+
"invalidName": "잘못된 폴더 이름입니다.",
|
|
124
|
+
"browseError": "파일시스템 탐색 중 오류가 발생했습니다."
|
|
125
|
+
}
|
|
126
|
+
},
|
|
110
127
|
"fs": {
|
|
111
128
|
"validation": {
|
|
112
129
|
"slugRequired": "프로젝트 식별자가 필요합니다.",
|
|
@@ -107,6 +107,23 @@
|
|
|
107
107
|
"nameError": "Erro ao atualizar nome da sessão."
|
|
108
108
|
}
|
|
109
109
|
},
|
|
110
|
+
"systemBrowse": {
|
|
111
|
+
"validation": {
|
|
112
|
+
"pathRequired": "path é obrigatório",
|
|
113
|
+
"parentPathRequired": "parentPath é obrigatório",
|
|
114
|
+
"nameRequired": "name é obrigatório",
|
|
115
|
+
"newNameRequired": "newName é obrigatório"
|
|
116
|
+
},
|
|
117
|
+
"error": {
|
|
118
|
+
"invalidPath": "Caminho inválido.",
|
|
119
|
+
"notFound": "Caminho não encontrado.",
|
|
120
|
+
"notADirectory": "Não é um diretório.",
|
|
121
|
+
"permissionDenied": "Permissão negada.",
|
|
122
|
+
"alreadyExists": "Já existe uma pasta com esse nome.",
|
|
123
|
+
"invalidName": "Nome de pasta inválido.",
|
|
124
|
+
"browseError": "Erro ao navegar no sistema de arquivos."
|
|
125
|
+
}
|
|
126
|
+
},
|
|
110
127
|
"fs": {
|
|
111
128
|
"validation": {
|
|
112
129
|
"slugRequired": "O identificador do projeto é obrigatório.",
|
|
@@ -107,6 +107,23 @@
|
|
|
107
107
|
"nameError": "更新会话名称时出错。"
|
|
108
108
|
}
|
|
109
109
|
},
|
|
110
|
+
"systemBrowse": {
|
|
111
|
+
"validation": {
|
|
112
|
+
"pathRequired": "缺少 path 参数",
|
|
113
|
+
"parentPathRequired": "缺少 parentPath 参数",
|
|
114
|
+
"nameRequired": "缺少 name 参数",
|
|
115
|
+
"newNameRequired": "缺少 newName 参数"
|
|
116
|
+
},
|
|
117
|
+
"error": {
|
|
118
|
+
"invalidPath": "路径无效。",
|
|
119
|
+
"notFound": "未找到路径。",
|
|
120
|
+
"notADirectory": "不是目录。",
|
|
121
|
+
"permissionDenied": "权限被拒绝。",
|
|
122
|
+
"alreadyExists": "同名文件夹已存在。",
|
|
123
|
+
"invalidName": "文件夹名称无效。",
|
|
124
|
+
"browseError": "文件系统浏览出错。"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
110
127
|
"fs": {
|
|
111
128
|
"validation": {
|
|
112
129
|
"slugRequired": "请输入项目标识。",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../src/routes/harness.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../src/routes/harness.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAoBH,QAAA,MAAM,MAAM,4CAAW,CAAC;AA2JxB,eAAe,MAAM,CAAC"}
|
|
@@ -15,6 +15,11 @@ import { harnessAgentController } from '../controllers/harnessAgentController.js
|
|
|
15
15
|
import { claudeMdController } from '../controllers/claudeMdController.js';
|
|
16
16
|
import { harnessShareScopeController } from '../controllers/harnessShareScopeController.js';
|
|
17
17
|
import { harnessLintController } from '../controllers/harnessLintController.js';
|
|
18
|
+
import { harnessBundleController, handleBundleUpload } from '../controllers/harnessBundleController.js';
|
|
19
|
+
import { bmadCoreConfigController } from '../controllers/bmadCoreConfigController.js';
|
|
20
|
+
import { contextBuilderController } from '../controllers/contextBuilderController.js';
|
|
21
|
+
import { observabilityController } from '../controllers/observabilityController.js';
|
|
22
|
+
import { marketplaceController } from '../controllers/marketplaceController.js';
|
|
18
23
|
const router = Router();
|
|
19
24
|
// Same body size as fileSystem routes (JSON envelopes can carry ~1MB source files).
|
|
20
25
|
const largeBodyParser = express.json({ limit: '5mb' });
|
|
@@ -57,6 +62,10 @@ router.delete('/hooks/:event/:groupIndex/:hookIndex', largeBodyParser, harnessHo
|
|
|
57
62
|
// splat so Express prefers them.
|
|
58
63
|
router.post('/commands/copy-directory', largeBodyParser, harnessCommandController.copyDirectory);
|
|
59
64
|
router.post('/commands/copy', largeBodyParser, harnessCommandController.copy);
|
|
65
|
+
// Story 30.7 (Task B.2) — env-ref replace endpoint. Must live above the
|
|
66
|
+
// splat so Express does not treat `replace-secret-with-env-ref` as a
|
|
67
|
+
// command relative path.
|
|
68
|
+
router.post('/commands/replace-secret-with-env-ref', largeBodyParser, harnessCommandController.replaceSecretWithEnvRef);
|
|
60
69
|
router.post('/commands', largeBodyParser, harnessCommandController.create);
|
|
61
70
|
router.get('/commands', harnessCommandController.list);
|
|
62
71
|
router.get('/commands/*', harnessCommandController.read);
|
|
@@ -67,6 +76,9 @@ router.delete('/commands/*', largeBodyParser, harnessCommandController.delete);
|
|
|
67
76
|
// Literal `/agents/copy` and the splat-free POST live above the dynamic
|
|
68
77
|
// `:name` segment so Express prefers them.
|
|
69
78
|
router.post('/agents/copy', largeBodyParser, harnessAgentController.copy);
|
|
79
|
+
// Story 30.7 (Task B.2) — env-ref replace endpoint. Lives above the dynamic
|
|
80
|
+
// `:name` so Express does not match the literal as an agent name.
|
|
81
|
+
router.post('/agents/replace-secret-with-env-ref', largeBodyParser, harnessAgentController.replaceSecretWithEnvRef);
|
|
70
82
|
router.post('/agents', largeBodyParser, harnessAgentController.create);
|
|
71
83
|
router.get('/agents', harnessAgentController.list);
|
|
72
84
|
router.get('/agents/:name', harnessAgentController.read);
|
|
@@ -84,9 +96,55 @@ router.post('/claude-md', largeBodyParser, claudeMdController.create);
|
|
|
84
96
|
// Mode A/B verdict. Project scope only — `.gitignore` is irrelevant for
|
|
85
97
|
// the user-scope (`~/.claude`) tree.
|
|
86
98
|
router.get('/share-scope', harnessShareScopeController.evaluate);
|
|
99
|
+
// Story 30.7 (Task D.3) — append a pattern to the project `.gitignore`
|
|
100
|
+
// (idempotent). Used by the `SecretOnSharedDialog → Move to local` flow
|
|
101
|
+
// when the sibling pre-check detects `**/.claude/**/*.local.*` is missing.
|
|
102
|
+
router.post('/share-scope/:projectSlug/append-gitignore', express.json({ limit: '4kb' }), harnessShareScopeController.appendGitignore);
|
|
87
103
|
// Story 30.2 — Static harness lint: 7 rules across the 5 harness domains
|
|
88
104
|
// (skill / mcp / hook / command / agent). Returns LintIssue[] + the user's
|
|
89
105
|
// effective rule preferences (defaults merged with ~/.hammoc/preferences.json).
|
|
90
106
|
router.get('/lint', harnessLintController.evaluate);
|
|
107
|
+
// Story 30.5 — Harness Export/Import bundle: 4 endpoints providing the
|
|
108
|
+
// server-side single source of truth for serializing a project's harness
|
|
109
|
+
// surface into a ZIP + manifest.json and back. Multipart upload is only
|
|
110
|
+
// required by the import-preview endpoint; the other three use JSON bodies.
|
|
111
|
+
router.post('/bundle/export', largeBodyParser, harnessBundleController.export);
|
|
112
|
+
router.post('/bundle/import/preview', handleBundleUpload, harnessBundleController.importPreview);
|
|
113
|
+
router.post('/bundle/import/apply', largeBodyParser, harnessBundleController.importApply);
|
|
114
|
+
router.get('/bundle/plugin-deps', harnessBundleController.pluginDeps);
|
|
115
|
+
// Story 31.1 — BMad core-config editor: read / AST-patch / raw-overwrite of a
|
|
116
|
+
// single project's `.bmad-core/core-config.yaml` (BMad projects only — the nav
|
|
117
|
+
// gate is client-side via `isBmadProject`). The `/raw` segment lives above the
|
|
118
|
+
// bare `:projectSlug` PATCH so Express does not treat `raw` as a slug value.
|
|
119
|
+
router.get('/bmad-config/:projectSlug', bmadCoreConfigController.read);
|
|
120
|
+
router.put('/bmad-config/:projectSlug/raw', largeBodyParser, bmadCoreConfigController.writeRaw);
|
|
121
|
+
router.patch('/bmad-config/:projectSlug', largeBodyParser, bmadCoreConfigController.patch);
|
|
122
|
+
// Story 31.2 — SessionStart context-builder: read / save+generate / disable the
|
|
123
|
+
// `.hammoc/context-builder.json` manifest and its generated `.mjs` + settings
|
|
124
|
+
// entry. Available on ALL projects (no BMad gate). The `/disable` segment lives
|
|
125
|
+
// above the bare `:projectSlug` PUT so Express does not treat `disable` as a
|
|
126
|
+
// slug value.
|
|
127
|
+
router.get('/context-builder/:projectSlug', contextBuilderController.read);
|
|
128
|
+
router.post('/context-builder/:projectSlug/disable', largeBodyParser, contextBuilderController.disable);
|
|
129
|
+
router.put('/context-builder/:projectSlug', largeBodyParser, contextBuilderController.write);
|
|
130
|
+
// Story 31.3 — Observability: MCP call log (read-only aggregates + timeline) +
|
|
131
|
+
// token attribution + count_tokens proxy + global tokenizer preference.
|
|
132
|
+
// Available on ALL projects (no gate). The global `/tokenizer-pref` (no
|
|
133
|
+
// projectSlug) is mounted ABOVE the `:projectSlug` routes so Express does not
|
|
134
|
+
// treat `tokenizer-pref` as a slug. The MCP log has no write endpoint —
|
|
135
|
+
// records are appended by the streamCallbacks recorder.
|
|
136
|
+
const smallBodyParser = express.json({ limit: '32kb' });
|
|
137
|
+
router.get('/observability/tokenizer-pref', observabilityController.getTokenizerPref);
|
|
138
|
+
router.put('/observability/tokenizer-pref', smallBodyParser, observabilityController.setTokenizerPref);
|
|
139
|
+
router.get('/observability/:projectSlug/mcp-calls', observabilityController.mcpCalls);
|
|
140
|
+
router.get('/observability/:projectSlug/token-attribution', observabilityController.tokenAttribution);
|
|
141
|
+
router.post('/observability/:projectSlug/exact-count', smallBodyParser, observabilityController.exactCount);
|
|
142
|
+
// Story 31.4 — Plugin marketplace catalog (read-only). Single GET endpoint:
|
|
143
|
+
// the unified `plugins[]` catalog across registered marketplaces + installed
|
|
144
|
+
// join + per-market partial failures + installed_plugins.json format warning.
|
|
145
|
+
// No install/add POST — direct-install automation was dropped after spike #2
|
|
146
|
+
// (negative); installs are copy-only command guides (see sdk-upstream-issues.md
|
|
147
|
+
// §17·§18).
|
|
148
|
+
router.get('/marketplace/:projectSlug/catalog', marketplaceController.catalog);
|
|
91
149
|
export default router;
|
|
92
150
|
//# sourceMappingURL=harness.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/routes/harness.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/routes/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../src/routes/preferences.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../src/routes/preferences.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,QAAA,MAAM,MAAM,4CAAW,CAAC;AA4MxB,eAAe,MAAM,CAAC"}
|
|
@@ -7,7 +7,8 @@ import { preferencesService } from '../services/preferencesService.js';
|
|
|
7
7
|
import { notificationService } from '../services/notificationService.js';
|
|
8
8
|
import { webPushService } from '../services/webPushService.js';
|
|
9
9
|
import { invalidateI18nCache } from '../middleware/i18n.js';
|
|
10
|
-
import { DEFAULT_WORKSPACE_TEMPLATE, TEMPLATE_VARIABLES } from '../services/
|
|
10
|
+
import { DEFAULT_WORKSPACE_TEMPLATE, TEMPLATE_VARIABLES } from '../services/workspaceContext.js';
|
|
11
|
+
import { broadcastPreferencesChange } from '../handlers/websocket.js';
|
|
11
12
|
const router = Router();
|
|
12
13
|
// GET /api/preferences/telegram — Get Telegram settings (masked)
|
|
13
14
|
router.get('/telegram', async (req, res) => {
|
|
@@ -170,7 +171,10 @@ router.get('/', async (req, res) => {
|
|
|
170
171
|
const overrides = [];
|
|
171
172
|
if (process.env.CHAT_TIMEOUT_MS)
|
|
172
173
|
overrides.push('chatTimeoutMs');
|
|
173
|
-
res.json({
|
|
174
|
+
res.json({
|
|
175
|
+
...preferences,
|
|
176
|
+
_overrides: overrides,
|
|
177
|
+
});
|
|
174
178
|
}
|
|
175
179
|
catch {
|
|
176
180
|
res.status(500).json({ error: { code: 'PREFERENCES_READ_ERROR', message: req.t('preferences.readError') } });
|
|
@@ -189,6 +193,12 @@ router.patch('/', async (req, res) => {
|
|
|
189
193
|
if (req.body.telegram !== undefined || req.body.webPush !== undefined) {
|
|
190
194
|
await notificationService.reload();
|
|
191
195
|
}
|
|
196
|
+
// Multi-device sync: push the change to other connected browsers. The origin
|
|
197
|
+
// browser is identified by a socket-id header and excluded so it doesn't get
|
|
198
|
+
// its own echo (it already applied the change optimistically).
|
|
199
|
+
const rawSocketId = req.header('x-hammoc-socket-id');
|
|
200
|
+
const originSocketId = rawSocketId && rawSocketId.trim() ? rawSocketId.trim() : undefined;
|
|
201
|
+
broadcastPreferencesChange(updated, originSocketId);
|
|
192
202
|
res.json(updated);
|
|
193
203
|
}
|
|
194
204
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preferences.js","sourceRoot":"","sources":["../../src/routes/preferences.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"preferences.js","sourceRoot":"","sources":["../../src/routes/preferences.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System Browse Routes
|
|
3
|
+
* Directory-only system browse endpoints (Epic 34, Story 34.1).
|
|
4
|
+
*
|
|
5
|
+
* GET /browse — list child directories (or drive roots)
|
|
6
|
+
* POST /browse/mkdir — create a folder
|
|
7
|
+
* POST /browse/rename — rename an entry within its parent
|
|
8
|
+
*
|
|
9
|
+
* There is intentionally NO delete route (AC7 — destructive actions are removed
|
|
10
|
+
* from the surface). Request bodies are tiny, so the global express.json() parser
|
|
11
|
+
* (app.ts) suffices — no per-route large-body parser like fileSystem.ts needs.
|
|
12
|
+
* Auth is automatic: this mounts under /api and is not in PUBLIC_ROUTES.
|
|
13
|
+
* [Source: docs/prd/epic-34-directory-browser.md#Story 34.1; packages/server/src/app.ts:97, 105]
|
|
14
|
+
*/
|
|
15
|
+
declare const router: import("express-serve-static-core").Router;
|
|
16
|
+
export default router;
|
|
17
|
+
//# sourceMappingURL=systemBrowse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemBrowse.d.ts","sourceRoot":"","sources":["../../src/routes/systemBrowse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,QAAA,MAAM,MAAM,4CAAW,CAAC;AAMxB,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System Browse Routes
|
|
3
|
+
* Directory-only system browse endpoints (Epic 34, Story 34.1).
|
|
4
|
+
*
|
|
5
|
+
* GET /browse — list child directories (or drive roots)
|
|
6
|
+
* POST /browse/mkdir — create a folder
|
|
7
|
+
* POST /browse/rename — rename an entry within its parent
|
|
8
|
+
*
|
|
9
|
+
* There is intentionally NO delete route (AC7 — destructive actions are removed
|
|
10
|
+
* from the surface). Request bodies are tiny, so the global express.json() parser
|
|
11
|
+
* (app.ts) suffices — no per-route large-body parser like fileSystem.ts needs.
|
|
12
|
+
* Auth is automatic: this mounts under /api and is not in PUBLIC_ROUTES.
|
|
13
|
+
* [Source: docs/prd/epic-34-directory-browser.md#Story 34.1; packages/server/src/app.ts:97, 105]
|
|
14
|
+
*/
|
|
15
|
+
import { Router } from 'express';
|
|
16
|
+
import { systemBrowseController } from '../controllers/systemBrowseController.js';
|
|
17
|
+
const router = Router();
|
|
18
|
+
router.get('/browse', systemBrowseController.browse);
|
|
19
|
+
router.post('/browse/mkdir', systemBrowseController.mkdir);
|
|
20
|
+
router.post('/browse/rename', systemBrowseController.rename);
|
|
21
|
+
export default router;
|
|
22
|
+
//# sourceMappingURL=systemBrowse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemBrowse.js","sourceRoot":"","sources":["../../src/routes/systemBrowse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAElF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,sBAAsB,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,sBAAsB,CAAC,KAAK,CAAC,CAAC;AAC3D,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAE7D,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 31.1: BMad core-config editor service (Epic 31).
|
|
3
|
+
*
|
|
4
|
+
* Domain: the single `<projectRoot>/.bmad-core/core-config.yaml` file that
|
|
5
|
+
* drives downstream BMad agents (`/dev` · `/sm` · `/qa`). This file is the
|
|
6
|
+
* SIBLING of `.claude/` (it lives under `.bmad-core/`, outside the harness
|
|
7
|
+
* whitelist), so it gets a dedicated canonical-path resolver
|
|
8
|
+
* (`resolveBmadCoreConfigPath`) exactly like Story 29.1's CLAUDE.md and Story
|
|
9
|
+
* 30.7's `.gitignore`.
|
|
10
|
+
*
|
|
11
|
+
* Separation from `bmadStatusService`: that service SCANS the whole BMad
|
|
12
|
+
* project (epics, stories, QA, documents) and returns a status snapshot;
|
|
13
|
+
* this service does single-file R/W on the config itself. They read the same
|
|
14
|
+
* file but expose different shapes (status snapshot vs raw config + AST ops),
|
|
15
|
+
* so they stay separate.
|
|
16
|
+
*
|
|
17
|
+
* YAML parser single source of truth: `yaml` (eemeli) via
|
|
18
|
+
* `structuredEditor.applyYamlPatch`, which preserves comments, key order,
|
|
19
|
+
* quoting, and blank-line metadata across a patch. `js-yaml@4` (used by
|
|
20
|
+
* `bmadStatusService` for a lossy status read) must NOT be used here — it has
|
|
21
|
+
* no comment-preservation path (see structuredEditor.ts header).
|
|
22
|
+
*
|
|
23
|
+
* Method contract (all throw typed errors from `HARNESS_ERRORS`):
|
|
24
|
+
* read — content + mtime; missing file → HARNESS_FILE_NOT_FOUND
|
|
25
|
+
* patchKey — AST patch preserving comments/order; STALE_WRITE guard
|
|
26
|
+
* writeRaw — raw text overwrite (Raw editor); same STALE_WRITE guard
|
|
27
|
+
* parseUnknownKeys — partition parsed YAML into known/unknown top-level keys
|
|
28
|
+
*/
|
|
29
|
+
import { type HarnessStructuredPatchOp, type BmadCoreConfigKnownKeys } from '@hammoc/shared';
|
|
30
|
+
export interface BmadCoreConfigReadResult {
|
|
31
|
+
content: string;
|
|
32
|
+
mtime: string;
|
|
33
|
+
}
|
|
34
|
+
export interface BmadCoreConfigParsed {
|
|
35
|
+
knownKeys: BmadCoreConfigKnownKeys;
|
|
36
|
+
unknownKeys: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
declare class BmadCoreConfigService {
|
|
39
|
+
/**
|
|
40
|
+
* Read the raw config text + mtime. Missing file →
|
|
41
|
+
* HARNESS_FILE_NOT_FOUND: the BMad-project gate means this service is only
|
|
42
|
+
* ever called for projects that have `.bmad-core/`, so a missing
|
|
43
|
+
* core-config.yaml is an abnormal state, not an empty-state.
|
|
44
|
+
*/
|
|
45
|
+
read(projectSlug: string): Promise<BmadCoreConfigReadResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Partition a parsed config into the 10 known top-level keys vs everything
|
|
48
|
+
* else. Known nested groups (`qa`/`prd`/`architecture`/`brownfieldEpic`)
|
|
49
|
+
* pass through whole; their leaves are the 18-key matrix the form renders.
|
|
50
|
+
* Unknown top-level keys are surfaced read-only (AC4). Unparseable input →
|
|
51
|
+
* HARNESS_PARSE_ERROR so the client can fall back to raw editing.
|
|
52
|
+
*/
|
|
53
|
+
parseUnknownKeys(content: string): BmadCoreConfigParsed;
|
|
54
|
+
/**
|
|
55
|
+
* Apply AST-level patches to the config, preserving comments/order/quoting
|
|
56
|
+
* for every untouched node — including unknown keys (AC4.b). Running through
|
|
57
|
+
* a read → patch → write round trip means an external mutation that slipped
|
|
58
|
+
* in between read and write surfaces as STALE_WRITE.
|
|
59
|
+
*
|
|
60
|
+
* `expectedMtime` semantics mirror `harnessService.patchStructured`: when the
|
|
61
|
+
* client supplies it, that value is the guard; otherwise the freshly-read
|
|
62
|
+
* mtime guards against a concurrent write during our own round trip.
|
|
63
|
+
*/
|
|
64
|
+
patchKey(projectSlug: string, ops: HarnessStructuredPatchOp[], expectedMtime?: string): Promise<{
|
|
65
|
+
mtime: string;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Raw-mode overwrite: write the supplied text verbatim, bypassing the AST
|
|
69
|
+
* patch (the user intentionally took control of the whole file). The
|
|
70
|
+
* STALE_WRITE guard still applies so a raw save cannot silently clobber an
|
|
71
|
+
* external edit (AC5.b).
|
|
72
|
+
*/
|
|
73
|
+
writeRaw(projectSlug: string, content: string, expectedMtime?: string): Promise<{
|
|
74
|
+
mtime: string;
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Shared write tail: STALE_WRITE guard + writeFile + self-write echo
|
|
78
|
+
* suppression. Mirrors `harnessService.write` / `claudeMdService.write`.
|
|
79
|
+
* The parent `.bmad-core/` directory is guaranteed to exist (BMad-project
|
|
80
|
+
* gate), so there is no auto-mkdir path here.
|
|
81
|
+
*/
|
|
82
|
+
private writeInternal;
|
|
83
|
+
}
|
|
84
|
+
export declare const bmadCoreConfigService: BmadCoreConfigService;
|
|
85
|
+
export {};
|
|
86
|
+
//# sourceMappingURL=bmadCoreConfigService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bmadCoreConfigService.d.ts","sourceRoot":"","sources":["../../src/services/bmadCoreConfigService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC7B,MAAM,gBAAgB,CAAC;AAcxB,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,uBAAuB,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,cAAM,qBAAqB;IACzB;;;;;OAKG;IACG,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAyBlE;;;;;;OAMG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB;IA4BvD;;;;;;;;;OASG;IACG,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,wBAAwB,EAAE,EAC/B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAS7B;;;;;OAKG;IACG,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAK7B;;;;;OAKG;YACW,aAAa;CA0C5B;AAED,eAAO,MAAM,qBAAqB,uBAA8B,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 31.1: BMad core-config editor service (Epic 31).
|
|
3
|
+
*
|
|
4
|
+
* Domain: the single `<projectRoot>/.bmad-core/core-config.yaml` file that
|
|
5
|
+
* drives downstream BMad agents (`/dev` · `/sm` · `/qa`). This file is the
|
|
6
|
+
* SIBLING of `.claude/` (it lives under `.bmad-core/`, outside the harness
|
|
7
|
+
* whitelist), so it gets a dedicated canonical-path resolver
|
|
8
|
+
* (`resolveBmadCoreConfigPath`) exactly like Story 29.1's CLAUDE.md and Story
|
|
9
|
+
* 30.7's `.gitignore`.
|
|
10
|
+
*
|
|
11
|
+
* Separation from `bmadStatusService`: that service SCANS the whole BMad
|
|
12
|
+
* project (epics, stories, QA, documents) and returns a status snapshot;
|
|
13
|
+
* this service does single-file R/W on the config itself. They read the same
|
|
14
|
+
* file but expose different shapes (status snapshot vs raw config + AST ops),
|
|
15
|
+
* so they stay separate.
|
|
16
|
+
*
|
|
17
|
+
* YAML parser single source of truth: `yaml` (eemeli) via
|
|
18
|
+
* `structuredEditor.applyYamlPatch`, which preserves comments, key order,
|
|
19
|
+
* quoting, and blank-line metadata across a patch. `js-yaml@4` (used by
|
|
20
|
+
* `bmadStatusService` for a lossy status read) must NOT be used here — it has
|
|
21
|
+
* no comment-preservation path (see structuredEditor.ts header).
|
|
22
|
+
*
|
|
23
|
+
* Method contract (all throw typed errors from `HARNESS_ERRORS`):
|
|
24
|
+
* read — content + mtime; missing file → HARNESS_FILE_NOT_FOUND
|
|
25
|
+
* patchKey — AST patch preserving comments/order; STALE_WRITE guard
|
|
26
|
+
* writeRaw — raw text overwrite (Raw editor); same STALE_WRITE guard
|
|
27
|
+
* parseUnknownKeys — partition parsed YAML into known/unknown top-level keys
|
|
28
|
+
*/
|
|
29
|
+
import fs from 'fs/promises';
|
|
30
|
+
import { parse as parseYaml } from 'yaml';
|
|
31
|
+
import { HARNESS_ERRORS, BMAD_CORE_CONFIG_KNOWN_TOP_LEVEL_KEYS, } from '@hammoc/shared';
|
|
32
|
+
import { resolveBmadCoreConfigPath } from '../utils/harnessPaths.js';
|
|
33
|
+
import { applyYamlPatch } from '../utils/structuredEditor.js';
|
|
34
|
+
import { fileWatcherService } from './fileWatcherService.js';
|
|
35
|
+
function throwMapped(code, message, extras) {
|
|
36
|
+
const err = new Error(message);
|
|
37
|
+
err.code = code;
|
|
38
|
+
if (extras)
|
|
39
|
+
Object.assign(err, extras);
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
const KNOWN_TOP_LEVEL = new Set(BMAD_CORE_CONFIG_KNOWN_TOP_LEVEL_KEYS);
|
|
43
|
+
class BmadCoreConfigService {
|
|
44
|
+
/**
|
|
45
|
+
* Read the raw config text + mtime. Missing file →
|
|
46
|
+
* HARNESS_FILE_NOT_FOUND: the BMad-project gate means this service is only
|
|
47
|
+
* ever called for projects that have `.bmad-core/`, so a missing
|
|
48
|
+
* core-config.yaml is an abnormal state, not an empty-state.
|
|
49
|
+
*/
|
|
50
|
+
async read(projectSlug) {
|
|
51
|
+
const { absolutePath } = await resolveBmadCoreConfigPath(projectSlug);
|
|
52
|
+
let stat;
|
|
53
|
+
try {
|
|
54
|
+
stat = await fs.stat(absolutePath);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
const code = error.code;
|
|
58
|
+
if (code === 'ENOENT') {
|
|
59
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FILE_NOT_FOUND.code, 'core-config.yaml not found', { absolutePath });
|
|
60
|
+
}
|
|
61
|
+
if (code === 'EACCES') {
|
|
62
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied');
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
if (!stat.isFile()) {
|
|
67
|
+
throwMapped(HARNESS_ERRORS.HARNESS_NOT_A_FILE.code, 'path is not a file');
|
|
68
|
+
}
|
|
69
|
+
const content = await fs.readFile(absolutePath, 'utf-8');
|
|
70
|
+
return { content, mtime: stat.mtime.toISOString() };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Partition a parsed config into the 10 known top-level keys vs everything
|
|
74
|
+
* else. Known nested groups (`qa`/`prd`/`architecture`/`brownfieldEpic`)
|
|
75
|
+
* pass through whole; their leaves are the 18-key matrix the form renders.
|
|
76
|
+
* Unknown top-level keys are surfaced read-only (AC4). Unparseable input →
|
|
77
|
+
* HARNESS_PARSE_ERROR so the client can fall back to raw editing.
|
|
78
|
+
*/
|
|
79
|
+
parseUnknownKeys(content) {
|
|
80
|
+
let parsed;
|
|
81
|
+
try {
|
|
82
|
+
parsed = parseYaml(content);
|
|
83
|
+
}
|
|
84
|
+
catch (cause) {
|
|
85
|
+
throwMapped(HARNESS_ERRORS.HARNESS_PARSE_ERROR.code, `failed to parse core-config.yaml: ${cause?.message ?? String(cause)}`);
|
|
86
|
+
}
|
|
87
|
+
const knownKeys = {};
|
|
88
|
+
const unknownKeys = {};
|
|
89
|
+
// A comment-only / empty file parses to null or a scalar — treat as no keys.
|
|
90
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
91
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
92
|
+
if (KNOWN_TOP_LEVEL.has(key)) {
|
|
93
|
+
knownKeys[key] = value;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
unknownKeys[key] = value;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { knownKeys: knownKeys, unknownKeys };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Apply AST-level patches to the config, preserving comments/order/quoting
|
|
104
|
+
* for every untouched node — including unknown keys (AC4.b). Running through
|
|
105
|
+
* a read → patch → write round trip means an external mutation that slipped
|
|
106
|
+
* in between read and write surfaces as STALE_WRITE.
|
|
107
|
+
*
|
|
108
|
+
* `expectedMtime` semantics mirror `harnessService.patchStructured`: when the
|
|
109
|
+
* client supplies it, that value is the guard; otherwise the freshly-read
|
|
110
|
+
* mtime guards against a concurrent write during our own round trip.
|
|
111
|
+
*/
|
|
112
|
+
async patchKey(projectSlug, ops, expectedMtime) {
|
|
113
|
+
const { absolutePath } = await resolveBmadCoreConfigPath(projectSlug);
|
|
114
|
+
const current = await this.read(projectSlug);
|
|
115
|
+
const patched = applyYamlPatch(current.content, ops);
|
|
116
|
+
const guardMtime = expectedMtime ?? current.mtime;
|
|
117
|
+
return this.writeInternal(absolutePath, patched, guardMtime);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Raw-mode overwrite: write the supplied text verbatim, bypassing the AST
|
|
121
|
+
* patch (the user intentionally took control of the whole file). The
|
|
122
|
+
* STALE_WRITE guard still applies so a raw save cannot silently clobber an
|
|
123
|
+
* external edit (AC5.b).
|
|
124
|
+
*/
|
|
125
|
+
async writeRaw(projectSlug, content, expectedMtime) {
|
|
126
|
+
const { absolutePath } = await resolveBmadCoreConfigPath(projectSlug);
|
|
127
|
+
return this.writeInternal(absolutePath, content, expectedMtime);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Shared write tail: STALE_WRITE guard + writeFile + self-write echo
|
|
131
|
+
* suppression. Mirrors `harnessService.write` / `claudeMdService.write`.
|
|
132
|
+
* The parent `.bmad-core/` directory is guaranteed to exist (BMad-project
|
|
133
|
+
* gate), so there is no auto-mkdir path here.
|
|
134
|
+
*/
|
|
135
|
+
async writeInternal(absolutePath, content, expectedMtime) {
|
|
136
|
+
if (expectedMtime !== undefined) {
|
|
137
|
+
try {
|
|
138
|
+
const existing = await fs.stat(absolutePath);
|
|
139
|
+
const currentMtime = existing.mtime.toISOString();
|
|
140
|
+
if (currentMtime !== expectedMtime) {
|
|
141
|
+
throwMapped(HARNESS_ERRORS.HARNESS_STALE_WRITE.code, 'file changed on disk', { currentMtime });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
const code = error.code;
|
|
146
|
+
if (code === 'ENOENT') {
|
|
147
|
+
throwMapped(HARNESS_ERRORS.HARNESS_STALE_WRITE.code, 'file missing on disk', { currentMtime: '' });
|
|
148
|
+
}
|
|
149
|
+
if (code === HARNESS_ERRORS.HARNESS_STALE_WRITE.code)
|
|
150
|
+
throw error;
|
|
151
|
+
if (code === 'EACCES') {
|
|
152
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied');
|
|
153
|
+
}
|
|
154
|
+
// Any other stat failure: fall through and let writeFile surface it.
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
await fs.writeFile(absolutePath, content, 'utf-8');
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
const code = error.code;
|
|
162
|
+
if (code === 'EACCES') {
|
|
163
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied');
|
|
164
|
+
}
|
|
165
|
+
throwMapped(HARNESS_ERRORS.HARNESS_WRITE_ERROR.code, 'failed to write file');
|
|
166
|
+
}
|
|
167
|
+
const stat = await fs.stat(absolutePath);
|
|
168
|
+
// Share the harness self-write suppression map so the `.bmad-core/`
|
|
169
|
+
// watcher (Task A.4) swallows our own-write echo on the same path.
|
|
170
|
+
fileWatcherService.noteLocalWrite(absolutePath);
|
|
171
|
+
return { mtime: stat.mtime.toISOString() };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
export const bmadCoreConfigService = new BmadCoreConfigService();
|
|
175
|
+
//# sourceMappingURL=bmadCoreConfigService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bmadCoreConfigService.js","sourceRoot":"","sources":["../../src/services/bmadCoreConfigService.ts"],"names":[],"mappings":"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"}
|