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,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 29.2: Snippet management service.
|
|
3
|
+
*
|
|
4
|
+
* Manages the three-scope snippet store consumed by `snippetResolver` for
|
|
5
|
+
* `%name%` chat-input expansion:
|
|
6
|
+
*
|
|
7
|
+
* - project → `<projectRoot>/.hammoc/snippets/<name>.md` (mutable)
|
|
8
|
+
* - user → `~/.hammoc/snippets/<name>.md` (mutable)
|
|
9
|
+
* - bundled → `<serverDist>/snippets/<name>[.md]` (read-only)
|
|
10
|
+
*
|
|
11
|
+
* Differences from the harness services (Epic 28):
|
|
12
|
+
* - no YAML frontmatter — body is free-form markdown
|
|
13
|
+
* - no plugin scope — `bundled` replaces it but is structurally simpler
|
|
14
|
+
* (no manifest, no installed_plugins.json lookup)
|
|
15
|
+
* - no watcher integration (Story 29.2 Phase 1) — `noteLocalWrite` is not
|
|
16
|
+
* called because snippets are NOT in the harness watcher's subscription
|
|
17
|
+
* tree (`fileWatcherService` only watches `.claude/`, never `.hammoc/`)
|
|
18
|
+
*
|
|
19
|
+
* STALE_WRITE / HARNESS_FILE_EXISTS contract mirrors `harnessService` so the
|
|
20
|
+
* client can reuse its existing conflict UX.
|
|
21
|
+
*/
|
|
22
|
+
import fs from 'node:fs/promises';
|
|
23
|
+
import path from 'node:path';
|
|
24
|
+
import { HARNESS_ERRORS, } from '@hammoc/shared';
|
|
25
|
+
import { getBundledSnippetsDir, getProjectSnippetsDir, getUserSnippetsDir, resolveSnippetPath, validateSnippetName, } from '../utils/snippetPaths.js';
|
|
26
|
+
const MAX_FILE_SIZE = 102_400; // 100KB — matches snippetResolver
|
|
27
|
+
const PREVIEW_MAX_LEN = 80;
|
|
28
|
+
function throwMapped(code, message, extras) {
|
|
29
|
+
const err = new Error(message);
|
|
30
|
+
err.code = code;
|
|
31
|
+
if (extras)
|
|
32
|
+
Object.assign(err, extras);
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Read snippet content from a path, transparently handling both `<name>.md`
|
|
37
|
+
* and the legacy extension-less `<name>` form (snippetResolver back-compat).
|
|
38
|
+
* Returns `null` when neither path exists.
|
|
39
|
+
*/
|
|
40
|
+
async function readSnippetFile(primaryPath, legacyPath) {
|
|
41
|
+
for (const candidate of [primaryPath, legacyPath]) {
|
|
42
|
+
try {
|
|
43
|
+
const stat = await fs.stat(candidate);
|
|
44
|
+
if (!stat.isFile())
|
|
45
|
+
continue;
|
|
46
|
+
const content = await fs.readFile(candidate, 'utf-8');
|
|
47
|
+
return {
|
|
48
|
+
content,
|
|
49
|
+
mtime: stat.mtime.toISOString(),
|
|
50
|
+
size: stat.size,
|
|
51
|
+
effectivePath: candidate,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const code = err.code;
|
|
56
|
+
if (code === 'ENOENT')
|
|
57
|
+
continue;
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/** Scan one root for `.md` and extension-less files, returning SnippetCard entries. */
|
|
64
|
+
async function scanSnippetDir(dir, scope) {
|
|
65
|
+
let entries;
|
|
66
|
+
try {
|
|
67
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const cards = [];
|
|
73
|
+
// Use `for await` style so we don't touch fs serially in a way that blows up
|
|
74
|
+
// on large dirs — but with awaits inside a loop the cost is bounded by the
|
|
75
|
+
// number of files; the user-facing dir is tiny.
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
if (!entry.isFile())
|
|
78
|
+
continue;
|
|
79
|
+
const rawName = entry.name;
|
|
80
|
+
const name = rawName.endsWith('.md') ? rawName.slice(0, -3) : rawName;
|
|
81
|
+
// Skip files whose stem fails NAME_RE — e.g. README.md inside the bundled dir.
|
|
82
|
+
try {
|
|
83
|
+
validateSnippetName(name);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const abs = path.join(dir, rawName);
|
|
89
|
+
let stat;
|
|
90
|
+
try {
|
|
91
|
+
stat = await fs.stat(abs);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (!stat.isFile())
|
|
97
|
+
continue;
|
|
98
|
+
let preview;
|
|
99
|
+
try {
|
|
100
|
+
const content = await fs.readFile(abs, 'utf-8');
|
|
101
|
+
const firstLine = content.split('\n').find((l) => l.trim().length > 0);
|
|
102
|
+
if (firstLine)
|
|
103
|
+
preview = firstLine.trim().slice(0, PREVIEW_MAX_LEN);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// unreadable — leave preview undefined
|
|
107
|
+
}
|
|
108
|
+
cards.push({
|
|
109
|
+
scope,
|
|
110
|
+
name,
|
|
111
|
+
preview,
|
|
112
|
+
mtime: stat.mtime.toISOString(),
|
|
113
|
+
size: stat.size,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return cards;
|
|
117
|
+
}
|
|
118
|
+
class SnippetService {
|
|
119
|
+
/**
|
|
120
|
+
* List snippets across all three scopes. Names are NOT deduplicated — the
|
|
121
|
+
* client renders one card per (scope, name) combination so users can see
|
|
122
|
+
* shadowing relationships explicitly. Resolution at runtime
|
|
123
|
+
* (snippetResolver) still applies project > user > bundled precedence.
|
|
124
|
+
*/
|
|
125
|
+
async list(opts) {
|
|
126
|
+
const tasks = [
|
|
127
|
+
scanSnippetDir(getUserSnippetsDir(), 'user'),
|
|
128
|
+
scanSnippetDir(getBundledSnippetsDir(), 'bundled'),
|
|
129
|
+
];
|
|
130
|
+
if (opts.projectSlug) {
|
|
131
|
+
tasks.push(getProjectSnippetsDir(opts.projectSlug).then((dir) => scanSnippetDir(dir, 'project')));
|
|
132
|
+
}
|
|
133
|
+
const results = await Promise.all(tasks);
|
|
134
|
+
const merged = results.flat();
|
|
135
|
+
merged.sort((a, b) => a.name.localeCompare(b.name) || a.scope.localeCompare(b.scope));
|
|
136
|
+
return { snippets: merged };
|
|
137
|
+
}
|
|
138
|
+
async read(ref) {
|
|
139
|
+
const { absolutePath, legacyAbsolutePath } = await resolveSnippetPath(ref);
|
|
140
|
+
const file = await readSnippetFile(absolutePath, legacyAbsolutePath);
|
|
141
|
+
if (!file) {
|
|
142
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FILE_NOT_FOUND.code, 'snippet not found', {
|
|
143
|
+
absolutePath,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (file.size > MAX_FILE_SIZE) {
|
|
147
|
+
// Truncate to stay consistent with snippetResolver's 100KB limit.
|
|
148
|
+
throwMapped(HARNESS_ERRORS.HARNESS_PARSE_ERROR.code, 'snippet exceeds 100KB limit');
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
scope: ref.scope,
|
|
152
|
+
name: ref.name,
|
|
153
|
+
content: file.content,
|
|
154
|
+
mtime: file.mtime,
|
|
155
|
+
size: file.size,
|
|
156
|
+
absolutePath: file.effectivePath,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/** Create a new snippet — fails with HARNESS_FILE_EXISTS when a same-named file exists. */
|
|
160
|
+
async create(ref, body) {
|
|
161
|
+
if (ref.scope === 'bundled') {
|
|
162
|
+
throwMapped(HARNESS_ERRORS.HARNESS_BUNDLED_READONLY.code, 'bundled scope is read-only');
|
|
163
|
+
}
|
|
164
|
+
const { absolutePath, legacyAbsolutePath, resolvedRoot } = await resolveSnippetPath(ref);
|
|
165
|
+
// Reject creation if either form already exists.
|
|
166
|
+
for (const candidate of [absolutePath, legacyAbsolutePath]) {
|
|
167
|
+
try {
|
|
168
|
+
const stat = await fs.stat(candidate);
|
|
169
|
+
if (stat.isFile()) {
|
|
170
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FILE_EXISTS.code, 'snippet already exists');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
const code = err.code;
|
|
175
|
+
if (code === 'ENOENT')
|
|
176
|
+
continue;
|
|
177
|
+
if (code === HARNESS_ERRORS.HARNESS_FILE_EXISTS.code)
|
|
178
|
+
throw err;
|
|
179
|
+
throw err;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
await fs.mkdir(resolvedRoot, { recursive: true });
|
|
183
|
+
await writeSnippetFile(absolutePath, body.content);
|
|
184
|
+
const stat = await fs.stat(absolutePath);
|
|
185
|
+
return { success: true, size: stat.size, mtime: stat.mtime.toISOString() };
|
|
186
|
+
}
|
|
187
|
+
/** Update an existing snippet body with optional STALE_WRITE guard. */
|
|
188
|
+
async update(ref, body) {
|
|
189
|
+
if (ref.scope === 'bundled') {
|
|
190
|
+
throwMapped(HARNESS_ERRORS.HARNESS_BUNDLED_READONLY.code, 'bundled scope is read-only');
|
|
191
|
+
}
|
|
192
|
+
const { absolutePath, legacyAbsolutePath, resolvedRoot } = await resolveSnippetPath(ref);
|
|
193
|
+
// STALE_WRITE check — try `.md` first, fall back to legacy ext-less form
|
|
194
|
+
// because the existing file may still be in the legacy layout. If neither
|
|
195
|
+
// exists, treat the write as a fresh create (no guard).
|
|
196
|
+
let targetPath = absolutePath;
|
|
197
|
+
let existing;
|
|
198
|
+
try {
|
|
199
|
+
existing = await fs.stat(absolutePath);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (err.code !== 'ENOENT')
|
|
203
|
+
throw err;
|
|
204
|
+
try {
|
|
205
|
+
existing = await fs.stat(legacyAbsolutePath);
|
|
206
|
+
targetPath = legacyAbsolutePath;
|
|
207
|
+
}
|
|
208
|
+
catch (err2) {
|
|
209
|
+
if (err2.code !== 'ENOENT')
|
|
210
|
+
throw err2;
|
|
211
|
+
// Neither exists — caller should use create(); but to keep update()
|
|
212
|
+
// forgiving we proceed and let it be created at the canonical .md path.
|
|
213
|
+
existing = undefined;
|
|
214
|
+
targetPath = absolutePath;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (body.expectedMtime !== undefined && existing) {
|
|
218
|
+
const currentMtime = existing.mtime.toISOString();
|
|
219
|
+
if (currentMtime !== body.expectedMtime) {
|
|
220
|
+
throwMapped(HARNESS_ERRORS.HARNESS_STALE_WRITE.code, 'snippet changed on disk', {
|
|
221
|
+
currentMtime,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (!existing) {
|
|
226
|
+
await fs.mkdir(resolvedRoot, { recursive: true });
|
|
227
|
+
}
|
|
228
|
+
await writeSnippetFile(targetPath, body.content);
|
|
229
|
+
const stat = await fs.stat(targetPath);
|
|
230
|
+
return { success: true, size: stat.size, mtime: stat.mtime.toISOString() };
|
|
231
|
+
}
|
|
232
|
+
async delete(ref, body) {
|
|
233
|
+
if (ref.scope === 'bundled') {
|
|
234
|
+
throwMapped(HARNESS_ERRORS.HARNESS_BUNDLED_READONLY.code, 'bundled scope is read-only');
|
|
235
|
+
}
|
|
236
|
+
const { absolutePath, legacyAbsolutePath } = await resolveSnippetPath(ref);
|
|
237
|
+
let targetPath = null;
|
|
238
|
+
let stat;
|
|
239
|
+
for (const candidate of [absolutePath, legacyAbsolutePath]) {
|
|
240
|
+
try {
|
|
241
|
+
stat = await fs.stat(candidate);
|
|
242
|
+
if (stat.isFile()) {
|
|
243
|
+
targetPath = candidate;
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
if (err.code === 'ENOENT')
|
|
249
|
+
continue;
|
|
250
|
+
throw err;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (!targetPath || !stat) {
|
|
254
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FILE_NOT_FOUND.code, 'snippet not found');
|
|
255
|
+
}
|
|
256
|
+
if (body.expectedMtime !== undefined && stat.mtime.toISOString() !== body.expectedMtime) {
|
|
257
|
+
throwMapped(HARNESS_ERRORS.HARNESS_STALE_WRITE.code, 'snippet changed on disk', {
|
|
258
|
+
currentMtime: stat.mtime.toISOString(),
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
await fs.unlink(targetPath);
|
|
262
|
+
return { success: true };
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Copy a snippet across scopes.
|
|
266
|
+
*
|
|
267
|
+
* project ↔ user → bi-directional
|
|
268
|
+
* bundled → project → one-way clone
|
|
269
|
+
* bundled → user → one-way clone
|
|
270
|
+
*
|
|
271
|
+
* `bundled` is never a target. When the target exists the call resolves
|
|
272
|
+
* according to `onConflict` (default 'abort' → HARNESS_FILE_EXISTS).
|
|
273
|
+
*/
|
|
274
|
+
async copy(req) {
|
|
275
|
+
if (req.targetScope !== 'project' && req.targetScope !== 'user') {
|
|
276
|
+
throwMapped(HARNESS_ERRORS.HARNESS_BUNDLED_READONLY.code, 'bundled cannot be a copy target');
|
|
277
|
+
}
|
|
278
|
+
if (req.sourceScope === 'project' && !req.sourceProjectSlug) {
|
|
279
|
+
throwMapped(HARNESS_ERRORS.HARNESS_ROOT_MISSING.code, 'sourceProjectSlug is required');
|
|
280
|
+
}
|
|
281
|
+
if (req.targetScope === 'project' && !req.targetProjectSlug) {
|
|
282
|
+
throwMapped(HARNESS_ERRORS.HARNESS_ROOT_MISSING.code, 'targetProjectSlug is required');
|
|
283
|
+
}
|
|
284
|
+
const sourceRef = {
|
|
285
|
+
scope: req.sourceScope,
|
|
286
|
+
projectSlug: req.sourceProjectSlug,
|
|
287
|
+
name: req.sourceName,
|
|
288
|
+
};
|
|
289
|
+
const sourceResolved = await resolveSnippetPath(sourceRef);
|
|
290
|
+
const sourceFile = await readSnippetFile(sourceResolved.absolutePath, sourceResolved.legacyAbsolutePath);
|
|
291
|
+
if (!sourceFile) {
|
|
292
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FILE_NOT_FOUND.code, 'source snippet not found');
|
|
293
|
+
}
|
|
294
|
+
const targetName = req.targetName ?? req.sourceName;
|
|
295
|
+
validateSnippetName(targetName);
|
|
296
|
+
const targetRef = {
|
|
297
|
+
scope: req.targetScope,
|
|
298
|
+
projectSlug: req.targetProjectSlug,
|
|
299
|
+
name: targetName,
|
|
300
|
+
};
|
|
301
|
+
const targetResolved = await resolveSnippetPath(targetRef);
|
|
302
|
+
// Detect target conflict (either canonical or legacy form).
|
|
303
|
+
let targetExisting = false;
|
|
304
|
+
let targetExistingPath = '';
|
|
305
|
+
for (const candidate of [
|
|
306
|
+
targetResolved.absolutePath,
|
|
307
|
+
targetResolved.legacyAbsolutePath,
|
|
308
|
+
]) {
|
|
309
|
+
try {
|
|
310
|
+
const stat = await fs.stat(candidate);
|
|
311
|
+
if (stat.isFile()) {
|
|
312
|
+
targetExisting = true;
|
|
313
|
+
targetExistingPath = candidate;
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
if (err.code === 'ENOENT')
|
|
319
|
+
continue;
|
|
320
|
+
throw err;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const onConflict = req.onConflict ?? 'abort';
|
|
324
|
+
if (targetExisting) {
|
|
325
|
+
if (onConflict === 'abort') {
|
|
326
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FILE_EXISTS.code, 'target snippet already exists');
|
|
327
|
+
}
|
|
328
|
+
if (onConflict === 'rename') {
|
|
329
|
+
// Rename mode requires a fresh targetName, which the caller is
|
|
330
|
+
// responsible for choosing. If the new name still collides, surface
|
|
331
|
+
// the same 409 — the dialog will re-prompt.
|
|
332
|
+
if (!req.targetName || req.targetName === req.sourceName) {
|
|
333
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FILE_EXISTS.code, 'rename requires a distinct targetName');
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// overwrite → fall through; we'll write to the canonical .md path so
|
|
337
|
+
// the target is always normalized to `<name>.md` even if the existing
|
|
338
|
+
// form was legacy.
|
|
339
|
+
}
|
|
340
|
+
await fs.mkdir(targetResolved.resolvedRoot, { recursive: true });
|
|
341
|
+
await writeSnippetFile(targetResolved.absolutePath, sourceFile.content);
|
|
342
|
+
// If the existing file was at the legacy path, leave it in place per the
|
|
343
|
+
// story's "no automatic rename" policy (S4 in AC1.b). The client may end
|
|
344
|
+
// up with two files (legacy + new .md) — listSnippets will show only the
|
|
345
|
+
// canonical card because scanSnippetDir dedupes by stem name.
|
|
346
|
+
void targetExistingPath;
|
|
347
|
+
return {
|
|
348
|
+
success: true,
|
|
349
|
+
target: {
|
|
350
|
+
scope: req.targetScope,
|
|
351
|
+
name: targetName,
|
|
352
|
+
absolutePath: targetResolved.absolutePath,
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/** Atomic-ish file write — `fs.writeFile` with utf-8 encoding. */
|
|
358
|
+
async function writeSnippetFile(absolutePath, content) {
|
|
359
|
+
try {
|
|
360
|
+
await fs.writeFile(absolutePath, content, 'utf-8');
|
|
361
|
+
}
|
|
362
|
+
catch (err) {
|
|
363
|
+
const code = err.code;
|
|
364
|
+
if (code === 'EACCES') {
|
|
365
|
+
throwMapped(HARNESS_ERRORS.HARNESS_FORBIDDEN.code, 'permission denied');
|
|
366
|
+
}
|
|
367
|
+
throwMapped(HARNESS_ERRORS.HARNESS_WRITE_ERROR.code, 'failed to write snippet');
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
export const snippetService = new SnippetService();
|
|
371
|
+
//# sourceMappingURL=snippetService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snippetService.js","sourceRoot":"","sources":["../../src/services/snippetService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 31.3 (Task A.3 / A.5): token attribution + exact count_tokens proxy.
|
|
3
|
+
*
|
|
4
|
+
* Two responsibilities, sharing one text-resolution path so the "exact count"
|
|
5
|
+
* input and the "approximation" input are always the same bytes (N-1):
|
|
6
|
+
*
|
|
7
|
+
* 1. listTokenAttribution(projectSlug) — enumerate the measured harness
|
|
8
|
+
* elements (project/global CLAUDE.md · each skill's SKILL.md · the
|
|
9
|
+
* Hammoc-managed context-builder injection) and report UTF-8 byte size +
|
|
10
|
+
* `approxTokens = ceil(bytes/4)` + a sha256 content hash (AC-B1 / AC-B2).
|
|
11
|
+
*
|
|
12
|
+
* 2. exactCount(projectSlug, req) — proxy the official `count_tokens` via the
|
|
13
|
+
* already-installed `@anthropic-ai/sdk` `messages.countTokens` (spike #2,
|
|
14
|
+
* §15 — no new dependency), keyed by a server-recomputed content hash
|
|
15
|
+
* (N-B: the request hash is only an optimistic hint). Failures are
|
|
16
|
+
* non-blocking (`failed: true`) so the client keeps the approximation
|
|
17
|
+
* (AC-B3.c).
|
|
18
|
+
*
|
|
19
|
+
* Enumeration REUSES existing controllers/services (claudeMdService,
|
|
20
|
+
* harnessSkillService, contextBuilderService) — no new file scanner (S-2). The
|
|
21
|
+
* context-builder injection is estimated from the Story 31.2 manifest WITHOUT
|
|
22
|
+
* executing the hook (dynamic variable / command values are placeholders).
|
|
23
|
+
*
|
|
24
|
+
* Per spike #1 (§14) the SERVER approximation tier is byte `size/4` only — the
|
|
25
|
+
* `@anthropic-ai/tokenizer` tier was NOT adopted (Task A.4 skipped).
|
|
26
|
+
*/
|
|
27
|
+
import { type TokenAttributionItem, type ExactTokenCountRequest, type ExactTokenCountResponse } from '@hammoc/shared';
|
|
28
|
+
/** ceil(bytes / 4) — the size-based heuristic (§14). */
|
|
29
|
+
export declare function approxTokensFromBytes(bytes: number): number;
|
|
30
|
+
declare class TokenCountService {
|
|
31
|
+
/** sha256(text) → token count. In-memory; persisted best-effort to disk. */
|
|
32
|
+
private cache;
|
|
33
|
+
private cacheLoaded;
|
|
34
|
+
private cacheFilePath;
|
|
35
|
+
private loadCache;
|
|
36
|
+
private persistCache;
|
|
37
|
+
/**
|
|
38
|
+
* Enumerate measured harness elements (AC-B1.a). Missing CLAUDE.md files and a
|
|
39
|
+
* disabled/empty context builder are omitted (they contribute no tokens).
|
|
40
|
+
*/
|
|
41
|
+
listTokenAttribution(projectSlug: string): Promise<TokenAttributionItem[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Exact count for one element (AC-B3). The text is re-resolved server-side and
|
|
44
|
+
* its sha256 is the AUTHORITATIVE cache key (N-B) — the request `contentHash`
|
|
45
|
+
* is only an optimistic hint. count_tokens failures return `failed: true`.
|
|
46
|
+
*/
|
|
47
|
+
exactCount(projectSlug: string, req: ExactTokenCountRequest): Promise<ExactTokenCountResponse>;
|
|
48
|
+
private makeItem;
|
|
49
|
+
/** Resolve the text used for BOTH attribution and exact-count (N-1). */
|
|
50
|
+
private resolveElementText;
|
|
51
|
+
private readClaudeMd;
|
|
52
|
+
/**
|
|
53
|
+
* Read a skill's SKILL.md, validating `elementPath` against the enumerated
|
|
54
|
+
* skills so an arbitrary client path can never be read (the path must be one
|
|
55
|
+
* the server itself vouched for in listTokenAttribution).
|
|
56
|
+
*/
|
|
57
|
+
private readSkillTextByPath;
|
|
58
|
+
/**
|
|
59
|
+
* Assemble the context-builder `additionalContext` text WITHOUT executing the
|
|
60
|
+
* hook (N-1). Reference files are read (their content dominates the size);
|
|
61
|
+
* dynamic variables / acknowledged commands contribute only their block
|
|
62
|
+
* headers with a `(dynamic)` placeholder. Mirrors the block format of
|
|
63
|
+
* `contextBuilderScriptTemplate` for the statically-knowable parts. Returns ''
|
|
64
|
+
* when the builder is disabled or empty.
|
|
65
|
+
*/
|
|
66
|
+
private assembleContextBuilderText;
|
|
67
|
+
private callCountTokens;
|
|
68
|
+
}
|
|
69
|
+
export declare const tokenCountService: TokenCountService;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=tokenCountService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenCountService.d.ts","sourceRoot":"","sources":["../../src/services/tokenCountService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAQH,OAAO,EACL,KAAK,oBAAoB,EAEzB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC7B,MAAM,gBAAgB,CAAC;AAwBxB,wDAAwD;AACxD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AA6BD,cAAM,iBAAiB;IACrB,4EAA4E;IAC5E,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,aAAa;YAIP,SAAS;YAcT,YAAY;IAU1B;;;OAGG;IACG,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAkChF;;;;OAIG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAqBpG,OAAO,CAAC,QAAQ;IAiBhB,wEAAwE;YAC1D,kBAAkB;YAqBlB,YAAY;IAW1B;;;;OAIG;YACW,mBAAmB;IAkBjC;;;;;;;OAOG;YACW,0BAA0B;YAwC1B,eAAe;CAiB9B;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
|