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.
Files changed (353) hide show
  1. package/README.md +428 -405
  2. package/bin/hammoc.js +0 -6
  3. package/package.json +100 -94
  4. package/packages/client/dist/assets/agentExampleHighlight-ltj9ce0U.js +1 -0
  5. package/packages/client/dist/assets/commandTokenHighlight-ji_ViMb4.js +1 -0
  6. package/packages/client/dist/assets/index-B-DiRGuz.js +2 -0
  7. package/packages/client/dist/assets/index-B09doO8H.js +139 -0
  8. package/packages/client/dist/assets/index-BT4RIi0U.js +1523 -0
  9. package/packages/client/dist/assets/index-DyNJ5jEW.css +32 -0
  10. package/packages/client/dist/assets/snippetTokenHighlight-CP3v4o2g.js +1 -0
  11. package/packages/client/dist/index.html +2 -2
  12. package/packages/client/dist/sw.js +1 -1
  13. package/packages/server/dist/app.d.ts.map +1 -1
  14. package/packages/server/dist/app.js +13 -21
  15. package/packages/server/dist/app.js.map +1 -1
  16. package/packages/server/dist/controllers/bmadCoreConfigController.d.ts +41 -0
  17. package/packages/server/dist/controllers/bmadCoreConfigController.d.ts.map +1 -0
  18. package/packages/server/dist/controllers/bmadCoreConfigController.js +172 -0
  19. package/packages/server/dist/controllers/bmadCoreConfigController.js.map +1 -0
  20. package/packages/server/dist/controllers/claudeMdController.d.ts +26 -0
  21. package/packages/server/dist/controllers/claudeMdController.d.ts.map +1 -0
  22. package/packages/server/dist/controllers/claudeMdController.js +158 -0
  23. package/packages/server/dist/controllers/claudeMdController.js.map +1 -0
  24. package/packages/server/dist/controllers/contextBuilderController.d.ts +43 -0
  25. package/packages/server/dist/controllers/contextBuilderController.d.ts.map +1 -0
  26. package/packages/server/dist/controllers/contextBuilderController.js +159 -0
  27. package/packages/server/dist/controllers/contextBuilderController.js.map +1 -0
  28. package/packages/server/dist/controllers/harnessAgentController.d.ts +35 -0
  29. package/packages/server/dist/controllers/harnessAgentController.d.ts.map +1 -0
  30. package/packages/server/dist/controllers/harnessAgentController.js +372 -0
  31. package/packages/server/dist/controllers/harnessAgentController.js.map +1 -0
  32. package/packages/server/dist/controllers/harnessBundleController.d.ts +37 -0
  33. package/packages/server/dist/controllers/harnessBundleController.d.ts.map +1 -0
  34. package/packages/server/dist/controllers/harnessBundleController.js +312 -0
  35. package/packages/server/dist/controllers/harnessBundleController.js.map +1 -0
  36. package/packages/server/dist/controllers/harnessCommandController.d.ts +35 -0
  37. package/packages/server/dist/controllers/harnessCommandController.d.ts.map +1 -0
  38. package/packages/server/dist/controllers/harnessCommandController.js +415 -0
  39. package/packages/server/dist/controllers/harnessCommandController.js.map +1 -0
  40. package/packages/server/dist/controllers/harnessController.d.ts +21 -0
  41. package/packages/server/dist/controllers/harnessController.d.ts.map +1 -0
  42. package/packages/server/dist/controllers/harnessController.js +176 -0
  43. package/packages/server/dist/controllers/harnessController.js.map +1 -0
  44. package/packages/server/dist/controllers/harnessHookController.d.ts +32 -0
  45. package/packages/server/dist/controllers/harnessHookController.d.ts.map +1 -0
  46. package/packages/server/dist/controllers/harnessHookController.js +406 -0
  47. package/packages/server/dist/controllers/harnessHookController.js.map +1 -0
  48. package/packages/server/dist/controllers/harnessLintController.d.ts +18 -0
  49. package/packages/server/dist/controllers/harnessLintController.d.ts.map +1 -0
  50. package/packages/server/dist/controllers/harnessLintController.js +72 -0
  51. package/packages/server/dist/controllers/harnessLintController.js.map +1 -0
  52. package/packages/server/dist/controllers/harnessMcpController.d.ts +28 -0
  53. package/packages/server/dist/controllers/harnessMcpController.d.ts.map +1 -0
  54. package/packages/server/dist/controllers/harnessMcpController.js +371 -0
  55. package/packages/server/dist/controllers/harnessMcpController.js.map +1 -0
  56. package/packages/server/dist/controllers/harnessPluginController.d.ts +17 -0
  57. package/packages/server/dist/controllers/harnessPluginController.d.ts.map +1 -0
  58. package/packages/server/dist/controllers/harnessPluginController.js +115 -0
  59. package/packages/server/dist/controllers/harnessPluginController.js.map +1 -0
  60. package/packages/server/dist/controllers/harnessShareScopeController.d.ts +24 -0
  61. package/packages/server/dist/controllers/harnessShareScopeController.d.ts.map +1 -0
  62. package/packages/server/dist/controllers/harnessShareScopeController.js +120 -0
  63. package/packages/server/dist/controllers/harnessShareScopeController.js.map +1 -0
  64. package/packages/server/dist/controllers/harnessSkillController.d.ts +32 -0
  65. package/packages/server/dist/controllers/harnessSkillController.d.ts.map +1 -0
  66. package/packages/server/dist/controllers/harnessSkillController.js +453 -0
  67. package/packages/server/dist/controllers/harnessSkillController.js.map +1 -0
  68. package/packages/server/dist/controllers/marketplaceController.d.ts +19 -0
  69. package/packages/server/dist/controllers/marketplaceController.d.ts.map +1 -0
  70. package/packages/server/dist/controllers/marketplaceController.js +74 -0
  71. package/packages/server/dist/controllers/marketplaceController.js.map +1 -0
  72. package/packages/server/dist/controllers/observabilityController.d.ts +32 -0
  73. package/packages/server/dist/controllers/observabilityController.d.ts.map +1 -0
  74. package/packages/server/dist/controllers/observabilityController.js +148 -0
  75. package/packages/server/dist/controllers/observabilityController.js.map +1 -0
  76. package/packages/server/dist/controllers/projectController.d.ts.map +1 -1
  77. package/packages/server/dist/controllers/projectController.js +11 -0
  78. package/packages/server/dist/controllers/projectController.js.map +1 -1
  79. package/packages/server/dist/controllers/snippetController.d.ts +35 -0
  80. package/packages/server/dist/controllers/snippetController.d.ts.map +1 -0
  81. package/packages/server/dist/controllers/snippetController.js +294 -0
  82. package/packages/server/dist/controllers/snippetController.js.map +1 -0
  83. package/packages/server/dist/handlers/streamCallbacks.d.ts +8 -0
  84. package/packages/server/dist/handlers/streamCallbacks.d.ts.map +1 -1
  85. package/packages/server/dist/handlers/streamCallbacks.js +8 -0
  86. package/packages/server/dist/handlers/streamCallbacks.js.map +1 -1
  87. package/packages/server/dist/handlers/websocket.d.ts +15 -0
  88. package/packages/server/dist/handlers/websocket.d.ts.map +1 -1
  89. package/packages/server/dist/handlers/websocket.js +103 -2
  90. package/packages/server/dist/handlers/websocket.js.map +1 -1
  91. package/packages/server/dist/index.js +5 -0
  92. package/packages/server/dist/index.js.map +1 -1
  93. package/packages/server/dist/locales/en/server.json +37 -4
  94. package/packages/server/dist/locales/es/server.json +0 -4
  95. package/packages/server/dist/locales/ja/server.json +0 -4
  96. package/packages/server/dist/locales/ko/server.json +0 -4
  97. package/packages/server/dist/locales/pt/server.json +0 -4
  98. package/packages/server/dist/locales/zh-CN/server.json +0 -4
  99. package/packages/server/dist/routes/harness.d.ts +8 -0
  100. package/packages/server/dist/routes/harness.d.ts.map +1 -0
  101. package/packages/server/dist/routes/harness.js +150 -0
  102. package/packages/server/dist/routes/harness.js.map +1 -0
  103. package/packages/server/dist/routes/projects.d.ts.map +1 -1
  104. package/packages/server/dist/routes/projects.js +5 -60
  105. package/packages/server/dist/routes/projects.js.map +1 -1
  106. package/packages/server/dist/routes/snippets.d.ts +14 -0
  107. package/packages/server/dist/routes/snippets.d.ts.map +1 -0
  108. package/packages/server/dist/routes/snippets.js +27 -0
  109. package/packages/server/dist/routes/snippets.js.map +1 -0
  110. package/packages/server/dist/services/bmadCoreConfigService.d.ts +86 -0
  111. package/packages/server/dist/services/bmadCoreConfigService.d.ts.map +1 -0
  112. package/packages/server/dist/services/bmadCoreConfigService.js +175 -0
  113. package/packages/server/dist/services/bmadCoreConfigService.js.map +1 -0
  114. package/packages/server/dist/services/bmadStatusService.d.ts +15 -2
  115. package/packages/server/dist/services/bmadStatusService.d.ts.map +1 -1
  116. package/packages/server/dist/services/bmadStatusService.js +146 -37
  117. package/packages/server/dist/services/bmadStatusService.js.map +1 -1
  118. package/packages/server/dist/services/chatService.d.ts +3 -0
  119. package/packages/server/dist/services/chatService.d.ts.map +1 -1
  120. package/packages/server/dist/services/chatService.js +28 -7
  121. package/packages/server/dist/services/chatService.js.map +1 -1
  122. package/packages/server/dist/services/claudeMdService.d.ts +48 -0
  123. package/packages/server/dist/services/claudeMdService.d.ts.map +1 -0
  124. package/packages/server/dist/services/claudeMdService.js +240 -0
  125. package/packages/server/dist/services/claudeMdService.js.map +1 -0
  126. package/packages/server/dist/services/commandService.d.ts +10 -0
  127. package/packages/server/dist/services/commandService.d.ts.map +1 -1
  128. package/packages/server/dist/services/commandService.js +129 -4
  129. package/packages/server/dist/services/commandService.js.map +1 -1
  130. package/packages/server/dist/services/contextBuilderScriptTemplate.d.ts +24 -0
  131. package/packages/server/dist/services/contextBuilderScriptTemplate.d.ts.map +1 -0
  132. package/packages/server/dist/services/contextBuilderScriptTemplate.js +181 -0
  133. package/packages/server/dist/services/contextBuilderScriptTemplate.js.map +1 -0
  134. package/packages/server/dist/services/contextBuilderService.d.ts +68 -0
  135. package/packages/server/dist/services/contextBuilderService.d.ts.map +1 -0
  136. package/packages/server/dist/services/contextBuilderService.js +345 -0
  137. package/packages/server/dist/services/contextBuilderService.js.map +1 -0
  138. package/packages/server/dist/services/fileWatcherService.d.ts +24 -0
  139. package/packages/server/dist/services/fileWatcherService.d.ts.map +1 -1
  140. package/packages/server/dist/services/fileWatcherService.js +232 -1
  141. package/packages/server/dist/services/fileWatcherService.js.map +1 -1
  142. package/packages/server/dist/services/harnessAgentService.d.ts +97 -0
  143. package/packages/server/dist/services/harnessAgentService.d.ts.map +1 -0
  144. package/packages/server/dist/services/harnessAgentService.js +988 -0
  145. package/packages/server/dist/services/harnessAgentService.js.map +1 -0
  146. package/packages/server/dist/services/harnessBundleService.d.ts +145 -0
  147. package/packages/server/dist/services/harnessBundleService.d.ts.map +1 -0
  148. package/packages/server/dist/services/harnessBundleService.js +1318 -0
  149. package/packages/server/dist/services/harnessBundleService.js.map +1 -0
  150. package/packages/server/dist/services/harnessCommandService.d.ts +81 -0
  151. package/packages/server/dist/services/harnessCommandService.d.ts.map +1 -0
  152. package/packages/server/dist/services/harnessCommandService.js +917 -0
  153. package/packages/server/dist/services/harnessCommandService.js.map +1 -0
  154. package/packages/server/dist/services/harnessHookService.d.ts +82 -0
  155. package/packages/server/dist/services/harnessHookService.d.ts.map +1 -0
  156. package/packages/server/dist/services/harnessHookService.js +1112 -0
  157. package/packages/server/dist/services/harnessHookService.js.map +1 -0
  158. package/packages/server/dist/services/harnessLintService.d.ts +49 -0
  159. package/packages/server/dist/services/harnessLintService.d.ts.map +1 -0
  160. package/packages/server/dist/services/harnessLintService.js +628 -0
  161. package/packages/server/dist/services/harnessLintService.js.map +1 -0
  162. package/packages/server/dist/services/harnessMcpService.d.ts +100 -0
  163. package/packages/server/dist/services/harnessMcpService.d.ts.map +1 -0
  164. package/packages/server/dist/services/harnessMcpService.js +884 -0
  165. package/packages/server/dist/services/harnessMcpService.js.map +1 -0
  166. package/packages/server/dist/services/harnessPluginService.d.ts +66 -0
  167. package/packages/server/dist/services/harnessPluginService.d.ts.map +1 -0
  168. package/packages/server/dist/services/harnessPluginService.js +559 -0
  169. package/packages/server/dist/services/harnessPluginService.js.map +1 -0
  170. package/packages/server/dist/services/harnessService.d.ts +40 -0
  171. package/packages/server/dist/services/harnessService.d.ts.map +1 -0
  172. package/packages/server/dist/services/harnessService.js +222 -0
  173. package/packages/server/dist/services/harnessService.js.map +1 -0
  174. package/packages/server/dist/services/harnessShareScopeService.d.ts +50 -0
  175. package/packages/server/dist/services/harnessShareScopeService.d.ts.map +1 -0
  176. package/packages/server/dist/services/harnessShareScopeService.js +158 -0
  177. package/packages/server/dist/services/harnessShareScopeService.js.map +1 -0
  178. package/packages/server/dist/services/harnessSkillService.d.ts +70 -0
  179. package/packages/server/dist/services/harnessSkillService.d.ts.map +1 -0
  180. package/packages/server/dist/services/harnessSkillService.js +636 -0
  181. package/packages/server/dist/services/harnessSkillService.js.map +1 -0
  182. package/packages/server/dist/services/issueService.d.ts.map +1 -1
  183. package/packages/server/dist/services/issueService.js +3 -1
  184. package/packages/server/dist/services/issueService.js.map +1 -1
  185. package/packages/server/dist/services/manualSyncService.d.ts +19 -0
  186. package/packages/server/dist/services/manualSyncService.d.ts.map +1 -0
  187. package/packages/server/dist/services/manualSyncService.js +110 -0
  188. package/packages/server/dist/services/manualSyncService.js.map +1 -0
  189. package/packages/server/dist/services/marketplaceService.d.ts +50 -0
  190. package/packages/server/dist/services/marketplaceService.d.ts.map +1 -0
  191. package/packages/server/dist/services/marketplaceService.js +326 -0
  192. package/packages/server/dist/services/marketplaceService.js.map +1 -0
  193. package/packages/server/dist/services/observabilityService.d.ts +87 -0
  194. package/packages/server/dist/services/observabilityService.d.ts.map +1 -0
  195. package/packages/server/dist/services/observabilityService.js +0 -0
  196. package/packages/server/dist/services/observabilityService.js.map +1 -0
  197. package/packages/server/dist/services/queueService.d.ts.map +1 -1
  198. package/packages/server/dist/services/queueService.js +48 -2
  199. package/packages/server/dist/services/queueService.js.map +1 -1
  200. package/packages/server/dist/services/sessionService.d.ts +16 -0
  201. package/packages/server/dist/services/sessionService.d.ts.map +1 -1
  202. package/packages/server/dist/services/sessionService.js +125 -0
  203. package/packages/server/dist/services/sessionService.js.map +1 -1
  204. package/packages/server/dist/services/snippetService.d.ts +54 -0
  205. package/packages/server/dist/services/snippetService.d.ts.map +1 -0
  206. package/packages/server/dist/services/snippetService.js +371 -0
  207. package/packages/server/dist/services/snippetService.js.map +1 -0
  208. package/packages/server/dist/services/tokenCountService.d.ts +71 -0
  209. package/packages/server/dist/services/tokenCountService.d.ts.map +1 -0
  210. package/packages/server/dist/services/tokenCountService.js +313 -0
  211. package/packages/server/dist/services/tokenCountService.js.map +1 -0
  212. package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.d.ts +46 -0
  213. package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.d.ts.map +1 -0
  214. package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.js +125 -0
  215. package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.js.map +1 -0
  216. package/packages/server/dist/snippets/apply-qa-fixes +7 -5
  217. package/packages/server/dist/snippets/qa-review +5 -1
  218. package/packages/server/dist/snippets/split-commit +9 -0
  219. package/packages/server/dist/utils/applySecretsPolicy.d.ts +53 -0
  220. package/packages/server/dist/utils/applySecretsPolicy.d.ts.map +1 -0
  221. package/packages/server/dist/utils/applySecretsPolicy.js +204 -0
  222. package/packages/server/dist/utils/applySecretsPolicy.js.map +1 -0
  223. package/packages/server/dist/utils/assertNoSecretOnShared.d.ts +40 -0
  224. package/packages/server/dist/utils/assertNoSecretOnShared.d.ts.map +1 -0
  225. package/packages/server/dist/utils/assertNoSecretOnShared.js +47 -0
  226. package/packages/server/dist/utils/assertNoSecretOnShared.js.map +1 -0
  227. package/packages/server/dist/utils/assertSafeBundlePath.d.ts +29 -0
  228. package/packages/server/dist/utils/assertSafeBundlePath.d.ts.map +1 -0
  229. package/packages/server/dist/utils/assertSafeBundlePath.js +53 -0
  230. package/packages/server/dist/utils/assertSafeBundlePath.js.map +1 -0
  231. package/packages/server/dist/utils/bundledBinaryModelSupport.d.ts +7 -0
  232. package/packages/server/dist/utils/bundledBinaryModelSupport.d.ts.map +1 -0
  233. package/packages/server/dist/utils/bundledBinaryModelSupport.js +107 -0
  234. package/packages/server/dist/utils/bundledBinaryModelSupport.js.map +1 -0
  235. package/packages/server/dist/utils/effortUtils.d.ts +2 -2
  236. package/packages/server/dist/utils/effortUtils.js +5 -5
  237. package/packages/server/dist/utils/effortUtils.js.map +1 -1
  238. package/packages/server/dist/utils/errors.d.ts +1 -0
  239. package/packages/server/dist/utils/errors.d.ts.map +1 -1
  240. package/packages/server/dist/utils/errors.js +17 -0
  241. package/packages/server/dist/utils/errors.js.map +1 -1
  242. package/packages/server/dist/utils/gitignoreFilter.d.ts +23 -0
  243. package/packages/server/dist/utils/gitignoreFilter.d.ts.map +1 -0
  244. package/packages/server/dist/utils/gitignoreFilter.js +42 -0
  245. package/packages/server/dist/utils/gitignoreFilter.js.map +1 -0
  246. package/packages/server/dist/utils/harnessBundleSchema.d.ts +107 -0
  247. package/packages/server/dist/utils/harnessBundleSchema.d.ts.map +1 -0
  248. package/packages/server/dist/utils/harnessBundleSchema.js +89 -0
  249. package/packages/server/dist/utils/harnessBundleSchema.js.map +1 -0
  250. package/packages/server/dist/utils/harnessPaths.d.ts +74 -0
  251. package/packages/server/dist/utils/harnessPaths.d.ts.map +1 -0
  252. package/packages/server/dist/utils/harnessPaths.js +247 -0
  253. package/packages/server/dist/utils/harnessPaths.js.map +1 -0
  254. package/packages/server/dist/utils/secretHeuristic.d.ts +72 -0
  255. package/packages/server/dist/utils/secretHeuristic.d.ts.map +1 -0
  256. package/packages/server/dist/utils/secretHeuristic.js +163 -0
  257. package/packages/server/dist/utils/secretHeuristic.js.map +1 -0
  258. package/packages/server/dist/utils/secretPlaceholderNamer.d.ts +41 -0
  259. package/packages/server/dist/utils/secretPlaceholderNamer.d.ts.map +1 -0
  260. package/packages/server/dist/utils/secretPlaceholderNamer.js +81 -0
  261. package/packages/server/dist/utils/secretPlaceholderNamer.js.map +1 -0
  262. package/packages/server/dist/utils/serverPathResolver.d.ts +29 -0
  263. package/packages/server/dist/utils/serverPathResolver.d.ts.map +1 -0
  264. package/packages/server/dist/utils/serverPathResolver.js +59 -0
  265. package/packages/server/dist/utils/serverPathResolver.js.map +1 -0
  266. package/packages/server/dist/utils/snippetPaths.d.ts +61 -0
  267. package/packages/server/dist/utils/snippetPaths.d.ts.map +1 -0
  268. package/packages/server/dist/utils/snippetPaths.js +123 -0
  269. package/packages/server/dist/utils/snippetPaths.js.map +1 -0
  270. package/packages/server/dist/utils/structuredEditor.d.ts +34 -0
  271. package/packages/server/dist/utils/structuredEditor.d.ts.map +1 -0
  272. package/packages/server/dist/utils/structuredEditor.js +111 -0
  273. package/packages/server/dist/utils/structuredEditor.js.map +1 -0
  274. package/packages/server/package.json +6 -2
  275. package/packages/server/resources/internals/INDEX.md +25 -0
  276. package/packages/server/resources/internals/bmad-qa-fix-marker.md +32 -0
  277. package/packages/server/resources/internals/harness-files.md +85 -0
  278. package/packages/server/resources/internals/image-storage.md +43 -0
  279. package/packages/server/resources/internals/observability-storage.md +23 -0
  280. package/packages/server/resources/manual/01-getting-started.md +104 -0
  281. package/packages/server/resources/manual/02-chat.md +285 -0
  282. package/packages/server/resources/manual/03-sessions.md +48 -0
  283. package/packages/server/resources/manual/04-slash-commands-favorites.md +152 -0
  284. package/packages/server/resources/manual/05-projects.md +76 -0
  285. package/packages/server/resources/manual/06-file-explorer-editor.md +90 -0
  286. package/packages/server/resources/manual/07-git.md +94 -0
  287. package/packages/server/resources/manual/08-terminal.md +59 -0
  288. package/packages/server/resources/manual/09-queue-runner.md +262 -0
  289. package/packages/server/resources/manual/10-project-board.md +194 -0
  290. package/packages/server/resources/manual/11-bmad-method-integration.md +130 -0
  291. package/packages/server/resources/manual/12-harness-workbench.md +256 -0
  292. package/packages/server/resources/manual/13-settings.md +241 -0
  293. package/packages/server/resources/manual/14-keyboard-shortcuts.md +68 -0
  294. package/packages/server/resources/manual/15-environment-variables.md +28 -0
  295. package/packages/server/resources/manual/16-troubleshooting.md +110 -0
  296. package/packages/server/resources/manual/INDEX.md +60 -0
  297. package/packages/shared/dist/index.d.ts +7 -0
  298. package/packages/shared/dist/index.d.ts.map +1 -1
  299. package/packages/shared/dist/index.js +14 -0
  300. package/packages/shared/dist/index.js.map +1 -1
  301. package/packages/shared/dist/types/bmadCoreConfig.d.ts +71 -0
  302. package/packages/shared/dist/types/bmadCoreConfig.d.ts.map +1 -0
  303. package/packages/shared/dist/types/bmadCoreConfig.js +30 -0
  304. package/packages/shared/dist/types/bmadCoreConfig.js.map +1 -0
  305. package/packages/shared/dist/types/bmadStatus.d.ts +10 -0
  306. package/packages/shared/dist/types/bmadStatus.d.ts.map +1 -1
  307. package/packages/shared/dist/types/bmadStatus.js.map +1 -1
  308. package/packages/shared/dist/types/board.d.ts +6 -0
  309. package/packages/shared/dist/types/board.d.ts.map +1 -1
  310. package/packages/shared/dist/types/command.d.ts +3 -3
  311. package/packages/shared/dist/types/command.d.ts.map +1 -1
  312. package/packages/shared/dist/types/contextBuilder.d.ts +102 -0
  313. package/packages/shared/dist/types/contextBuilder.d.ts.map +1 -0
  314. package/packages/shared/dist/types/contextBuilder.js +55 -0
  315. package/packages/shared/dist/types/contextBuilder.js.map +1 -0
  316. package/packages/shared/dist/types/harness.d.ts +1211 -0
  317. package/packages/shared/dist/types/harness.d.ts.map +1 -0
  318. package/packages/shared/dist/types/harness.js +107 -0
  319. package/packages/shared/dist/types/harness.js.map +1 -0
  320. package/packages/shared/dist/types/harnessBundle.d.ts +205 -0
  321. package/packages/shared/dist/types/harnessBundle.d.ts.map +1 -0
  322. package/packages/shared/dist/types/harnessBundle.js +18 -0
  323. package/packages/shared/dist/types/harnessBundle.js.map +1 -0
  324. package/packages/shared/dist/types/marketplace.d.ts +83 -0
  325. package/packages/shared/dist/types/marketplace.d.ts.map +1 -0
  326. package/packages/shared/dist/types/marketplace.js +18 -0
  327. package/packages/shared/dist/types/marketplace.js.map +1 -0
  328. package/packages/shared/dist/types/observability.d.ts +148 -0
  329. package/packages/shared/dist/types/observability.d.ts.map +1 -0
  330. package/packages/shared/dist/types/observability.js +24 -0
  331. package/packages/shared/dist/types/observability.js.map +1 -0
  332. package/packages/shared/dist/types/preferences.d.ts +4 -0
  333. package/packages/shared/dist/types/preferences.d.ts.map +1 -1
  334. package/packages/shared/dist/types/preferences.js.map +1 -1
  335. package/packages/shared/dist/types/queue.d.ts +9 -0
  336. package/packages/shared/dist/types/queue.d.ts.map +1 -1
  337. package/packages/shared/dist/types/sdk.d.ts +1 -1
  338. package/packages/shared/dist/types/sdk.d.ts.map +1 -1
  339. package/packages/shared/dist/types/sdk.js +1 -1
  340. package/packages/shared/dist/types/sdk.js.map +1 -1
  341. package/packages/shared/dist/types/websocket.d.ts +10 -0
  342. package/packages/shared/dist/types/websocket.d.ts.map +1 -1
  343. package/packages/shared/dist/utils/markdownSections.d.ts +50 -0
  344. package/packages/shared/dist/utils/markdownSections.d.ts.map +1 -0
  345. package/packages/shared/dist/utils/markdownSections.js +111 -0
  346. package/packages/shared/dist/utils/markdownSections.js.map +1 -0
  347. package/packages/shared/dist/utils/queueParser.d.ts.map +1 -1
  348. package/packages/shared/dist/utils/queueParser.js +104 -0
  349. package/packages/shared/dist/utils/queueParser.js.map +1 -1
  350. package/scripts/build-manual-shards.mjs +100 -0
  351. package/packages/client/dist/assets/index-6jREnVYd.js +0 -2
  352. package/packages/client/dist/assets/index-BFF0iqyW.css +0 -32
  353. 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"}