hammoc 1.4.0 → 1.6.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 +428 -405
- package/bin/hammoc.js +0 -6
- package/package.json +100 -94
- package/packages/client/dist/assets/agentExampleHighlight-ltj9ce0U.js +1 -0
- package/packages/client/dist/assets/commandTokenHighlight-ji_ViMb4.js +1 -0
- package/packages/client/dist/assets/index-B-DiRGuz.js +2 -0
- package/packages/client/dist/assets/index-B09doO8H.js +139 -0
- package/packages/client/dist/assets/index-BT4RIi0U.js +1523 -0
- package/packages/client/dist/assets/index-DyNJ5jEW.css +32 -0
- package/packages/client/dist/assets/snippetTokenHighlight-CP3v4o2g.js +1 -0
- package/packages/client/dist/index.html +2 -2
- package/packages/client/dist/sw.js +1 -1
- package/packages/server/dist/app.d.ts.map +1 -1
- package/packages/server/dist/app.js +13 -21
- package/packages/server/dist/app.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/claudeMdController.d.ts +26 -0
- package/packages/server/dist/controllers/claudeMdController.d.ts.map +1 -0
- package/packages/server/dist/controllers/claudeMdController.js +158 -0
- package/packages/server/dist/controllers/claudeMdController.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 +35 -0
- package/packages/server/dist/controllers/harnessAgentController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessAgentController.js +372 -0
- package/packages/server/dist/controllers/harnessAgentController.js.map +1 -0
- 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 +35 -0
- package/packages/server/dist/controllers/harnessCommandController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessCommandController.js +415 -0
- package/packages/server/dist/controllers/harnessCommandController.js.map +1 -0
- package/packages/server/dist/controllers/harnessController.d.ts +21 -0
- package/packages/server/dist/controllers/harnessController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessController.js +176 -0
- package/packages/server/dist/controllers/harnessController.js.map +1 -0
- package/packages/server/dist/controllers/harnessHookController.d.ts +32 -0
- package/packages/server/dist/controllers/harnessHookController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessHookController.js +406 -0
- package/packages/server/dist/controllers/harnessHookController.js.map +1 -0
- package/packages/server/dist/controllers/harnessLintController.d.ts +18 -0
- package/packages/server/dist/controllers/harnessLintController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessLintController.js +72 -0
- package/packages/server/dist/controllers/harnessLintController.js.map +1 -0
- package/packages/server/dist/controllers/harnessMcpController.d.ts +28 -0
- package/packages/server/dist/controllers/harnessMcpController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessMcpController.js +371 -0
- package/packages/server/dist/controllers/harnessMcpController.js.map +1 -0
- package/packages/server/dist/controllers/harnessPluginController.d.ts +17 -0
- package/packages/server/dist/controllers/harnessPluginController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessPluginController.js +115 -0
- package/packages/server/dist/controllers/harnessPluginController.js.map +1 -0
- package/packages/server/dist/controllers/harnessShareScopeController.d.ts +24 -0
- package/packages/server/dist/controllers/harnessShareScopeController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessShareScopeController.js +120 -0
- package/packages/server/dist/controllers/harnessShareScopeController.js.map +1 -0
- package/packages/server/dist/controllers/harnessSkillController.d.ts +32 -0
- package/packages/server/dist/controllers/harnessSkillController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessSkillController.js +453 -0
- package/packages/server/dist/controllers/harnessSkillController.js.map +1 -0
- 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 +11 -0
- package/packages/server/dist/controllers/projectController.js.map +1 -1
- package/packages/server/dist/controllers/snippetController.d.ts +35 -0
- package/packages/server/dist/controllers/snippetController.d.ts.map +1 -0
- package/packages/server/dist/controllers/snippetController.js +294 -0
- package/packages/server/dist/controllers/snippetController.js.map +1 -0
- package/packages/server/dist/handlers/streamCallbacks.d.ts +8 -0
- package/packages/server/dist/handlers/streamCallbacks.d.ts.map +1 -1
- package/packages/server/dist/handlers/streamCallbacks.js +8 -0
- package/packages/server/dist/handlers/streamCallbacks.js.map +1 -1
- package/packages/server/dist/handlers/websocket.d.ts +15 -0
- package/packages/server/dist/handlers/websocket.d.ts.map +1 -1
- package/packages/server/dist/handlers/websocket.js +103 -2
- package/packages/server/dist/handlers/websocket.js.map +1 -1
- package/packages/server/dist/index.js +5 -0
- package/packages/server/dist/index.js.map +1 -1
- package/packages/server/dist/locales/en/server.json +37 -4
- package/packages/server/dist/locales/es/server.json +0 -4
- package/packages/server/dist/locales/ja/server.json +0 -4
- package/packages/server/dist/locales/ko/server.json +0 -4
- package/packages/server/dist/locales/pt/server.json +0 -4
- package/packages/server/dist/locales/zh-CN/server.json +0 -4
- package/packages/server/dist/routes/harness.d.ts +8 -0
- package/packages/server/dist/routes/harness.d.ts.map +1 -0
- package/packages/server/dist/routes/harness.js +150 -0
- package/packages/server/dist/routes/harness.js.map +1 -0
- package/packages/server/dist/routes/projects.d.ts.map +1 -1
- package/packages/server/dist/routes/projects.js +5 -60
- package/packages/server/dist/routes/projects.js.map +1 -1
- package/packages/server/dist/routes/snippets.d.ts +14 -0
- package/packages/server/dist/routes/snippets.d.ts.map +1 -0
- package/packages/server/dist/routes/snippets.js +27 -0
- package/packages/server/dist/routes/snippets.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 +15 -2
- package/packages/server/dist/services/bmadStatusService.d.ts.map +1 -1
- package/packages/server/dist/services/bmadStatusService.js +146 -37
- package/packages/server/dist/services/bmadStatusService.js.map +1 -1
- package/packages/server/dist/services/chatService.d.ts +3 -0
- package/packages/server/dist/services/chatService.d.ts.map +1 -1
- package/packages/server/dist/services/chatService.js +28 -7
- package/packages/server/dist/services/chatService.js.map +1 -1
- package/packages/server/dist/services/claudeMdService.d.ts +48 -0
- package/packages/server/dist/services/claudeMdService.d.ts.map +1 -0
- package/packages/server/dist/services/claudeMdService.js +240 -0
- package/packages/server/dist/services/claudeMdService.js.map +1 -0
- package/packages/server/dist/services/commandService.d.ts +10 -0
- package/packages/server/dist/services/commandService.d.ts.map +1 -1
- package/packages/server/dist/services/commandService.js +129 -4
- package/packages/server/dist/services/commandService.js.map +1 -1
- 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/fileWatcherService.d.ts +24 -0
- package/packages/server/dist/services/fileWatcherService.d.ts.map +1 -1
- package/packages/server/dist/services/fileWatcherService.js +232 -1
- package/packages/server/dist/services/fileWatcherService.js.map +1 -1
- package/packages/server/dist/services/harnessAgentService.d.ts +97 -0
- package/packages/server/dist/services/harnessAgentService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessAgentService.js +988 -0
- package/packages/server/dist/services/harnessAgentService.js.map +1 -0
- 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 +81 -0
- package/packages/server/dist/services/harnessCommandService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessCommandService.js +917 -0
- package/packages/server/dist/services/harnessCommandService.js.map +1 -0
- package/packages/server/dist/services/harnessHookService.d.ts +82 -0
- package/packages/server/dist/services/harnessHookService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessHookService.js +1112 -0
- package/packages/server/dist/services/harnessHookService.js.map +1 -0
- package/packages/server/dist/services/harnessLintService.d.ts +49 -0
- package/packages/server/dist/services/harnessLintService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessLintService.js +628 -0
- package/packages/server/dist/services/harnessLintService.js.map +1 -0
- package/packages/server/dist/services/harnessMcpService.d.ts +100 -0
- package/packages/server/dist/services/harnessMcpService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessMcpService.js +884 -0
- package/packages/server/dist/services/harnessMcpService.js.map +1 -0
- package/packages/server/dist/services/harnessPluginService.d.ts +66 -0
- package/packages/server/dist/services/harnessPluginService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessPluginService.js +559 -0
- package/packages/server/dist/services/harnessPluginService.js.map +1 -0
- package/packages/server/dist/services/harnessService.d.ts +40 -0
- package/packages/server/dist/services/harnessService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessService.js +222 -0
- package/packages/server/dist/services/harnessService.js.map +1 -0
- package/packages/server/dist/services/harnessShareScopeService.d.ts +50 -0
- package/packages/server/dist/services/harnessShareScopeService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessShareScopeService.js +158 -0
- package/packages/server/dist/services/harnessShareScopeService.js.map +1 -0
- package/packages/server/dist/services/harnessSkillService.d.ts +70 -0
- package/packages/server/dist/services/harnessSkillService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessSkillService.js +636 -0
- package/packages/server/dist/services/harnessSkillService.js.map +1 -0
- package/packages/server/dist/services/issueService.d.ts.map +1 -1
- package/packages/server/dist/services/issueService.js +3 -1
- package/packages/server/dist/services/issueService.js.map +1 -1
- package/packages/server/dist/services/manualSyncService.d.ts +19 -0
- package/packages/server/dist/services/manualSyncService.d.ts.map +1 -0
- package/packages/server/dist/services/manualSyncService.js +110 -0
- package/packages/server/dist/services/manualSyncService.js.map +1 -0
- 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/queueService.d.ts.map +1 -1
- package/packages/server/dist/services/queueService.js +48 -2
- package/packages/server/dist/services/queueService.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/snippetService.d.ts +54 -0
- package/packages/server/dist/services/snippetService.d.ts.map +1 -0
- package/packages/server/dist/services/snippetService.js +371 -0
- package/packages/server/dist/services/snippetService.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/utils/applyYamlFrontmatterPatch.d.ts +46 -0
- package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.d.ts.map +1 -0
- package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.js +125 -0
- package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.js.map +1 -0
- package/packages/server/dist/snippets/apply-qa-fixes +7 -5
- package/packages/server/dist/snippets/qa-review +5 -1
- package/packages/server/dist/snippets/split-commit +9 -0
- package/packages/server/dist/utils/applySecretsPolicy.d.ts +53 -0
- package/packages/server/dist/utils/applySecretsPolicy.d.ts.map +1 -0
- package/packages/server/dist/utils/applySecretsPolicy.js +204 -0
- package/packages/server/dist/utils/applySecretsPolicy.js.map +1 -0
- package/packages/server/dist/utils/assertNoSecretOnShared.d.ts +40 -0
- package/packages/server/dist/utils/assertNoSecretOnShared.d.ts.map +1 -0
- package/packages/server/dist/utils/assertNoSecretOnShared.js +47 -0
- package/packages/server/dist/utils/assertNoSecretOnShared.js.map +1 -0
- 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/bundledBinaryModelSupport.d.ts +7 -0
- package/packages/server/dist/utils/bundledBinaryModelSupport.d.ts.map +1 -0
- package/packages/server/dist/utils/bundledBinaryModelSupport.js +107 -0
- package/packages/server/dist/utils/bundledBinaryModelSupport.js.map +1 -0
- package/packages/server/dist/utils/effortUtils.d.ts +2 -2
- package/packages/server/dist/utils/effortUtils.js +5 -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/gitignoreFilter.d.ts +23 -0
- package/packages/server/dist/utils/gitignoreFilter.d.ts.map +1 -0
- package/packages/server/dist/utils/gitignoreFilter.js +42 -0
- package/packages/server/dist/utils/gitignoreFilter.js.map +1 -0
- package/packages/server/dist/utils/harnessBundleSchema.d.ts +107 -0
- package/packages/server/dist/utils/harnessBundleSchema.d.ts.map +1 -0
- package/packages/server/dist/utils/harnessBundleSchema.js +89 -0
- package/packages/server/dist/utils/harnessBundleSchema.js.map +1 -0
- package/packages/server/dist/utils/harnessPaths.d.ts +74 -0
- package/packages/server/dist/utils/harnessPaths.d.ts.map +1 -0
- package/packages/server/dist/utils/harnessPaths.js +247 -0
- package/packages/server/dist/utils/harnessPaths.js.map +1 -0
- package/packages/server/dist/utils/secretHeuristic.d.ts +72 -0
- package/packages/server/dist/utils/secretHeuristic.d.ts.map +1 -0
- package/packages/server/dist/utils/secretHeuristic.js +163 -0
- package/packages/server/dist/utils/secretHeuristic.js.map +1 -0
- package/packages/server/dist/utils/secretPlaceholderNamer.d.ts +41 -0
- package/packages/server/dist/utils/secretPlaceholderNamer.d.ts.map +1 -0
- package/packages/server/dist/utils/secretPlaceholderNamer.js +81 -0
- package/packages/server/dist/utils/secretPlaceholderNamer.js.map +1 -0
- package/packages/server/dist/utils/serverPathResolver.d.ts +29 -0
- package/packages/server/dist/utils/serverPathResolver.d.ts.map +1 -0
- package/packages/server/dist/utils/serverPathResolver.js +59 -0
- package/packages/server/dist/utils/serverPathResolver.js.map +1 -0
- package/packages/server/dist/utils/snippetPaths.d.ts +61 -0
- package/packages/server/dist/utils/snippetPaths.d.ts.map +1 -0
- package/packages/server/dist/utils/snippetPaths.js +123 -0
- package/packages/server/dist/utils/snippetPaths.js.map +1 -0
- package/packages/server/dist/utils/structuredEditor.d.ts +34 -0
- package/packages/server/dist/utils/structuredEditor.d.ts.map +1 -0
- package/packages/server/dist/utils/structuredEditor.js +111 -0
- package/packages/server/dist/utils/structuredEditor.js.map +1 -0
- package/packages/server/package.json +6 -2
- package/packages/server/resources/internals/INDEX.md +25 -0
- package/packages/server/resources/internals/bmad-qa-fix-marker.md +32 -0
- package/packages/server/resources/internals/harness-files.md +85 -0
- package/packages/server/resources/internals/image-storage.md +43 -0
- package/packages/server/resources/internals/observability-storage.md +23 -0
- package/packages/server/resources/manual/01-getting-started.md +104 -0
- package/packages/server/resources/manual/02-chat.md +285 -0
- package/packages/server/resources/manual/03-sessions.md +48 -0
- package/packages/server/resources/manual/04-slash-commands-favorites.md +152 -0
- package/packages/server/resources/manual/05-projects.md +76 -0
- package/packages/server/resources/manual/06-file-explorer-editor.md +90 -0
- package/packages/server/resources/manual/07-git.md +94 -0
- package/packages/server/resources/manual/08-terminal.md +59 -0
- package/packages/server/resources/manual/09-queue-runner.md +262 -0
- package/packages/server/resources/manual/10-project-board.md +194 -0
- package/packages/server/resources/manual/11-bmad-method-integration.md +130 -0
- package/packages/server/resources/manual/12-harness-workbench.md +256 -0
- package/packages/server/resources/manual/13-settings.md +241 -0
- package/packages/server/resources/manual/14-keyboard-shortcuts.md +68 -0
- package/packages/server/resources/manual/15-environment-variables.md +28 -0
- package/packages/server/resources/manual/16-troubleshooting.md +110 -0
- package/packages/server/resources/manual/INDEX.md +60 -0
- 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 +10 -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/command.d.ts +3 -3
- package/packages/shared/dist/types/command.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/harness.d.ts +1211 -0
- package/packages/shared/dist/types/harness.d.ts.map +1 -0
- package/packages/shared/dist/types/harness.js +107 -0
- package/packages/shared/dist/types/harness.js.map +1 -0
- package/packages/shared/dist/types/harnessBundle.d.ts +205 -0
- package/packages/shared/dist/types/harnessBundle.d.ts.map +1 -0
- package/packages/shared/dist/types/harnessBundle.js +18 -0
- package/packages/shared/dist/types/harnessBundle.js.map +1 -0
- 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 +4 -0
- package/packages/shared/dist/types/preferences.d.ts.map +1 -1
- package/packages/shared/dist/types/preferences.js.map +1 -1
- package/packages/shared/dist/types/queue.d.ts +9 -0
- package/packages/shared/dist/types/queue.d.ts.map +1 -1
- package/packages/shared/dist/types/sdk.d.ts +1 -1
- package/packages/shared/dist/types/sdk.d.ts.map +1 -1
- package/packages/shared/dist/types/sdk.js +1 -1
- package/packages/shared/dist/types/sdk.js.map +1 -1
- package/packages/shared/dist/types/websocket.d.ts +10 -0
- package/packages/shared/dist/types/websocket.d.ts.map +1 -1
- package/packages/shared/dist/utils/markdownSections.d.ts +50 -0
- package/packages/shared/dist/utils/markdownSections.d.ts.map +1 -0
- package/packages/shared/dist/utils/markdownSections.js +111 -0
- package/packages/shared/dist/utils/markdownSections.js.map +1 -0
- package/packages/shared/dist/utils/queueParser.d.ts.map +1 -1
- package/packages/shared/dist/utils/queueParser.js +104 -0
- package/packages/shared/dist/utils/queueParser.js.map +1 -1
- package/scripts/build-manual-shards.mjs +100 -0
- package/packages/client/dist/assets/index-6jREnVYd.js +0 -2
- package/packages/client/dist/assets/index-BFF0iqyW.css +0 -32
- package/packages/client/dist/assets/index-BcI4y-fU.js +0 -1454
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 29.2: Snippet management controller.
|
|
3
|
+
*
|
|
4
|
+
* Mounts at `/api/snippets/*` (NOT `/api/harness/*`) — the snippet system is
|
|
5
|
+
* Hammoc-native (`%name%` chat-input expansion via `snippetResolver`), not a
|
|
6
|
+
* Claude Code harness primitive, so its API namespace is intentionally
|
|
7
|
+
* separate from `/api/harness/snippets` to keep intent boundaries crisp.
|
|
8
|
+
*
|
|
9
|
+
* Error envelope mirrors `claudeMdController` and `harnessController` so the
|
|
10
|
+
* client can route both response shapes through the same error-display logic:
|
|
11
|
+
* `{ error: { code, message, details? } }`
|
|
12
|
+
*
|
|
13
|
+
* Origin-socket broadcast (AC1.e): mutation endpoints (POST/PUT/DELETE/copy)
|
|
14
|
+
* read `X-Hammoc-Socket-Id` and `X-Hammoc-Working-Directory` headers and
|
|
15
|
+
* forward them to `broadcastSnippetList()` so the originating client's
|
|
16
|
+
* autocomplete surfaces (`SnippetPalette` via `useSnippets`) re-receive a
|
|
17
|
+
* fresh `snippets:list` payload without an explicit `refresh()` call.
|
|
18
|
+
* Phase-1 fan-out is single-socket; multi-tab sync is deferred (story AC1.e).
|
|
19
|
+
*/
|
|
20
|
+
import { z } from 'zod';
|
|
21
|
+
import { HARNESS_ERRORS } from '@hammoc/shared';
|
|
22
|
+
import { snippetService } from '../services/snippetService.js';
|
|
23
|
+
import { broadcastSnippetList } from '../handlers/websocket.js';
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Schemas
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
const SCOPE_SCHEMA = z.enum(['project', 'user', 'bundled']);
|
|
28
|
+
const MUTABLE_SCOPE_SCHEMA = z.enum(['project', 'user']);
|
|
29
|
+
const refParamsSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
scope: SCOPE_SCHEMA,
|
|
32
|
+
name: z.string().min(1),
|
|
33
|
+
});
|
|
34
|
+
const refQuerySchema = z.object({
|
|
35
|
+
projectSlug: z.string().optional(),
|
|
36
|
+
});
|
|
37
|
+
const listQuerySchema = z.object({
|
|
38
|
+
projectSlug: z.string().optional(),
|
|
39
|
+
});
|
|
40
|
+
const writeBodySchema = z.object({
|
|
41
|
+
content: z.string(),
|
|
42
|
+
expectedMtime: z.string().optional(),
|
|
43
|
+
projectSlug: z.string().optional(),
|
|
44
|
+
});
|
|
45
|
+
const deleteBodySchema = z.object({
|
|
46
|
+
expectedMtime: z.string().optional(),
|
|
47
|
+
projectSlug: z.string().optional(),
|
|
48
|
+
});
|
|
49
|
+
const copyBodySchema = z.object({
|
|
50
|
+
sourceScope: SCOPE_SCHEMA,
|
|
51
|
+
sourceName: z.string().min(1),
|
|
52
|
+
sourceProjectSlug: z.string().optional(),
|
|
53
|
+
targetScope: MUTABLE_SCOPE_SCHEMA,
|
|
54
|
+
targetName: z.string().min(1).optional(),
|
|
55
|
+
targetProjectSlug: z.string().optional(),
|
|
56
|
+
onConflict: z.enum(['abort', 'overwrite', 'rename']).optional(),
|
|
57
|
+
});
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Error mapping
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
const MAPPED_CODES = [
|
|
62
|
+
'HARNESS_PATH_DENIED',
|
|
63
|
+
'HARNESS_FORBIDDEN',
|
|
64
|
+
'HARNESS_FILE_NOT_FOUND',
|
|
65
|
+
'HARNESS_ROOT_MISSING',
|
|
66
|
+
'HARNESS_STALE_WRITE',
|
|
67
|
+
'HARNESS_FILE_EXISTS',
|
|
68
|
+
'HARNESS_BUNDLED_READONLY',
|
|
69
|
+
'HARNESS_PARSE_ERROR',
|
|
70
|
+
];
|
|
71
|
+
const MESSAGE_KEY = {
|
|
72
|
+
HARNESS_PATH_DENIED: 'harness.error.pathDenied',
|
|
73
|
+
HARNESS_FORBIDDEN: 'harness.error.forbidden',
|
|
74
|
+
HARNESS_FILE_NOT_FOUND: 'harness.error.fileNotFound',
|
|
75
|
+
HARNESS_ROOT_MISSING: 'harness.error.rootMissing',
|
|
76
|
+
HARNESS_STALE_WRITE: 'harness.error.staleWrite',
|
|
77
|
+
HARNESS_FILE_EXISTS: 'harness.snippets.error.fileExists',
|
|
78
|
+
HARNESS_BUNDLED_READONLY: 'harness.snippets.error.bundledReadOnly',
|
|
79
|
+
HARNESS_PARSE_ERROR: 'harness.error.parseError',
|
|
80
|
+
};
|
|
81
|
+
function handleError(req, res, error) {
|
|
82
|
+
const nodeError = error;
|
|
83
|
+
for (const key of MAPPED_CODES) {
|
|
84
|
+
const entry = HARNESS_ERRORS[key];
|
|
85
|
+
if (nodeError.code === entry.code) {
|
|
86
|
+
const body = {
|
|
87
|
+
code: entry.code,
|
|
88
|
+
message: req.t(MESSAGE_KEY[key]),
|
|
89
|
+
};
|
|
90
|
+
if (key === 'HARNESS_STALE_WRITE') {
|
|
91
|
+
body.details = { currentMtime: nodeError.currentMtime ?? '' };
|
|
92
|
+
}
|
|
93
|
+
if (key === 'HARNESS_FILE_NOT_FOUND' && nodeError.absolutePath) {
|
|
94
|
+
body.details = { absolutePath: nodeError.absolutePath };
|
|
95
|
+
}
|
|
96
|
+
res.status(entry.httpStatus).json({ error: body });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
res.status(HARNESS_ERRORS.HARNESS_WRITE_ERROR.httpStatus).json({
|
|
101
|
+
error: {
|
|
102
|
+
code: HARNESS_ERRORS.HARNESS_WRITE_ERROR.code,
|
|
103
|
+
message: req.t('harness.error.writeError'),
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// Helpers
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
function parseRefParams(req, res, projectSlug) {
|
|
111
|
+
const parsed = refParamsSchema.safeParse(req.params);
|
|
112
|
+
if (!parsed.success) {
|
|
113
|
+
res.status(400).json({
|
|
114
|
+
error: {
|
|
115
|
+
code: 'INVALID_REQUEST',
|
|
116
|
+
message: parsed.error.issues[0]?.message ?? 'invalid params',
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
if (parsed.data.scope === 'project' && !projectSlug) {
|
|
122
|
+
res.status(400).json({
|
|
123
|
+
error: {
|
|
124
|
+
code: 'INVALID_REQUEST',
|
|
125
|
+
message: 'projectSlug is required for project scope',
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
scope: parsed.data.scope,
|
|
132
|
+
projectSlug: parsed.data.scope === 'project' ? projectSlug : undefined,
|
|
133
|
+
name: parsed.data.name,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function readBroadcastHeaders(req) {
|
|
137
|
+
const socketId = stringHeader(req.header('x-hammoc-socket-id'));
|
|
138
|
+
const workingDirectory = stringHeader(req.header('x-hammoc-working-directory'));
|
|
139
|
+
return { socketId, workingDirectory };
|
|
140
|
+
}
|
|
141
|
+
function stringHeader(value) {
|
|
142
|
+
if (!value)
|
|
143
|
+
return undefined;
|
|
144
|
+
const trimmed = value.trim();
|
|
145
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
146
|
+
}
|
|
147
|
+
async function emitOriginRefresh(req) {
|
|
148
|
+
const { socketId, workingDirectory } = readBroadcastHeaders(req);
|
|
149
|
+
if (!socketId || !workingDirectory)
|
|
150
|
+
return;
|
|
151
|
+
await broadcastSnippetList(workingDirectory, socketId);
|
|
152
|
+
}
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// Controller
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
export const snippetController = {
|
|
157
|
+
/** GET /api/snippets?projectSlug=<slug> */
|
|
158
|
+
async list(req, res) {
|
|
159
|
+
const parsed = listQuerySchema.safeParse(req.query);
|
|
160
|
+
if (!parsed.success) {
|
|
161
|
+
res.status(400).json({
|
|
162
|
+
error: {
|
|
163
|
+
code: 'INVALID_REQUEST',
|
|
164
|
+
message: parsed.error.issues[0]?.message ?? 'invalid query',
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const result = await snippetService.list({ projectSlug: parsed.data.projectSlug });
|
|
171
|
+
res.json(result);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
handleError(req, res, error);
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
/** GET /api/snippets/:scope/:name?projectSlug=<slug> */
|
|
178
|
+
async read(req, res) {
|
|
179
|
+
const query = refQuerySchema.safeParse(req.query);
|
|
180
|
+
if (!query.success) {
|
|
181
|
+
res.status(400).json({ error: { code: 'INVALID_REQUEST', message: 'invalid query' } });
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const ref = parseRefParams(req, res, query.data.projectSlug);
|
|
185
|
+
if (!ref)
|
|
186
|
+
return;
|
|
187
|
+
try {
|
|
188
|
+
const result = await snippetService.read(ref);
|
|
189
|
+
res.json(result);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
handleError(req, res, error);
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
/** POST /api/snippets/:scope/:name body: { content, projectSlug? } */
|
|
196
|
+
async create(req, res) {
|
|
197
|
+
const body = writeBodySchema.safeParse(req.body ?? {});
|
|
198
|
+
if (!body.success) {
|
|
199
|
+
res.status(400).json({
|
|
200
|
+
error: {
|
|
201
|
+
code: 'INVALID_REQUEST',
|
|
202
|
+
message: body.error.issues[0]?.message ?? 'invalid body',
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const ref = parseRefParams(req, res, body.data.projectSlug);
|
|
208
|
+
if (!ref)
|
|
209
|
+
return;
|
|
210
|
+
try {
|
|
211
|
+
const result = await snippetService.create(ref, { content: body.data.content });
|
|
212
|
+
await emitOriginRefresh(req);
|
|
213
|
+
res.status(201).json(result);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
handleError(req, res, error);
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
/** PUT /api/snippets/:scope/:name body: { content, expectedMtime?, projectSlug? } */
|
|
220
|
+
async update(req, res) {
|
|
221
|
+
const body = writeBodySchema.safeParse(req.body ?? {});
|
|
222
|
+
if (!body.success) {
|
|
223
|
+
res.status(400).json({
|
|
224
|
+
error: {
|
|
225
|
+
code: 'INVALID_REQUEST',
|
|
226
|
+
message: body.error.issues[0]?.message ?? 'invalid body',
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const ref = parseRefParams(req, res, body.data.projectSlug);
|
|
232
|
+
if (!ref)
|
|
233
|
+
return;
|
|
234
|
+
try {
|
|
235
|
+
const result = await snippetService.update(ref, {
|
|
236
|
+
content: body.data.content,
|
|
237
|
+
expectedMtime: body.data.expectedMtime,
|
|
238
|
+
});
|
|
239
|
+
await emitOriginRefresh(req);
|
|
240
|
+
res.json(result);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
handleError(req, res, error);
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
/** DELETE /api/snippets/:scope/:name body: { expectedMtime?, projectSlug? } */
|
|
247
|
+
async delete(req, res) {
|
|
248
|
+
const body = deleteBodySchema.safeParse(req.body ?? {});
|
|
249
|
+
if (!body.success) {
|
|
250
|
+
res.status(400).json({
|
|
251
|
+
error: {
|
|
252
|
+
code: 'INVALID_REQUEST',
|
|
253
|
+
message: body.error.issues[0]?.message ?? 'invalid body',
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const ref = parseRefParams(req, res, body.data.projectSlug);
|
|
259
|
+
if (!ref)
|
|
260
|
+
return;
|
|
261
|
+
try {
|
|
262
|
+
const result = await snippetService.delete(ref, {
|
|
263
|
+
expectedMtime: body.data.expectedMtime,
|
|
264
|
+
});
|
|
265
|
+
await emitOriginRefresh(req);
|
|
266
|
+
res.json(result);
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
handleError(req, res, error);
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
/** POST /api/snippets/copy body: SnippetCopyRequest */
|
|
273
|
+
async copy(req, res) {
|
|
274
|
+
const parsed = copyBodySchema.safeParse(req.body ?? {});
|
|
275
|
+
if (!parsed.success) {
|
|
276
|
+
res.status(400).json({
|
|
277
|
+
error: {
|
|
278
|
+
code: 'INVALID_REQUEST',
|
|
279
|
+
message: parsed.error.issues[0]?.message ?? 'invalid body',
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
const result = await snippetService.copy(parsed.data);
|
|
286
|
+
await emitOriginRefresh(req);
|
|
287
|
+
res.json(result);
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
handleError(req, res, error);
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
//# sourceMappingURL=snippetController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snippetController.js","sourceRoot":"","sources":["../../src/controllers/snippetController.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* they differ fundamentally between browser and queue paths.
|
|
7
7
|
*/
|
|
8
8
|
import type { StreamCallbacks, StreamChunk } from '@hammoc/shared';
|
|
9
|
+
import type { McpCallRecorder } from '../services/observabilityService.js';
|
|
9
10
|
export interface StreamRef {
|
|
10
11
|
sessionId: string;
|
|
11
12
|
sockets: {
|
|
@@ -36,6 +37,13 @@ export interface CallbackBuilderDeps {
|
|
|
36
37
|
getQueueProgress?: () => QueueProgress | undefined;
|
|
37
38
|
/** Story 25.11: when true, emit 'session:forked' instead of 'session:created'/'session:resumed' */
|
|
38
39
|
isFork?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Story 31.3: optional MCP-call recorder (read-only observability collection).
|
|
42
|
+
* When present, tool-use/result callbacks feed it; the body of args/results is
|
|
43
|
+
* never passed through — only sizes are persisted. Absent on paths that opt
|
|
44
|
+
* out (no behavior change when undefined).
|
|
45
|
+
*/
|
|
46
|
+
mcpRecorder?: McpCallRecorder;
|
|
39
47
|
}
|
|
40
48
|
export interface CallbackBuilderHooks {
|
|
41
49
|
/** Called after SDK resolves session ID. Browser: disk write. Queue: state update. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamCallbacks.d.ts","sourceRoot":"","sources":["../../src/handlers/streamCallbacks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EAOZ,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"streamCallbacks.d.ts","sourceRoot":"","sources":["../../src/handlers/streamCallbacks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EAOZ,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAO3E,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3C,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7F,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACrD;AAID,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,qBAAqB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACpE,mBAAmB,EAAE,eAAe,CAAC;IACrC,+FAA+F;IAC/F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mGAAmG;IACnG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,aAAa,GAAG,SAAS,CAAC;IACnD,mGAAmG;IACnG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,sFAAsF;IACtF,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,oFAAoF;IACpF,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACnD,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,eAAe,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,mBAAmB,EACzB,KAAK,CAAC,EAAE,oBAAoB,GAC3B,WAAW,CAkIb"}
|
|
@@ -54,6 +54,8 @@ export function buildStreamCallbacks(deps, hooks) {
|
|
|
54
54
|
input: toolCall.input,
|
|
55
55
|
startedAt: Date.now(),
|
|
56
56
|
});
|
|
57
|
+
// Story 31.3 — buffer start info (size only, body discarded).
|
|
58
|
+
deps.mcpRecorder?.onToolUse(toolCall.id, toolCall.name, toolCall.input);
|
|
57
59
|
},
|
|
58
60
|
onToolInputUpdate: (toolCallId, input) => {
|
|
59
61
|
activity?.('onToolInputUpdate');
|
|
@@ -63,6 +65,8 @@ export function buildStreamCallbacks(deps, hooks) {
|
|
|
63
65
|
activity?.('onToolResult');
|
|
64
66
|
log.debug(`onToolResult: id=${toolCallId}, success=${result.success}`);
|
|
65
67
|
emit('tool:result', { toolCallId, result });
|
|
68
|
+
// Story 31.3 — append the completed record (size only, body discarded).
|
|
69
|
+
deps.mcpRecorder?.onToolResult(toolCallId, result, sessionIdRef.current);
|
|
66
70
|
},
|
|
67
71
|
onCompact: (metadata) => {
|
|
68
72
|
activity?.('onCompact');
|
|
@@ -88,6 +92,8 @@ export function buildStreamCallbacks(deps, hooks) {
|
|
|
88
92
|
},
|
|
89
93
|
onResultError: (data) => {
|
|
90
94
|
emit('result:error', data);
|
|
95
|
+
// Story 31.3 — flush any orphan (started-never-returned) calls on error end.
|
|
96
|
+
deps.mcpRecorder?.onTurnEnd(sessionIdRef.current);
|
|
91
97
|
},
|
|
92
98
|
onComplete: (response) => {
|
|
93
99
|
emit('message:complete', {
|
|
@@ -104,6 +110,8 @@ export function buildStreamCallbacks(deps, hooks) {
|
|
|
104
110
|
if (notificationService.shouldNotify(stream.sockets.size)) {
|
|
105
111
|
notificationService.notifyComplete(stream.sessionId, response.content, deps.getQueueProgress?.());
|
|
106
112
|
}
|
|
113
|
+
// Story 31.3 — flush any orphan (started-never-returned) calls at turn end.
|
|
114
|
+
deps.mcpRecorder?.onTurnEnd(sessionIdRef.current);
|
|
107
115
|
},
|
|
108
116
|
// onError: intentionally omitted — callers provide their own
|
|
109
117
|
// onActivity: intentionally omitted — browser-only
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamCallbacks.js","sourceRoot":"","sources":["../../src/handlers/streamCallbacks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"streamCallbacks.js","sourceRoot":"","sources":["../../src/handlers/streamCallbacks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAgE5C,MAAM,UAAU,oBAAoB,CAClC,IAAyB,EACzB,KAA4B;IAE5B,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC5H,MAAM,QAAQ,GAAG,KAAK,EAAE,kBAAkB,CAAC;IAC3C,MAAM,YAAY,GAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAEtE,MAAM,SAAS,GAAoB;QACjC,aAAa,EAAE,CAAC,GAAW,EAAE,QAAyB,EAAE,EAAE;YACxD,GAAG,CAAC,KAAK,CAAC,wBAAwB,GAAG,YAAY,QAAQ,EAAE,KAAK,IAAI,SAAS,GAAG,CAAC,CAAC;YAClF,YAAY,CAAC,OAAO,GAAG,GAAG,CAAC;YAE3B,WAAW,CAAC,GAAG,CAAC,CAAC;YAEjB,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBAC3B,GAAG,CAAC,IAAI,CAAC,0FAA0F,CAAC,CAAC;gBACvG,CAAC;gBACD,IAAI,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,CAAC,gBAAgB,IAAI,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YACtH,CAAC;iBAAM,IAAI,UAAU,EAAE,CAAC;gBACtB,IAAI,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACvH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YACtE,CAAC;YAED,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACjC,KAAK,EAAE,mBAAmB,EAAE,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;QAED,WAAW,EAAE,CAAC,KAAkB,EAAE,EAAE;YAClC,QAAQ,EAAE,CAAC,aAAa,CAAC,CAAC;YAC1B,KAAK,EAAE,mBAAmB,EAAE,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,eAAe,EAAE;gBACpB,SAAS,EAAE,YAAY,CAAC,OAAO,IAAI,KAAK,CAAC,SAAS;gBAClD,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC,CAAC;QACL,CAAC;QAED,UAAU,EAAE,CAAC,OAAe,EAAE,EAAE;YAC9B,QAAQ,EAAE,CAAC,YAAY,CAAC,CAAC;YACzB,IAAI,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,SAAS,EAAE,CAAC,QAAyB,EAAE,EAAE;YACvC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC;YACxB,GAAG,CAAC,KAAK,CAAC,mBAAmB,QAAQ,CAAC,IAAI,QAAQ,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,WAAW,EAAE;gBAChB,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC,CAAC;YACH,8DAA8D;YAC9D,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1E,CAAC;QAED,iBAAiB,EAAE,CAAC,UAAkB,EAAE,KAA8B,EAAE,EAAE;YACxE,QAAQ,EAAE,CAAC,mBAAmB,CAAC,CAAC;YAChC,IAAI,CAAC,mBAAmB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,YAAY,EAAE,CAAC,UAAkB,EAAE,MAAkB,EAAE,EAAE;YACvD,QAAQ,EAAE,CAAC,cAAc,CAAC,CAAC;YAC3B,GAAG,CAAC,KAAK,CAAC,oBAAoB,UAAU,aAAa,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YACvE,IAAI,CAAC,aAAa,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5C,wEAAwE;YACxE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAC3E,CAAC;QAED,SAAS,EAAE,CAAC,QAAyB,EAAE,EAAE;YACvC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC;YACxB,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;QAED,cAAc,EAAE,CAAC,SAAiB,EAAE,kBAA0B,EAAE,QAAgB,EAAE,EAAE;YAClF,QAAQ,EAAE,CAAC,gBAAgB,CAAC,CAAC;YAC7B,IAAI,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,kBAAkB,EAAE,CAAC,IAA0B,EAAE,EAAE;YACjD,QAAQ,EAAE,CAAC,oBAAoB,CAAC,CAAC;YACjC,IAAI,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;QAED,gBAAgB,EAAE,CAAC,OAAe,EAAE,mBAA6B,EAAE,EAAE;YACnE,QAAQ,EAAE,CAAC,kBAAkB,CAAC,CAAC;YAC/B,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC;QAED,iBAAiB,EAAE,CAAC,eAAe,EAAE,aAAa,EAAE,EAAE;YACpD,IAAI,CAAC,kBAAkB,EAAE,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;YACtB,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAC3B,6EAA6E;YAC7E,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;QAED,UAAU,EAAE,CAAC,QAAsB,EAAE,EAAE;YACrC,IAAI,CAAC,kBAAkB,EAAE;gBACvB,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,SAAS,EAAE,YAAY,CAAC,OAAO,IAAI,QAAQ,CAAC,SAAS;gBACrD,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,KAAK,EAAE,QAAQ,CAAC,KAAK;aACtB,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACnB,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YACxC,CAAC;YAED,IAAI,mBAAmB,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1D,mBAAmB,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;YACpG,CAAC;YAED,4EAA4E;YAC5E,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;QAED,6DAA6D;QAC7D,mDAAmD;KACpD,CAAC;IAEF,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -82,6 +82,21 @@ export declare function initializeWebSocket(httpServer: HttpServer): Promise<Soc
|
|
|
82
82
|
* @returns Socket.io server instance
|
|
83
83
|
*/
|
|
84
84
|
export declare function getIO(): SocketIOServer<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>;
|
|
85
|
+
/**
|
|
86
|
+
* Story 29.2 (AC1.e Phase 1): emit a fresh `snippets:list` payload to the
|
|
87
|
+
* single socket that triggered a mutation, so the originating client's
|
|
88
|
+
* SnippetPalette / useSnippets cache picks up the new state without an
|
|
89
|
+
* explicit refresh round-trip.
|
|
90
|
+
*
|
|
91
|
+
* Phase-1 limitation: only the origin socket is notified. Other tabs / browsers
|
|
92
|
+
* connected to the same project see stale data until their next user action
|
|
93
|
+
* (panel open, page reload). The Phase-2 `project:${slug}` room fan-out is
|
|
94
|
+
* deferred until ≥ 3 user reports of multi-tab divergence.
|
|
95
|
+
*
|
|
96
|
+
* Failures are swallowed — broadcast is best-effort and must not affect the
|
|
97
|
+
* REST mutation's success/failure semantics.
|
|
98
|
+
*/
|
|
99
|
+
export declare function broadcastSnippetList(workingDirectory: string | undefined, originSocketId: string | undefined): Promise<void>;
|
|
85
100
|
/**
|
|
86
101
|
* Get the current number of connected clients
|
|
87
102
|
* @returns Number of connected clients
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/handlers/websocket.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAG7D,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EAMV,SAAS,EACV,MAAM,gBAAgB,CAAC;AAQxB,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/handlers/websocket.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,9 @@ import { preferencesService } from '../services/preferencesService.js';
|
|
|
22
22
|
import { getOrCreateQueueService, getQueueInstances } from '../controllers/queueController.js';
|
|
23
23
|
import { createLogger } from '../utils/logger.js';
|
|
24
24
|
import { clampEffortForModel, supportsAdaptiveThinking } from '../utils/effortUtils.js';
|
|
25
|
+
import { modelMissingNative1MSupport } from '../utils/bundledBinaryModelSupport.js';
|
|
25
26
|
import { buildStreamCallbacks } from './streamCallbacks.js';
|
|
27
|
+
import { createMcpCallRecorder } from '../services/observabilityService.js';
|
|
26
28
|
import { rateLimitProbeService } from '../services/rateLimitProbeService.js';
|
|
27
29
|
import { ptyService } from '../services/ptyService.js';
|
|
28
30
|
import { projectService } from '../services/projectService.js';
|
|
@@ -37,6 +39,8 @@ import { isSnippetRef, resolveSnippet, listSnippets, SnippetError } from '../uti
|
|
|
37
39
|
const log = createLogger('websocket');
|
|
38
40
|
// Alias for concise usage in guards
|
|
39
41
|
const queueInstances = getQueueInstances;
|
|
42
|
+
// Defense B: models already warned about a stale-binary 1M fallback (warn once per model per process)
|
|
43
|
+
const warnedMissing1M = new Set();
|
|
40
44
|
// Socket-to-terminal mapping: socket.id → Set of terminalIds (Story 17.1)
|
|
41
45
|
const socketTerminals = new Map();
|
|
42
46
|
// Story 20.1: Session-to-project mapping for dashboard triggers
|
|
@@ -95,6 +99,10 @@ const socketToSession = new Map();
|
|
|
95
99
|
const socketSessionRoom = new Map();
|
|
96
100
|
// Track which project room each socket joined (for leave on session switch)
|
|
97
101
|
const socketProjectRoom = new Map();
|
|
102
|
+
// Story 28.0.5: Track harness rooms each socket has subscribed to, so we can
|
|
103
|
+
// release watcher ref counts on disconnect without leaking chokidar instances.
|
|
104
|
+
// Key: socket.id → Set of "harness:user" | "harness:project:<slug>" room strings.
|
|
105
|
+
const socketHarnessRooms = new Map();
|
|
98
106
|
const chainState = new Map();
|
|
99
107
|
// Per-session drain generation counter for race guard
|
|
100
108
|
const chainDrainGeneration = new Map();
|
|
@@ -1790,6 +1798,10 @@ export async function initializeWebSocket(httpServer) {
|
|
|
1790
1798
|
socket.emit('snippets:list', { snippets: [] });
|
|
1791
1799
|
}
|
|
1792
1800
|
});
|
|
1801
|
+
// Story 29.2: re-emit `snippets:list` after a snippet CRUD so the
|
|
1802
|
+
// originating client's autocomplete surfaces stay in sync without an
|
|
1803
|
+
// explicit refresh round-trip. This is the same channel the existing
|
|
1804
|
+
// listener above answers, so consumers don't need a new event handler.
|
|
1793
1805
|
// Handle project:join/leave — room for queue event delivery (Story 15.2)
|
|
1794
1806
|
socket.on('project:join', (projectSlug) => {
|
|
1795
1807
|
socket.join(`project:${projectSlug}`);
|
|
@@ -1802,6 +1814,37 @@ export async function initializeWebSocket(httpServer) {
|
|
|
1802
1814
|
socketProjectRoom.delete(socket.id);
|
|
1803
1815
|
}
|
|
1804
1816
|
});
|
|
1817
|
+
// Story 28.0.5: Harness workbench subscription — one room per scope.
|
|
1818
|
+
socket.on('harness:subscribe', async ({ scope, projectSlug }) => {
|
|
1819
|
+
const room = scope === 'user' ? 'harness:user' : `harness:project:${projectSlug ?? ''}`;
|
|
1820
|
+
await socket.join(room);
|
|
1821
|
+
let rooms = socketHarnessRooms.get(socket.id);
|
|
1822
|
+
if (!rooms) {
|
|
1823
|
+
rooms = new Set();
|
|
1824
|
+
socketHarnessRooms.set(socket.id, rooms);
|
|
1825
|
+
}
|
|
1826
|
+
// Idempotent subscribe: increment the watcher ref count only on the
|
|
1827
|
+
// first join so disconnect cleanup matches exactly.
|
|
1828
|
+
if (!rooms.has(room)) {
|
|
1829
|
+
rooms.add(room);
|
|
1830
|
+
try {
|
|
1831
|
+
await fileWatcherService.ensureHarnessWatcher({ scope, projectSlug });
|
|
1832
|
+
}
|
|
1833
|
+
catch (err) {
|
|
1834
|
+
log.warn(`harness:subscribe watcher failed for ${room}: ${String(err)}`);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
});
|
|
1838
|
+
socket.on('harness:unsubscribe', async ({ scope, projectSlug }) => {
|
|
1839
|
+
const room = scope === 'user' ? 'harness:user' : `harness:project:${projectSlug ?? ''}`;
|
|
1840
|
+
await socket.leave(room);
|
|
1841
|
+
const rooms = socketHarnessRooms.get(socket.id);
|
|
1842
|
+
if (rooms && rooms.delete(room)) {
|
|
1843
|
+
fileWatcherService.releaseHarnessWatcher({ scope, projectSlug });
|
|
1844
|
+
if (rooms.size === 0)
|
|
1845
|
+
socketHarnessRooms.delete(socket.id);
|
|
1846
|
+
}
|
|
1847
|
+
});
|
|
1805
1848
|
// Handle queue events via WebSocket (Story 15.2)
|
|
1806
1849
|
socket.on('queue:start', async (data) => {
|
|
1807
1850
|
const { items, sessionId, projectSlug, permissionMode } = data;
|
|
@@ -2069,6 +2112,21 @@ export async function initializeWebSocket(httpServer) {
|
|
|
2069
2112
|
}
|
|
2070
2113
|
}
|
|
2071
2114
|
socketProjectRoom.delete(socket.id);
|
|
2115
|
+
// Story 28.0.5: Release any harness watcher refs held by this socket so
|
|
2116
|
+
// chokidar instances don't leak when a client drops without unsubscribing.
|
|
2117
|
+
const harnessRooms = socketHarnessRooms.get(socket.id);
|
|
2118
|
+
if (harnessRooms) {
|
|
2119
|
+
for (const room of harnessRooms) {
|
|
2120
|
+
if (room === 'harness:user') {
|
|
2121
|
+
fileWatcherService.releaseHarnessWatcher({ scope: 'user' });
|
|
2122
|
+
}
|
|
2123
|
+
else if (room.startsWith('harness:project:')) {
|
|
2124
|
+
const slug = room.slice('harness:project:'.length);
|
|
2125
|
+
fileWatcherService.releaseHarnessWatcher({ scope: 'project', projectSlug: slug });
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
socketHarnessRooms.delete(socket.id);
|
|
2129
|
+
}
|
|
2072
2130
|
// Story 25.9: Cleanup summarizing state on disconnect
|
|
2073
2131
|
const sumState = socketSummarizing.get(socket.id);
|
|
2074
2132
|
if (sumState?.abortController) {
|
|
@@ -2104,6 +2162,31 @@ export function getIO() {
|
|
|
2104
2162
|
}
|
|
2105
2163
|
return io;
|
|
2106
2164
|
}
|
|
2165
|
+
/**
|
|
2166
|
+
* Story 29.2 (AC1.e Phase 1): emit a fresh `snippets:list` payload to the
|
|
2167
|
+
* single socket that triggered a mutation, so the originating client's
|
|
2168
|
+
* SnippetPalette / useSnippets cache picks up the new state without an
|
|
2169
|
+
* explicit refresh round-trip.
|
|
2170
|
+
*
|
|
2171
|
+
* Phase-1 limitation: only the origin socket is notified. Other tabs / browsers
|
|
2172
|
+
* connected to the same project see stale data until their next user action
|
|
2173
|
+
* (panel open, page reload). The Phase-2 `project:${slug}` room fan-out is
|
|
2174
|
+
* deferred until ≥ 3 user reports of multi-tab divergence.
|
|
2175
|
+
*
|
|
2176
|
+
* Failures are swallowed — broadcast is best-effort and must not affect the
|
|
2177
|
+
* REST mutation's success/failure semantics.
|
|
2178
|
+
*/
|
|
2179
|
+
export async function broadcastSnippetList(workingDirectory, originSocketId) {
|
|
2180
|
+
if (!workingDirectory || !originSocketId || !io)
|
|
2181
|
+
return;
|
|
2182
|
+
try {
|
|
2183
|
+
const snippets = await listSnippets(workingDirectory);
|
|
2184
|
+
io.to(originSocketId).emit('snippets:list', { snippets });
|
|
2185
|
+
}
|
|
2186
|
+
catch (err) {
|
|
2187
|
+
log.warn(`broadcastSnippetList failed for socket ${originSocketId}: ${String(err)}`);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2107
2190
|
/**
|
|
2108
2191
|
* Get the current number of connected clients
|
|
2109
2192
|
* @returns Number of connected clients
|
|
@@ -2306,7 +2389,7 @@ async function handleChatSend(stream, data, abortController, lang) {
|
|
|
2306
2389
|
// Load preferences early for advanced settings + timeout
|
|
2307
2390
|
const effectivePrefs = await preferencesService.getEffectivePreferences();
|
|
2308
2391
|
const effectiveEffort = clampEffortForModel(effort ?? effectivePrefs.defaultEffort, model);
|
|
2309
|
-
// Opus 4.7 flipped `thinking.display` default to 'omitted' — ThinkingBlock UI stays blank
|
|
2392
|
+
// Opus 4.7+ flipped `thinking.display` default to 'omitted' — ThinkingBlock UI stays blank
|
|
2310
2393
|
// unless we explicitly opt in. For adaptive-thinking models, forward an explicit `thinking`
|
|
2311
2394
|
// config based on the user's showThinkingBlocks preference (Hammoc default: true).
|
|
2312
2395
|
// Legacy models (Sonnet 4.5, Opus 4.5, Haiku, Sonnet 4) keep the `maxThinkingTokens` path
|
|
@@ -2324,7 +2407,7 @@ async function handleChatSend(stream, data, abortController, lang) {
|
|
|
2324
2407
|
// Advanced settings from preferences
|
|
2325
2408
|
customSystemPrompt: effectivePrefs.customSystemPrompt,
|
|
2326
2409
|
// maxThinkingTokens: legacy path; SDK docs say it takes precedence for backward-compat,
|
|
2327
|
-
// which conflicts with adaptive mode on Opus 4.7 (rejects enabled+budget). Skip on
|
|
2410
|
+
// which conflicts with adaptive mode on Opus 4.7+ (rejects enabled+budget). Skip on
|
|
2328
2411
|
// adaptive-capable models so the explicit `thinking` field governs.
|
|
2329
2412
|
...(!adaptiveCapable && { maxThinkingTokens: effectivePrefs.maxThinkingTokens }),
|
|
2330
2413
|
...(thinkingConfig && { thinking: thinkingConfig }),
|
|
@@ -2439,6 +2522,10 @@ async function handleChatSend(stream, data, abortController, lang) {
|
|
|
2439
2522
|
rekeyStream: (sid) => rekeyStream(stream, sid),
|
|
2440
2523
|
broadcastStreamChange,
|
|
2441
2524
|
notificationService,
|
|
2525
|
+
// Story 31.3 — browser path resolves projectSlug from the working dir
|
|
2526
|
+
// (async; memoized by the recorder). append is read-only so the lazy
|
|
2527
|
+
// slug resolution cannot disrupt the stream.
|
|
2528
|
+
mcpRecorder: createMcpCallRecorder(() => projectService.findProjectByPath(workingDirectory).then((p) => p?.projectSlug)),
|
|
2442
2529
|
}, {
|
|
2443
2530
|
onCallbackActivity: (source) => resetTimeout(source),
|
|
2444
2531
|
onSessionIdResolved: (sid) => {
|
|
@@ -2532,6 +2619,20 @@ async function handleChatSend(stream, data, abortController, lang) {
|
|
|
2532
2619
|
origOnError?.(error);
|
|
2533
2620
|
};
|
|
2534
2621
|
}
|
|
2622
|
+
// Defense B: if the bundled engine doesn't recognize this native-1M model, its
|
|
2623
|
+
// 1M context silently falls back to ~200K (long sessions then compact early and
|
|
2624
|
+
// can break on resume). Warn once per model so the fallback isn't invisible.
|
|
2625
|
+
// Non-blocking: the binary scan must not delay the query.
|
|
2626
|
+
const warnModel = model;
|
|
2627
|
+
if (warnModel && !warnedMissing1M.has(warnModel)) {
|
|
2628
|
+
void modelMissingNative1MSupport(warnModel).then((missing) => {
|
|
2629
|
+
if (missing && !warnedMissing1M.has(warnModel)) {
|
|
2630
|
+
warnedMissing1M.add(warnModel);
|
|
2631
|
+
log.warn(`Bundled Claude Code engine does not recognize model "${warnModel}" — native 1M context will not apply (falls back to ~200K). Update @anthropic-ai/claude-agent-sdk.`);
|
|
2632
|
+
emit('system:info', { message: `⚠️ "${warnModel}" 1M context is not active — the bundled engine doesn't recognize this model yet, so it's limited to ~200K. Update @anthropic-ai/claude-agent-sdk to enable the full 1M window.` });
|
|
2633
|
+
}
|
|
2634
|
+
}).catch(() => { });
|
|
2635
|
+
}
|
|
2535
2636
|
try {
|
|
2536
2637
|
const sendResult = await chatService.sendMessageWithCallbacks(content, callbacks, chatOptions, canUseTool, (messageType) => {
|
|
2537
2638
|
resetTimeout(`raw:${messageType}`);
|