hammoc 1.3.0 → 1.5.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 +422 -403
- package/bin/hammoc.js +0 -6
- package/package.json +100 -93
- package/packages/client/dist/assets/agentExampleHighlight-BgwTm15v.js +1 -0
- package/packages/client/dist/assets/commandTokenHighlight-BljHwnrK.js +1 -0
- package/packages/client/dist/assets/index-CjyjnXB8.css +32 -0
- package/packages/client/dist/assets/index-D3LxqW3f.js +2 -0
- package/packages/client/dist/assets/index-NqJdhlek.js +1498 -0
- package/packages/client/dist/assets/snippetTokenHighlight-DWsaQXX0.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 +24 -24
- package/packages/server/dist/app.js.map +1 -1
- package/packages/server/dist/controllers/boardController.d.ts.map +1 -1
- package/packages/server/dist/controllers/boardController.js +0 -5
- package/packages/server/dist/controllers/boardController.js.map +1 -1
- 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/fileSystemController.d.ts +4 -0
- package/packages/server/dist/controllers/fileSystemController.d.ts.map +1 -1
- package/packages/server/dist/controllers/fileSystemController.js +20 -2
- package/packages/server/dist/controllers/fileSystemController.js.map +1 -1
- package/packages/server/dist/controllers/harnessAgentController.d.ts +28 -0
- package/packages/server/dist/controllers/harnessAgentController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessAgentController.js +339 -0
- package/packages/server/dist/controllers/harnessAgentController.js.map +1 -0
- package/packages/server/dist/controllers/harnessCommandController.d.ts +28 -0
- package/packages/server/dist/controllers/harnessCommandController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessCommandController.js +382 -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 +363 -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 +310 -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 +15 -0
- package/packages/server/dist/controllers/harnessShareScopeController.d.ts.map +1 -0
- package/packages/server/dist/controllers/harnessShareScopeController.js +73 -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/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/serverController.d.ts.map +1 -1
- package/packages/server/dist/controllers/serverController.js +84 -49
- package/packages/server/dist/controllers/serverController.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/websocket.d.ts +16 -0
- package/packages/server/dist/handlers/websocket.d.ts.map +1 -1
- package/packages/server/dist/handlers/websocket.js +221 -8
- package/packages/server/dist/handlers/websocket.js.map +1 -1
- package/packages/server/dist/index.js +66 -0
- package/packages/server/dist/index.js.map +1 -1
- package/packages/server/dist/locales/en/server.json +41 -6
- package/packages/server/dist/locales/es/server.json +3 -5
- package/packages/server/dist/locales/ja/server.json +3 -5
- package/packages/server/dist/locales/ko/server.json +4 -6
- package/packages/server/dist/locales/pt/server.json +3 -5
- package/packages/server/dist/locales/zh-CN/server.json +3 -5
- package/packages/server/dist/routes/account.d.ts +7 -0
- package/packages/server/dist/routes/account.d.ts.map +1 -0
- package/packages/server/dist/routes/account.js +35 -0
- package/packages/server/dist/routes/account.js.map +1 -0
- package/packages/server/dist/routes/debug.d.ts +1 -1
- package/packages/server/dist/routes/debug.d.ts.map +1 -1
- package/packages/server/dist/routes/debug.js +60 -1
- package/packages/server/dist/routes/debug.js.map +1 -1
- 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 +92 -0
- package/packages/server/dist/routes/harness.js.map +1 -0
- package/packages/server/dist/routes/preferences.d.ts.map +1 -1
- package/packages/server/dist/routes/preferences.js +11 -2
- package/packages/server/dist/routes/preferences.js.map +1 -1
- 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/accountInfoService.d.ts +38 -0
- package/packages/server/dist/services/accountInfoService.d.ts.map +1 -0
- package/packages/server/dist/services/accountInfoService.js +118 -0
- package/packages/server/dist/services/accountInfoService.js.map +1 -0
- package/packages/server/dist/services/bmadStatusService.d.ts +6 -2
- package/packages/server/dist/services/bmadStatusService.d.ts.map +1 -1
- package/packages/server/dist/services/bmadStatusService.js +88 -32
- 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 +36 -8
- 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/fileSystemService.d.ts +7 -1
- package/packages/server/dist/services/fileSystemService.d.ts.map +1 -1
- package/packages/server/dist/services/fileSystemService.js +67 -8
- package/packages/server/dist/services/fileSystemService.js.map +1 -1
- package/packages/server/dist/services/fileWatcherService.d.ts +59 -0
- package/packages/server/dist/services/fileWatcherService.d.ts.map +1 -0
- package/packages/server/dist/services/fileWatcherService.js +329 -0
- package/packages/server/dist/services/fileWatcherService.js.map +1 -0
- package/packages/server/dist/services/gitService.d.ts.map +1 -1
- package/packages/server/dist/services/gitService.js +67 -7
- package/packages/server/dist/services/gitService.js.map +1 -1
- package/packages/server/dist/services/harnessAgentService.d.ts +79 -0
- package/packages/server/dist/services/harnessAgentService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessAgentService.js +933 -0
- package/packages/server/dist/services/harnessAgentService.js.map +1 -0
- package/packages/server/dist/services/harnessCommandService.d.ts +60 -0
- package/packages/server/dist/services/harnessCommandService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessCommandService.js +853 -0
- package/packages/server/dist/services/harnessCommandService.js.map +1 -0
- package/packages/server/dist/services/harnessHookService.d.ts +55 -0
- package/packages/server/dist/services/harnessHookService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessHookService.js +1060 -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 +77 -0
- package/packages/server/dist/services/harnessMcpService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessMcpService.js +814 -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 +31 -0
- package/packages/server/dist/services/harnessShareScopeService.d.ts.map +1 -0
- package/packages/server/dist/services/harnessShareScopeService.js +93 -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/historyParser.d.ts +4 -14
- package/packages/server/dist/services/historyParser.d.ts.map +1 -1
- package/packages/server/dist/services/historyParser.js +60 -5
- package/packages/server/dist/services/historyParser.js.map +1 -1
- package/packages/server/dist/services/issueService.d.ts.map +1 -1
- package/packages/server/dist/services/issueService.js +10 -2
- 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/notificationService.d.ts.map +1 -1
- package/packages/server/dist/services/notificationService.js +34 -9
- package/packages/server/dist/services/notificationService.js.map +1 -1
- package/packages/server/dist/services/preferencesService.d.ts.map +1 -1
- package/packages/server/dist/services/preferencesService.js +8 -1
- package/packages/server/dist/services/preferencesService.js.map +1 -1
- package/packages/server/dist/services/projectService.d.ts +5 -0
- package/packages/server/dist/services/projectService.d.ts.map +1 -1
- package/packages/server/dist/services/projectService.js +42 -2
- package/packages/server/dist/services/projectService.js.map +1 -1
- package/packages/server/dist/services/ptyService.d.ts +1 -0
- package/packages/server/dist/services/ptyService.d.ts.map +1 -1
- package/packages/server/dist/services/ptyService.js +36 -5
- package/packages/server/dist/services/ptyService.js.map +1 -1
- package/packages/server/dist/services/queueService.d.ts.map +1 -1
- package/packages/server/dist/services/queueService.js +83 -14
- package/packages/server/dist/services/queueService.js.map +1 -1
- package/packages/server/dist/services/sessionBufferManager.d.ts.map +1 -1
- package/packages/server/dist/services/sessionBufferManager.js +26 -0
- package/packages/server/dist/services/sessionBufferManager.js.map +1 -1
- package/packages/server/dist/services/sessionService.d.ts +4 -3
- package/packages/server/dist/services/sessionService.d.ts.map +1 -1
- package/packages/server/dist/services/sessionService.js +5 -4
- 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/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/services/webPushService.d.ts.map +1 -1
- package/packages/server/dist/services/webPushService.js +8 -1
- package/packages/server/dist/services/webPushService.js.map +1 -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/effortUtils.d.ts +21 -0
- package/packages/server/dist/utils/effortUtils.d.ts.map +1 -0
- package/packages/server/dist/utils/effortUtils.js +36 -0
- package/packages/server/dist/utils/effortUtils.js.map +1 -0
- 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 +105 -0
- package/packages/server/dist/utils/harnessBundleSchema.d.ts.map +1 -0
- package/packages/server/dist/utils/harnessBundleSchema.js +79 -0
- package/packages/server/dist/utils/harnessBundleSchema.js.map +1 -0
- package/packages/server/dist/utils/harnessPaths.d.ts +34 -0
- package/packages/server/dist/utils/harnessPaths.d.ts.map +1 -0
- package/packages/server/dist/utils/harnessPaths.js +124 -0
- package/packages/server/dist/utils/harnessPaths.js.map +1 -0
- package/packages/server/dist/utils/pathUtils.d.ts +3 -2
- package/packages/server/dist/utils/pathUtils.d.ts.map +1 -1
- package/packages/server/dist/utils/pathUtils.js +26 -2
- package/packages/server/dist/utils/pathUtils.js.map +1 -1
- 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 +23 -0
- package/packages/server/resources/internals/harness-files.md +63 -0
- package/packages/server/resources/internals/image-storage.md +43 -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 +74 -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 +193 -0
- package/packages/server/resources/manual/11-bmad-method-integration.md +128 -0
- package/packages/server/resources/manual/12-harness-workbench.md +175 -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 +3 -0
- package/packages/shared/dist/index.d.ts.map +1 -1
- package/packages/shared/dist/index.js +6 -0
- package/packages/shared/dist/index.js.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/fileSystem.d.ts +19 -0
- package/packages/shared/dist/types/fileSystem.d.ts.map +1 -1
- package/packages/shared/dist/types/fileSystem.js +5 -0
- package/packages/shared/dist/types/fileSystem.js.map +1 -1
- package/packages/shared/dist/types/git.d.ts +6 -1
- package/packages/shared/dist/types/git.d.ts.map +1 -1
- package/packages/shared/dist/types/git.js.map +1 -1
- 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 +170 -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/history.d.ts +7 -0
- package/packages/shared/dist/types/history.d.ts.map +1 -1
- package/packages/shared/dist/types/preferences.d.ts +4 -1
- 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/queue.d.ts +9 -0
- package/packages/shared/dist/types/queue.d.ts.map +1 -1
- package/packages/shared/dist/types/sdk.d.ts +42 -1
- package/packages/shared/dist/types/sdk.d.ts.map +1 -1
- package/packages/shared/dist/types/sdk.js +26 -2
- package/packages/shared/dist/types/sdk.js.map +1 -1
- package/packages/shared/dist/types/websocket.d.ts +24 -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/scripts/mock-telegram.mjs +172 -0
- package/scripts/run-integration-test.mjs +362 -0
- package/packages/client/dist/assets/index-Bf0D9oVJ.css +0 -32
- package/packages/client/dist/assets/index-CRmzoqHy.js +0 -2
- package/packages/client/dist/assets/index-CszGQ29O.js +0 -1432
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 28.0.5: Harness workbench service.
|
|
3
|
+
*
|
|
4
|
+
* Domain: the project's `.claude/` subtree and the global `~/.claude/` subtree
|
|
5
|
+
* — the files that drive plugins, skills, MCP servers, hooks, commands, and
|
|
6
|
+
* subagents. Responsibilities are intentionally separated from
|
|
7
|
+
* `fileSystemService` (which serves arbitrary project files) so that path
|
|
8
|
+
* resolution, scope routing, and the structured-edit surface can evolve
|
|
9
|
+
* independently for harness consumers.
|
|
10
|
+
*
|
|
11
|
+
* Method contract surfaces (all throw typed errors from `HARNESS_ERRORS`):
|
|
12
|
+
* list — directory contents for a `.claude/` subtree
|
|
13
|
+
* read — single file read with binary detection + 1MB truncation
|
|
14
|
+
* write — raw write with expectedMtime / STALE_WRITE guard
|
|
15
|
+
* patchStructured — YAML/JSONC AST-level patch preserving comments & order
|
|
16
|
+
*/
|
|
17
|
+
import fs from 'fs/promises';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import { HARNESS_ERRORS, } from '@hammoc/shared';
|
|
20
|
+
import { resolveHarnessPath } from '../utils/harnessPaths.js';
|
|
21
|
+
import { isBinaryFile, getMimeType, MAX_FILE_SIZE } from '../utils/pathUtils.js';
|
|
22
|
+
import { applyYamlPatch, applyJsoncPatch } from '../utils/structuredEditor.js';
|
|
23
|
+
import { fileWatcherService } from './fileWatcherService.js';
|
|
24
|
+
function throwMapped(code, message, extras) {
|
|
25
|
+
const err = new Error(message);
|
|
26
|
+
err.code = code;
|
|
27
|
+
if (extras)
|
|
28
|
+
Object.assign(err, extras);
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
class HarnessService {
|
|
32
|
+
/** List entries of a harness subtree. Missing root → empty list (AC1/AC2). */
|
|
33
|
+
async list(ref) {
|
|
34
|
+
const { resolvedRoot, absolutePath } = await resolveHarnessPath(ref);
|
|
35
|
+
let stat;
|
|
36
|
+
try {
|
|
37
|
+
stat = await fs.stat(absolutePath);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
const code = error.code;
|
|
41
|
+
if (code === 'ENOENT') {
|
|
42
|
+
// Harness root (or any subdir) that has never been created yet —
|
|
43
|
+
// return an empty list instead of 404 so the UI can render an empty
|
|
44
|
+
// state without a blocking error.
|
|
45
|
+
return {
|
|
46
|
+
scope: ref.scope,
|
|
47
|
+
projectSlug: ref.projectSlug,
|
|
48
|
+
resolvedRoot,
|
|
49
|
+
path: ref.relativePath ?? '',
|
|
50
|
+
entries: [],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (code === 'EACCES') {
|
|
54
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied');
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
if (!stat.isDirectory()) {
|
|
59
|
+
throwMapped(HARNESS_ERRORS.HARNESS_NOT_A_FILE.code, 'path is not a directory');
|
|
60
|
+
}
|
|
61
|
+
const names = await fs.readdir(absolutePath);
|
|
62
|
+
const entries = [];
|
|
63
|
+
for (const name of names) {
|
|
64
|
+
try {
|
|
65
|
+
const entryPath = path.join(absolutePath, name);
|
|
66
|
+
const entryStat = await fs.stat(entryPath);
|
|
67
|
+
entries.push({
|
|
68
|
+
name,
|
|
69
|
+
type: entryStat.isDirectory() ? 'directory' : 'file',
|
|
70
|
+
size: entryStat.isDirectory() ? 0 : entryStat.size,
|
|
71
|
+
modifiedAt: entryStat.mtime.toISOString(),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Skip broken symlinks / unstat-able entries — same policy as fileSystemService.
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
scope: ref.scope,
|
|
81
|
+
projectSlug: ref.projectSlug,
|
|
82
|
+
resolvedRoot,
|
|
83
|
+
path: ref.relativePath ?? '',
|
|
84
|
+
entries,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** Read a single harness file. Binary → content:null, >1MB → truncated. */
|
|
88
|
+
async read(ref) {
|
|
89
|
+
const { absolutePath } = await resolveHarnessPath(ref);
|
|
90
|
+
let stat;
|
|
91
|
+
try {
|
|
92
|
+
stat = await fs.stat(absolutePath);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
const code = error.code;
|
|
96
|
+
if (code === 'ENOENT') {
|
|
97
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FILE_NOT_FOUND.code, 'file not found');
|
|
98
|
+
}
|
|
99
|
+
if (code === 'EACCES') {
|
|
100
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied');
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
if (!stat.isFile()) {
|
|
105
|
+
throwMapped(HARNESS_ERRORS.HARNESS_NOT_A_FILE.code, 'path is not a file');
|
|
106
|
+
}
|
|
107
|
+
const size = stat.size;
|
|
108
|
+
const mtime = stat.mtime.toISOString();
|
|
109
|
+
const mimeType = getMimeType(absolutePath);
|
|
110
|
+
const base = {
|
|
111
|
+
scope: ref.scope,
|
|
112
|
+
projectSlug: ref.projectSlug,
|
|
113
|
+
path: ref.relativePath ?? '',
|
|
114
|
+
size,
|
|
115
|
+
mtime,
|
|
116
|
+
mimeType,
|
|
117
|
+
};
|
|
118
|
+
if (size > 0) {
|
|
119
|
+
const binary = await isBinaryFile(absolutePath);
|
|
120
|
+
if (binary) {
|
|
121
|
+
return { ...base, content: null, isBinary: true, isTruncated: false };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (size > MAX_FILE_SIZE) {
|
|
125
|
+
const handle = await fs.open(absolutePath, 'r');
|
|
126
|
+
try {
|
|
127
|
+
const buffer = Buffer.alloc(MAX_FILE_SIZE);
|
|
128
|
+
await handle.read(buffer, 0, MAX_FILE_SIZE, 0);
|
|
129
|
+
return { ...base, content: buffer.toString('utf-8'), isBinary: false, isTruncated: true };
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
await handle.close();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const content = await fs.readFile(absolutePath, 'utf-8');
|
|
136
|
+
return { ...base, content, isBinary: false, isTruncated: false };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Write a harness file with optional ETag/mtime conflict check.
|
|
140
|
+
* - expectedMtime present + file exists + mtime differs → STALE_WRITE
|
|
141
|
+
* - expectedMtime present + file missing → STALE_WRITE (currentMtime: '')
|
|
142
|
+
* - expectedMtime absent → force overwrite/create
|
|
143
|
+
* - parent directory missing → HARNESS_PARENT_NOT_FOUND (no auto-mkdir)
|
|
144
|
+
*/
|
|
145
|
+
async write(ref, body) {
|
|
146
|
+
const { absolutePath } = await resolveHarnessPath(ref);
|
|
147
|
+
const parentDir = path.dirname(absolutePath);
|
|
148
|
+
try {
|
|
149
|
+
const parentStat = await fs.stat(parentDir);
|
|
150
|
+
if (!parentStat.isDirectory()) {
|
|
151
|
+
throwMapped(HARNESS_ERRORS.HARNESS_PARENT_NOT_FOUND.code, 'parent is not a directory');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
const code = error.code;
|
|
156
|
+
if (code === HARNESS_ERRORS.HARNESS_PARENT_NOT_FOUND.code)
|
|
157
|
+
throw error;
|
|
158
|
+
if (code === 'ENOENT') {
|
|
159
|
+
throwMapped(HARNESS_ERRORS.HARNESS_PARENT_NOT_FOUND.code, 'parent directory not found');
|
|
160
|
+
}
|
|
161
|
+
if (code === 'EACCES') {
|
|
162
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied on parent');
|
|
163
|
+
}
|
|
164
|
+
throwMapped(HARNESS_ERRORS.HARNESS_WRITE_ERROR.code, 'failed to stat parent directory');
|
|
165
|
+
}
|
|
166
|
+
if (body.expectedMtime !== undefined) {
|
|
167
|
+
try {
|
|
168
|
+
const existing = await fs.stat(absolutePath);
|
|
169
|
+
const currentMtime = existing.mtime.toISOString();
|
|
170
|
+
if (currentMtime !== body.expectedMtime) {
|
|
171
|
+
throwMapped(HARNESS_ERRORS.HARNESS_STALE_WRITE.code, 'file changed on disk', { currentMtime });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
const code = error.code;
|
|
176
|
+
if (code === 'ENOENT') {
|
|
177
|
+
// Caller asserted a specific mtime but the file is gone — treat as stale.
|
|
178
|
+
throwMapped(HARNESS_ERRORS.HARNESS_STALE_WRITE.code, 'file missing on disk', { currentMtime: '' });
|
|
179
|
+
}
|
|
180
|
+
if (code === HARNESS_ERRORS.HARNESS_STALE_WRITE.code)
|
|
181
|
+
throw error;
|
|
182
|
+
if (code === 'EACCES') {
|
|
183
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied');
|
|
184
|
+
}
|
|
185
|
+
// Any other stat failure: fall through and let writeFile surface it.
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
await fs.writeFile(absolutePath, body.content, 'utf-8');
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
const code = error.code;
|
|
193
|
+
if (code === 'EACCES') {
|
|
194
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied');
|
|
195
|
+
}
|
|
196
|
+
throwMapped(HARNESS_ERRORS.HARNESS_WRITE_ERROR.code, 'failed to write file');
|
|
197
|
+
}
|
|
198
|
+
const stat = await fs.stat(absolutePath);
|
|
199
|
+
// Share the existing self-write suppression map so the harness watcher
|
|
200
|
+
// (Task 7) swallows our own-write echo on the same path.
|
|
201
|
+
fileWatcherService.noteLocalWrite(absolutePath);
|
|
202
|
+
return { success: true, size: stat.size, mtime: stat.mtime.toISOString() };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Read-patch-write an AST-level edit. Running the round trip through
|
|
206
|
+
* `write` means an external mutation that sneaks in between our read and
|
|
207
|
+
* write will surface as STALE_WRITE (AC5).
|
|
208
|
+
*/
|
|
209
|
+
async patchStructured(ref, body) {
|
|
210
|
+
const current = await this.read(ref);
|
|
211
|
+
if (current.isBinary || current.content == null) {
|
|
212
|
+
throwMapped(HARNESS_ERRORS.HARNESS_PARSE_ERROR.code, 'cannot patch binary file');
|
|
213
|
+
}
|
|
214
|
+
const patched = body.format === 'yaml'
|
|
215
|
+
? applyYamlPatch(current.content, body.ops)
|
|
216
|
+
: applyJsoncPatch(current.content, body.ops);
|
|
217
|
+
const expectedMtime = body.expectedMtime ?? current.mtime;
|
|
218
|
+
return this.write(ref, { content: patched, expectedMtime });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
export const harnessService = new HarnessService();
|
|
222
|
+
//# sourceMappingURL=harnessService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harnessService.js","sourceRoot":"","sources":["../../src/services/harnessService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 30.1 (Task 2.1): share-scope evaluator.
|
|
3
|
+
*
|
|
4
|
+
* Given a project slug and a set of project-relative POSIX paths, classify
|
|
5
|
+
* each path as `shared` / `local` / `fullyIgnored` based on the project's
|
|
6
|
+
* `.gitignore`. Also derives the project-level Mode A / Mode B classification
|
|
7
|
+
* by evaluating the virtual path `.claude/settings.json` (file may not exist
|
|
8
|
+
* physically — `isIgnored()` is a pattern test, not a stat call).
|
|
9
|
+
*
|
|
10
|
+
* Single source of truth: `gitignoreFilter.loadGitignore` + `isIgnored`. No
|
|
11
|
+
* direct `.gitignore` parsing.
|
|
12
|
+
*/
|
|
13
|
+
import { type HarnessShareScopeResponse } from '@hammoc/shared';
|
|
14
|
+
export interface EvaluateShareScopeRequest {
|
|
15
|
+
projectSlug: string;
|
|
16
|
+
/** Project-relative POSIX paths. May include sibling files outside `.claude/` (e.g. `.mcp.json`). */
|
|
17
|
+
relativePaths: string[];
|
|
18
|
+
}
|
|
19
|
+
declare class HarnessShareScopeService {
|
|
20
|
+
/**
|
|
21
|
+
* Evaluate share-scope for each path + the project-level mode in one
|
|
22
|
+
* `.gitignore` load. Returns `cards: {}` if no paths were requested but
|
|
23
|
+
* still computes `mode` (so a freshly mounted workbench can render the
|
|
24
|
+
* banner before any file is asked about).
|
|
25
|
+
*/
|
|
26
|
+
evaluate(req: EvaluateShareScopeRequest): Promise<HarnessShareScopeResponse>;
|
|
27
|
+
}
|
|
28
|
+
export declare const harnessShareScopeService: HarnessShareScopeService;
|
|
29
|
+
export declare function getProjectRootForShareScope(projectSlug: string): Promise<string>;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=harnessShareScopeService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harnessShareScopeService.d.ts","sourceRoot":"","sources":["../../src/services/harnessShareScopeService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAkB,KAAK,yBAAyB,EAAmB,MAAM,gBAAgB,CAAC;AAkBjG,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,qGAAqG;IACrG,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,cAAM,wBAAwB;IAC5B;;;;;OAKG;IACG,QAAQ,CAAC,GAAG,EAAE,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC;CAqCnF;AA6BD,eAAO,MAAM,wBAAwB,0BAAiC,CAAC;AAIvE,wBAAsB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtF"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 30.1 (Task 2.1): share-scope evaluator.
|
|
3
|
+
*
|
|
4
|
+
* Given a project slug and a set of project-relative POSIX paths, classify
|
|
5
|
+
* each path as `shared` / `local` / `fullyIgnored` based on the project's
|
|
6
|
+
* `.gitignore`. Also derives the project-level Mode A / Mode B classification
|
|
7
|
+
* by evaluating the virtual path `.claude/settings.json` (file may not exist
|
|
8
|
+
* physically — `isIgnored()` is a pattern test, not a stat call).
|
|
9
|
+
*
|
|
10
|
+
* Single source of truth: `gitignoreFilter.loadGitignore` + `isIgnored`. No
|
|
11
|
+
* direct `.gitignore` parsing.
|
|
12
|
+
*/
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import { HARNESS_ERRORS } from '@hammoc/shared';
|
|
15
|
+
import { projectService } from './projectService.js';
|
|
16
|
+
import { loadGitignore, isIgnored } from '../utils/gitignoreFilter.js';
|
|
17
|
+
const CLAUDE_DIR = '.claude';
|
|
18
|
+
/**
|
|
19
|
+
* Virtual path used for Mode A/B classification. The file may not exist on
|
|
20
|
+
* disk — `isIgnored()` evaluates the pattern alone, so a brand-new project
|
|
21
|
+
* with an empty `.claude/` still gets a deterministic mode verdict.
|
|
22
|
+
*/
|
|
23
|
+
const MODE_PROBE_PATH = `${CLAUDE_DIR}/settings.json`;
|
|
24
|
+
/**
|
|
25
|
+
* Probe used to detect "directory itself ignored" patterns like `.claude/`
|
|
26
|
+
* (which auto-propagates to descendants). When the directory itself is
|
|
27
|
+
* matched, every leaf gets the `fullyIgnored` verdict.
|
|
28
|
+
*/
|
|
29
|
+
const FULL_IGNORE_PROBE_PATH = `${CLAUDE_DIR}/`;
|
|
30
|
+
class HarnessShareScopeService {
|
|
31
|
+
/**
|
|
32
|
+
* Evaluate share-scope for each path + the project-level mode in one
|
|
33
|
+
* `.gitignore` load. Returns `cards: {}` if no paths were requested but
|
|
34
|
+
* still computes `mode` (so a freshly mounted workbench can render the
|
|
35
|
+
* banner before any file is asked about).
|
|
36
|
+
*/
|
|
37
|
+
async evaluate(req) {
|
|
38
|
+
if (!req.projectSlug) {
|
|
39
|
+
const err = new Error('projectSlug is required');
|
|
40
|
+
err.code = HARNESS_ERRORS.HARNESS_ROOT_MISSING.code;
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
let projectRoot;
|
|
44
|
+
try {
|
|
45
|
+
projectRoot = await projectService.resolveOriginalPath(req.projectSlug);
|
|
46
|
+
}
|
|
47
|
+
catch (cause) {
|
|
48
|
+
const wrapped = new Error(`Unable to resolve project root for "${req.projectSlug}": ${cause.message}`);
|
|
49
|
+
wrapped.code = HARNESS_ERRORS.HARNESS_ROOT_MISSING.code;
|
|
50
|
+
throw wrapped;
|
|
51
|
+
}
|
|
52
|
+
const matcher = await loadGitignore(projectRoot);
|
|
53
|
+
// Mode A/B verdict: probe `.claude/settings.json`. The file may be missing
|
|
54
|
+
// — `isIgnored` is a pattern test that returns the same verdict either way.
|
|
55
|
+
const mode = isIgnored(matcher, MODE_PROBE_PATH) ? 'B' : 'A';
|
|
56
|
+
// When `.claude/` itself is matched, the directory's children all become
|
|
57
|
+
// `fullyIgnored` regardless of their own paths. We still evaluate each
|
|
58
|
+
// requested path individually so callers can mix in sibling files
|
|
59
|
+
// (e.g. `.mcp.json`) that escape the directory pattern.
|
|
60
|
+
const claudeDirIgnored = isIgnored(matcher, FULL_IGNORE_PROBE_PATH);
|
|
61
|
+
const cards = {};
|
|
62
|
+
for (const rel of req.relativePaths) {
|
|
63
|
+
cards[rel] = classifyPath(matcher, rel, claudeDirIgnored);
|
|
64
|
+
}
|
|
65
|
+
return { mode, cards };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function classifyPath(matcher, relativePath, claudeDirIgnored) {
|
|
69
|
+
// Normalize separators so Windows callers don't accidentally bypass `ignore`.
|
|
70
|
+
const posix = relativePath.replace(/\\/g, '/');
|
|
71
|
+
const fileIgnored = isIgnored(matcher, posix);
|
|
72
|
+
if (!fileIgnored) {
|
|
73
|
+
return 'shared';
|
|
74
|
+
}
|
|
75
|
+
// The path is ignored. If `.claude/` itself is the source of the rule, treat
|
|
76
|
+
// the verdict as the project-wide `fullyIgnored` state so Mode B projects
|
|
77
|
+
// get a coherent badge across every harness file.
|
|
78
|
+
if (claudeDirIgnored && isUnderClaudeDir(posix)) {
|
|
79
|
+
return 'fullyIgnored';
|
|
80
|
+
}
|
|
81
|
+
return 'local';
|
|
82
|
+
}
|
|
83
|
+
function isUnderClaudeDir(posixPath) {
|
|
84
|
+
return posixPath === CLAUDE_DIR || posixPath.startsWith(`${CLAUDE_DIR}/`);
|
|
85
|
+
}
|
|
86
|
+
export const harnessShareScopeService = new HarnessShareScopeService();
|
|
87
|
+
// Re-export so consumers (e.g. the .gitignore append fallback in Task 6.4)
|
|
88
|
+
// can also resolve the standard project-root path the matcher was built from.
|
|
89
|
+
export async function getProjectRootForShareScope(projectSlug) {
|
|
90
|
+
const root = await projectService.resolveOriginalPath(projectSlug);
|
|
91
|
+
return path.resolve(root);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=harnessShareScopeService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harnessShareScopeService.js","sourceRoot":"","sources":["../../src/services/harnessShareScopeService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,cAAc,EAAmD,MAAM,gBAAgB,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAEvE,MAAM,UAAU,GAAG,SAAS,CAAC;AAC7B;;;;GAIG;AACH,MAAM,eAAe,GAAG,GAAG,UAAU,gBAAgB,CAAC;AACtD;;;;GAIG;AACH,MAAM,sBAAsB,GAAG,GAAG,UAAU,GAAG,CAAC;AAQhD,MAAM,wBAAwB;IAC5B;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,GAA8B;QAC3C,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,yBAAyB,CAA0B,CAAC;YAC1E,GAAG,CAAC,IAAI,GAAG,cAAc,CAAC,oBAAoB,CAAC,IAAI,CAAC;YACpD,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,WAAmB,CAAC;QACxB,IAAI,CAAC;YACH,WAAW,GAAG,MAAM,cAAc,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,IAAI,KAAK,CACvB,uCAAuC,GAAG,CAAC,WAAW,MAAO,KAAe,CAAC,OAAO,EAAE,CAC9D,CAAC;YAC3B,OAAO,CAAC,IAAI,GAAG,cAAc,CAAC,oBAAoB,CAAC,IAAI,CAAC;YACxD,MAAM,OAAO,CAAC;QAChB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;QAEjD,2EAA2E;QAC3E,4EAA4E;QAC5E,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAE7D,yEAAyE;QACzE,uEAAuE;QACvE,kEAAkE;QAClE,wDAAwD;QACxD,MAAM,gBAAgB,GAAG,SAAS,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;QAEpE,MAAM,KAAK,GAA+B,EAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;YACpC,KAAK,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;CACF;AAED,SAAS,YAAY,CACnB,OAAe,EACf,YAAoB,EACpB,gBAAyB;IAEzB,8EAA8E;IAC9E,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAE9C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,6EAA6E;IAC7E,0EAA0E;IAC1E,kDAAkD;IAClD,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB;IACzC,OAAO,SAAS,KAAK,UAAU,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,wBAAwB,EAAE,CAAC;AAEvE,2EAA2E;AAC3E,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,WAAmB;IACnE,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 28.2: Harness skill service.
|
|
3
|
+
*
|
|
4
|
+
* Combines three sources of `<root>/skills/<name>/` directories — the active
|
|
5
|
+
* project, the user-scope home, and every installed plugin bundle — into a
|
|
6
|
+
* single card list used by the "Harness Workbench → Skills" panel. File I/O,
|
|
7
|
+
* traversal guards, STALE_WRITE detection, and binary detection are delegated
|
|
8
|
+
* to `harnessService`. The plugin source enumerates from
|
|
9
|
+
* `installed_plugins.json` and supports both in-tree (~/.claude/plugins/...)
|
|
10
|
+
* and dev-installed (out-of-tree) install paths — the latter goes through a
|
|
11
|
+
* direct `fs` read after a manual containment check so it never escapes its
|
|
12
|
+
* own `installPath`.
|
|
13
|
+
*
|
|
14
|
+
* frontmatter parsing uses the `yaml` (eemeli) parser so the round-trip story
|
|
15
|
+
* stays consistent with `structuredEditor.ts` (no `js-yaml` for harness code).
|
|
16
|
+
*/
|
|
17
|
+
import { type HarnessSkillCopyRequest, type HarnessSkillCopyResponse, type HarnessSkillListResponse, type HarnessSkillReadResponse, type HarnessSkillSourceLocation, type HarnessSkillUpdateRequest } from '@hammoc/shared';
|
|
18
|
+
declare class HarnessSkillService {
|
|
19
|
+
/**
|
|
20
|
+
* Enumerate skills across project / user / plugin sources and merge entries
|
|
21
|
+
* sharing the same directory name into a single card.
|
|
22
|
+
*/
|
|
23
|
+
listCards(currentProjectSlug?: string): Promise<HarnessSkillListResponse>;
|
|
24
|
+
/**
|
|
25
|
+
* Read a single skill's SKILL.md plus the bundle file tree. Returns the
|
|
26
|
+
* frontmatter, the body separately, the raw text (for the Raw editor) and a
|
|
27
|
+
* flat list of bundle entries with binary / truncation flags pre-resolved.
|
|
28
|
+
*/
|
|
29
|
+
readSkill(source: HarnessSkillSourceLocation): Promise<HarnessSkillReadResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Apply a frontmatter / body / raw update against an existing SKILL.md.
|
|
32
|
+
* Plugin scope is read-only — any update against a plugin source is denied
|
|
33
|
+
* with HARNESS_FORBIDDEN.
|
|
34
|
+
*/
|
|
35
|
+
updateSkill(source: HarnessSkillSourceLocation, body: HarnessSkillUpdateRequest): Promise<{
|
|
36
|
+
success: true;
|
|
37
|
+
mtime: string;
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Recursively copy a skill folder. The destination is always a project or
|
|
41
|
+
* user scope — copies *into* a plugin bundle are blocked by Zod at the
|
|
42
|
+
* controller layer, but we re-assert here as a defensive belt.
|
|
43
|
+
*/
|
|
44
|
+
copySkill(req: HarnessSkillCopyRequest): Promise<HarnessSkillCopyResponse>;
|
|
45
|
+
private enumerateProjectSkills;
|
|
46
|
+
private enumerateUserSkills;
|
|
47
|
+
private enumeratePluginSkills;
|
|
48
|
+
private collectSourceFromRoot;
|
|
49
|
+
private malformedEntry;
|
|
50
|
+
private countBundle;
|
|
51
|
+
private collectBundleEntries;
|
|
52
|
+
/**
|
|
53
|
+
* Build the harnessService path reference for an editable (project or user)
|
|
54
|
+
* source. Plugin scope is rejected by the caller before this runs.
|
|
55
|
+
*/
|
|
56
|
+
private refForEditableSource;
|
|
57
|
+
/**
|
|
58
|
+
* Apply a frontmatter form patch by routing through the YAML round-trip
|
|
59
|
+
* editor on the frontmatter block alone. Comments / quoting / key order are
|
|
60
|
+
* preserved exactly the same way `harnessService.patchStructured` would for
|
|
61
|
+
* a pure-YAML file — but since SKILL.md is a hybrid file, we run the patch
|
|
62
|
+
* on the extracted block and recompose the full text afterwards.
|
|
63
|
+
*/
|
|
64
|
+
private applyFrontmatterPatch;
|
|
65
|
+
private resolveSkillRoot;
|
|
66
|
+
private resolvePluginInstallPath;
|
|
67
|
+
}
|
|
68
|
+
export declare const harnessSkillService: HarnessSkillService;
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=harnessSkillService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harnessSkillService.d.ts","sourceRoot":"","sources":["../../src/services/harnessSkillService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAML,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAE7B,KAAK,wBAAwB,EAE7B,KAAK,wBAAwB,EAE7B,KAAK,0BAA0B,EAE/B,KAAK,yBAAyB,EAC/B,MAAM,gBAAgB,CAAC;AAmCxB,cAAM,mBAAmB;IAGvB;;;OAGG;IACG,SAAS,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA8C/E;;;;OAIG;IACG,SAAS,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAiDtF;;;;OAIG;IACG,WAAW,CACf,MAAM,EAAE,0BAA0B,EAClC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA+C5C;;;;OAIG;IACG,SAAS,CAAC,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC;YAmFlE,sBAAsB;YAsBtB,mBAAmB;YAiBnB,qBAAqB;YA0DrB,qBAAqB;IAqDnC,OAAO,CAAC,cAAc;YAeR,WAAW;YAaX,oBAAoB;IAyDlC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA2B5B;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;YAyBf,gBAAgB;YAiChB,wBAAwB;CAmBvC;AA2FD,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}
|