maestro-flow 0.4.3 → 0.4.5

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 (263) hide show
  1. package/.claude/commands/maestro-collab.md +1 -1
  2. package/.claude/commands/maestro-composer.md +1 -1
  3. package/.claude/commands/maestro-impeccable.md +1 -1
  4. package/.claude/commands/maestro-learn.md +1 -1
  5. package/.claude/commands/maestro-overlay.md +1 -1
  6. package/.claude/commands/maestro-quick.md +1 -1
  7. package/.claude/commands/maestro-ralph.md +1 -1
  8. package/.claude/commands/maestro-tools-execute.md +1 -1
  9. package/.claude/commands/maestro-tools-register.md +1 -1
  10. package/.claude/commands/maestro.md +1 -1
  11. package/.claude/commands/manage-issue-discover.md +1 -1
  12. package/.claude/commands/manage-issue.md +1 -1
  13. package/.claude/commands/manage-knowhow-capture.md +3 -1
  14. package/.claude/commands/manage-knowhow.md +1 -1
  15. package/.claude/commands/manage-learn.md +1 -1
  16. package/.claude/commands/manage-status.md +1 -0
  17. package/.claude/commands/manage-wiki.md +1 -1
  18. package/.claude/commands/quality-auto-test.md +1 -2
  19. package/.claude/commands/quality-refactor.md +1 -1
  20. package/.claude/commands/quality-test.md +5 -0
  21. package/.claude/commands/security-audit.md +1 -0
  22. package/.claude/commands/spec-add.md +6 -3
  23. package/.claude/commands/spec-setup.md +0 -3
  24. package/dashboard/dist/assets/{ArtifactsPage-iJZtYsmR.js → ArtifactsPage-CVh0Z2I2.js} +3 -3
  25. package/dashboard/dist/assets/{ChatInput-DNnDLdQF.js → ChatInput-CBI3qHQQ.js} +2 -2
  26. package/dashboard/dist/assets/ChatPage-BjJ9CYox.js +22 -0
  27. package/dashboard/dist/assets/CollabPage-CprGGO9y.js +1 -0
  28. package/dashboard/dist/assets/{ExecutionPanel-BKV3GZ7Q.js → ExecutionPanel-CClxD7cH.js} +1 -1
  29. package/dashboard/dist/assets/KanbanPage-copqjdPg.js +16 -0
  30. package/dashboard/dist/assets/MaestroCoordinatePage-CioZjQ9N.js +4 -0
  31. package/dashboard/dist/assets/{MarkdownRenderer-cYFfe1uX.js → MarkdownRenderer-CtUhoxCT.js} +1 -1
  32. package/dashboard/dist/assets/McpPage-BcPPcJpr.js +21 -0
  33. package/dashboard/dist/assets/{MeetingRoomPage-wnvT7wlB.js → MeetingRoomPage-BgmAKxU-.js} +1 -1
  34. package/dashboard/dist/assets/{OutputPanel-DDL90Idy.js → OutputPanel-DgT3gMyp.js} +1 -1
  35. package/dashboard/dist/assets/{ProblemsPanel-zFN9IIs0.js → ProblemsPanel-BmG7rxoG.js} +1 -1
  36. package/dashboard/dist/assets/{RequirementBoardPage-DOPJoT0I.js → RequirementBoardPage-k8YoeQ0r.js} +1 -1
  37. package/dashboard/dist/assets/{RequirementPage-CEVquRgM.js → RequirementPage-Da2354px.js} +1 -1
  38. package/dashboard/dist/assets/{RoomsPage-D5USEWDh.js → RoomsPage-BtqDiYaU.js} +1 -1
  39. package/dashboard/dist/assets/SpecsPage-ByPVH_M3.js +36 -0
  40. package/dashboard/dist/assets/{TeamsPage-DlcEmr_Q.js → TeamsPage-sFDLN30L.js} +1 -1
  41. package/dashboard/dist/assets/{TreeBrowser-Y48Wz-QY.js → TreeBrowser-oEx8YJXV.js} +1 -1
  42. package/dashboard/dist/assets/WorkflowPage-JrX7CVHh.js +6 -0
  43. package/dashboard/dist/assets/{arrow-left-NCUOENvg.js → arrow-left-DYvgSdIH.js} +1 -1
  44. package/dashboard/dist/assets/{check-o7nfGNHf.js → check-jcgYBWVR.js} +1 -1
  45. package/dashboard/dist/assets/{chevron-right-BXySK2fn.js → chevron-right-DvZ5sMOg.js} +1 -1
  46. package/dashboard/dist/assets/{circle-cooAwnAR.js → circle-DYT-zoRZ.js} +1 -1
  47. package/dashboard/dist/assets/{circle-alert-DcSBokh4.js → circle-alert-Bfbv3gt4.js} +1 -1
  48. package/dashboard/dist/assets/{circle-check-Cd-jce4j.js → circle-check-D82WnpbI.js} +1 -1
  49. package/dashboard/dist/assets/{circle-check-big-BN7Mdp4i.js → circle-check-big-CPVD1GKF.js} +1 -1
  50. package/dashboard/dist/assets/{code-BQa9oL1n.js → code-B3bKFGI4.js} +1 -1
  51. package/dashboard/dist/assets/{columns-3-BzgxelGx.js → columns-3-BeMAQCix.js} +1 -1
  52. package/dashboard/dist/assets/{download-swRJnate.js → download-BCtpoWYB.js} +1 -1
  53. package/dashboard/dist/assets/en-2h6fD0j8.js +1 -0
  54. package/dashboard/dist/assets/{folder-DbGbLNFN.js → folder-CTj6SNNu.js} +1 -1
  55. package/dashboard/dist/assets/index-6-yE5Yl9.css +1 -0
  56. package/dashboard/dist/assets/{index-DIoMBMbv.js → index-BxR_3IbJ.js} +1 -1
  57. package/dashboard/dist/assets/{index-DLBN_7fb.js → index-CWBJLu42.js} +1 -1
  58. package/dashboard/dist/assets/index-DpcPd-UG.js +236 -0
  59. package/dashboard/dist/assets/{list-BTRAIvDq.js → list-BMv8pIQn.js} +1 -1
  60. package/dashboard/dist/assets/{loader-NHtB6Mdn.js → loader-DdM4VOgF.js} +1 -1
  61. package/dashboard/dist/assets/{minus-BjMxRTET.js → minus-D15s2E__.js} +1 -1
  62. package/dashboard/dist/assets/{pen-line-C4_O16H0.js → pen-line-DO6o4xWz.js} +1 -1
  63. package/dashboard/dist/assets/{pencil-DTmKhyDY.js → pencil-qGxg9jOe.js} +1 -1
  64. package/dashboard/dist/assets/{proxy-Dtx5p6IO.js → proxy-DOffTzwA.js} +1 -1
  65. package/dashboard/dist/assets/refresh-cw-C9UNdLCy.js +6 -0
  66. package/dashboard/dist/assets/{rows-2-GR1dZtRu.js → rows-2-CifAA5SL.js} +1 -1
  67. package/dashboard/dist/assets/{search-DVtgy2W7.js → search-pe7pU1YN.js} +1 -1
  68. package/dashboard/dist/assets/{shallow-BOmvDNsv.js → shallow-r7YynQYA.js} +1 -1
  69. package/dashboard/dist/assets/table-Bh772iIw.js +6 -0
  70. package/dashboard/dist/assets/{team-types-BPeOvVdA.js → team-types-C_HqX2p2.js} +1 -1
  71. package/dashboard/dist/assets/{terminal-CzogW4cl.js → terminal-EpmtGBlw.js} +1 -1
  72. package/dashboard/dist/assets/{trash-2-52LATVfW.js → trash-2-Xen46iNQ.js} +1 -1
  73. package/dashboard/dist/assets/{users-DLFE2voE.js → users-BLueDPxF.js} +1 -1
  74. package/dashboard/dist/assets/{zap-DhiYlgyZ.js → zap-DsQCPF61.js} +1 -1
  75. package/dashboard/dist/assets/zh-CN-r3AvxxOL.js +1 -0
  76. package/dashboard/dist/index.html +2 -2
  77. package/dashboard/dist-server/dashboard/src/server/routes/settings.js +70 -1
  78. package/dashboard/dist-server/dashboard/src/server/routes/settings.js.map +1 -1
  79. package/dashboard/dist-server/src/types/index.d.ts +48 -6
  80. package/dist/src/commands/coordinate.d.ts.map +1 -1
  81. package/dist/src/commands/coordinate.js +2 -0
  82. package/dist/src/commands/coordinate.js.map +1 -1
  83. package/dist/src/commands/hooks.d.ts.map +1 -1
  84. package/dist/src/commands/hooks.js +201 -6
  85. package/dist/src/commands/hooks.js.map +1 -1
  86. package/dist/src/commands/spec.d.ts.map +1 -1
  87. package/dist/src/commands/spec.js +466 -0
  88. package/dist/src/commands/spec.js.map +1 -1
  89. package/dist/src/config/index.d.ts +5 -1
  90. package/dist/src/config/index.d.ts.map +1 -1
  91. package/dist/src/config/index.js +42 -0
  92. package/dist/src/config/index.js.map +1 -1
  93. package/dist/src/hooks/keyword-spec-injector.d.ts.map +1 -1
  94. package/dist/src/hooks/keyword-spec-injector.js +106 -10
  95. package/dist/src/hooks/keyword-spec-injector.js.map +1 -1
  96. package/dist/src/hooks/plugins/spec-analytics-plugin.d.ts +13 -0
  97. package/dist/src/hooks/plugins/spec-analytics-plugin.d.ts.map +1 -0
  98. package/dist/src/hooks/plugins/spec-analytics-plugin.js +92 -0
  99. package/dist/src/hooks/plugins/spec-analytics-plugin.js.map +1 -0
  100. package/dist/src/hooks/plugins/spec-injection-plugin.d.ts.map +1 -1
  101. package/dist/src/hooks/plugins/spec-injection-plugin.js +57 -4
  102. package/dist/src/hooks/plugins/spec-injection-plugin.js.map +1 -1
  103. package/dist/src/hooks/spec-analytics.d.ts +128 -0
  104. package/dist/src/hooks/spec-analytics.d.ts.map +1 -0
  105. package/dist/src/hooks/spec-analytics.js +311 -0
  106. package/dist/src/hooks/spec-analytics.js.map +1 -0
  107. package/dist/src/hooks/spec-injector.d.ts.map +1 -1
  108. package/dist/src/hooks/spec-injector.js +140 -6
  109. package/dist/src/hooks/spec-injector.js.map +1 -1
  110. package/dist/src/tools/spec-keyword-index.d.ts.map +1 -1
  111. package/dist/src/tools/spec-keyword-index.js +23 -6
  112. package/dist/src/tools/spec-keyword-index.js.map +1 -1
  113. package/dist/src/tools/spec-loader.d.ts +20 -0
  114. package/dist/src/tools/spec-loader.d.ts.map +1 -1
  115. package/dist/src/tools/spec-loader.js +58 -7
  116. package/dist/src/tools/spec-loader.js.map +1 -1
  117. package/dist/src/tools/store-knowhow.d.ts.map +1 -1
  118. package/dist/src/tools/store-knowhow.js +26 -1
  119. package/dist/src/tools/store-knowhow.js.map +1 -1
  120. package/dist/src/tui/config-ui/ConfigHub.d.ts +1 -1
  121. package/dist/src/tui/config-ui/ConfigHub.d.ts.map +1 -1
  122. package/dist/src/tui/config-ui/ConfigHub.js +16 -10
  123. package/dist/src/tui/config-ui/ConfigHub.js.map +1 -1
  124. package/dist/src/tui/config-ui/ConfigSourcesView.d.ts.map +1 -1
  125. package/dist/src/tui/config-ui/ConfigSourcesView.js +3 -2
  126. package/dist/src/tui/config-ui/ConfigSourcesView.js.map +1 -1
  127. package/dist/src/tui/config-ui/HooksPanel.d.ts.map +1 -1
  128. package/dist/src/tui/config-ui/HooksPanel.js +15 -19
  129. package/dist/src/tui/config-ui/HooksPanel.js.map +1 -1
  130. package/dist/src/tui/config-ui/SkillConfigDashboard.d.ts.map +1 -1
  131. package/dist/src/tui/config-ui/SkillConfigDashboard.js +5 -9
  132. package/dist/src/tui/config-ui/SkillConfigDashboard.js.map +1 -1
  133. package/dist/src/tui/config-ui/SkillParamEditor.d.ts.map +1 -1
  134. package/dist/src/tui/config-ui/SkillParamEditor.js +1 -3
  135. package/dist/src/tui/config-ui/SkillParamEditor.js.map +1 -1
  136. package/dist/src/tui/config-ui/SkillsList.d.ts.map +1 -1
  137. package/dist/src/tui/config-ui/SkillsList.js +7 -9
  138. package/dist/src/tui/config-ui/SkillsList.js.map +1 -1
  139. package/dist/src/tui/config-ui/SpecAnalyticsPanel.d.ts +6 -0
  140. package/dist/src/tui/config-ui/SpecAnalyticsPanel.d.ts.map +1 -0
  141. package/dist/src/tui/config-ui/SpecAnalyticsPanel.js +164 -0
  142. package/dist/src/tui/config-ui/SpecAnalyticsPanel.js.map +1 -0
  143. package/dist/src/tui/config-ui/SpecPanel.d.ts.map +1 -1
  144. package/dist/src/tui/config-ui/SpecPanel.js +918 -20
  145. package/dist/src/tui/config-ui/SpecPanel.js.map +1 -1
  146. package/dist/src/tui/config-ui/index.d.ts +3 -1
  147. package/dist/src/tui/config-ui/index.d.ts.map +1 -1
  148. package/dist/src/tui/config-ui/index.js +4 -0
  149. package/dist/src/tui/config-ui/index.js.map +1 -1
  150. package/dist/src/tui/install-ui/BackupConfig.d.ts.map +1 -1
  151. package/dist/src/tui/install-ui/BackupConfig.js +3 -2
  152. package/dist/src/tui/install-ui/BackupConfig.js.map +1 -1
  153. package/dist/src/tui/install-ui/BlueprintPreview.d.ts.map +1 -1
  154. package/dist/src/tui/install-ui/BlueprintPreview.js +7 -6
  155. package/dist/src/tui/install-ui/BlueprintPreview.js.map +1 -1
  156. package/dist/src/tui/install-ui/ComponentGrid.d.ts.map +1 -1
  157. package/dist/src/tui/install-ui/ComponentGrid.js +3 -2
  158. package/dist/src/tui/install-ui/ComponentGrid.js.map +1 -1
  159. package/dist/src/tui/install-ui/ConfigPanel.d.ts.map +1 -1
  160. package/dist/src/tui/install-ui/ConfigPanel.js +4 -3
  161. package/dist/src/tui/install-ui/ConfigPanel.js.map +1 -1
  162. package/dist/src/tui/install-ui/CyberItem.d.ts.map +1 -1
  163. package/dist/src/tui/install-ui/CyberItem.js +7 -6
  164. package/dist/src/tui/install-ui/CyberItem.js.map +1 -1
  165. package/dist/src/tui/install-ui/CyberdeckBlueprint.d.ts.map +1 -1
  166. package/dist/src/tui/install-ui/CyberdeckBlueprint.js +2 -1
  167. package/dist/src/tui/install-ui/CyberdeckBlueprint.js.map +1 -1
  168. package/dist/src/tui/install-ui/ExecutionView.d.ts.map +1 -1
  169. package/dist/src/tui/install-ui/ExecutionView.js +3 -2
  170. package/dist/src/tui/install-ui/ExecutionView.js.map +1 -1
  171. package/dist/src/tui/install-ui/GradientHeader.d.ts.map +1 -1
  172. package/dist/src/tui/install-ui/GradientHeader.js +2 -1
  173. package/dist/src/tui/install-ui/GradientHeader.js.map +1 -1
  174. package/dist/src/tui/install-ui/HooksConfig.d.ts.map +1 -1
  175. package/dist/src/tui/install-ui/HooksConfig.js +8 -8
  176. package/dist/src/tui/install-ui/HooksConfig.js.map +1 -1
  177. package/dist/src/tui/install-ui/InstallConfirm.d.ts.map +1 -1
  178. package/dist/src/tui/install-ui/InstallConfirm.js +4 -3
  179. package/dist/src/tui/install-ui/InstallConfirm.js.map +1 -1
  180. package/dist/src/tui/install-ui/InstallExecution.d.ts.map +1 -1
  181. package/dist/src/tui/install-ui/InstallExecution.js +3 -2
  182. package/dist/src/tui/install-ui/InstallExecution.js.map +1 -1
  183. package/dist/src/tui/install-ui/InstallFlow.d.ts.map +1 -1
  184. package/dist/src/tui/install-ui/InstallFlow.js +3 -2
  185. package/dist/src/tui/install-ui/InstallFlow.js.map +1 -1
  186. package/dist/src/tui/install-ui/InstallHub.d.ts.map +1 -1
  187. package/dist/src/tui/install-ui/InstallHub.js +9 -8
  188. package/dist/src/tui/install-ui/InstallHub.js.map +1 -1
  189. package/dist/src/tui/install-ui/InstallResult.d.ts.map +1 -1
  190. package/dist/src/tui/install-ui/InstallResult.js +3 -2
  191. package/dist/src/tui/install-ui/InstallResult.js.map +1 -1
  192. package/dist/src/tui/install-ui/McpConfig.d.ts.map +1 -1
  193. package/dist/src/tui/install-ui/McpConfig.js +4 -3
  194. package/dist/src/tui/install-ui/McpConfig.js.map +1 -1
  195. package/dist/src/tui/install-ui/ResultDashboard.d.ts.map +1 -1
  196. package/dist/src/tui/install-ui/ResultDashboard.js +3 -2
  197. package/dist/src/tui/install-ui/ResultDashboard.js.map +1 -1
  198. package/dist/src/tui/install-ui/ReviewPanel.d.ts.map +1 -1
  199. package/dist/src/tui/install-ui/ReviewPanel.js +2 -1
  200. package/dist/src/tui/install-ui/ReviewPanel.js.map +1 -1
  201. package/dist/src/tui/install-ui/StatuslineConfig.d.ts.map +1 -1
  202. package/dist/src/tui/install-ui/StatuslineConfig.js +3 -2
  203. package/dist/src/tui/install-ui/StatuslineConfig.js.map +1 -1
  204. package/dist/src/tui/install-ui/StepSelector.d.ts.map +1 -1
  205. package/dist/src/tui/install-ui/StepSelector.js +11 -10
  206. package/dist/src/tui/install-ui/StepSelector.js.map +1 -1
  207. package/dist/src/tui/overlay-ui/OverlayList.d.ts.map +1 -1
  208. package/dist/src/tui/overlay-ui/OverlayList.js +8 -12
  209. package/dist/src/tui/overlay-ui/OverlayList.js.map +1 -1
  210. package/dist/src/tui/shared/components.d.ts +56 -0
  211. package/dist/src/tui/shared/components.d.ts.map +1 -0
  212. package/dist/src/tui/shared/components.js +55 -0
  213. package/dist/src/tui/shared/components.js.map +1 -0
  214. package/dist/src/tui/shared/helpers.d.ts +24 -0
  215. package/dist/src/tui/shared/helpers.d.ts.map +1 -0
  216. package/dist/src/tui/shared/helpers.js +49 -0
  217. package/dist/src/tui/shared/helpers.js.map +1 -0
  218. package/dist/src/tui/shared/index.d.ts +4 -0
  219. package/dist/src/tui/shared/index.d.ts.map +1 -0
  220. package/dist/src/tui/shared/index.js +7 -0
  221. package/dist/src/tui/shared/index.js.map +1 -0
  222. package/dist/src/tui/shared/tokens.d.ts +79 -0
  223. package/dist/src/tui/shared/tokens.d.ts.map +1 -0
  224. package/dist/src/tui/shared/tokens.js +81 -0
  225. package/dist/src/tui/shared/tokens.js.map +1 -0
  226. package/dist/src/tui/tools-ui/CommandReference.d.ts.map +1 -1
  227. package/dist/src/tui/tools-ui/CommandReference.js +2 -4
  228. package/dist/src/tui/tools-ui/CommandReference.js.map +1 -1
  229. package/dist/src/tui/tools-ui/ConfigSources.d.ts.map +1 -1
  230. package/dist/src/tui/tools-ui/ConfigSources.js +3 -2
  231. package/dist/src/tui/tools-ui/ConfigSources.js.map +1 -1
  232. package/dist/src/tui/tools-ui/RegisterSettings.d.ts.map +1 -1
  233. package/dist/src/tui/tools-ui/RegisterSettings.js +2 -1
  234. package/dist/src/tui/tools-ui/RegisterSettings.js.map +1 -1
  235. package/dist/src/tui/tools-ui/RoleMappings.d.ts.map +1 -1
  236. package/dist/src/tui/tools-ui/RoleMappings.js +3 -5
  237. package/dist/src/tui/tools-ui/RoleMappings.js.map +1 -1
  238. package/dist/src/tui/tools-ui/ToolsDashboard.d.ts.map +1 -1
  239. package/dist/src/tui/tools-ui/ToolsDashboard.js +3 -5
  240. package/dist/src/tui/tools-ui/ToolsDashboard.js.map +1 -1
  241. package/dist/src/tui/tools-ui/ToolsOverview.d.ts.map +1 -1
  242. package/dist/src/tui/tools-ui/ToolsOverview.js +3 -5
  243. package/dist/src/tui/tools-ui/ToolsOverview.js.map +1 -1
  244. package/dist/src/tui/uninstall-ui/UninstallFlow.d.ts.map +1 -1
  245. package/dist/src/tui/uninstall-ui/UninstallFlow.js +8 -7
  246. package/dist/src/tui/uninstall-ui/UninstallFlow.js.map +1 -1
  247. package/dist/src/types/index.d.ts +48 -6
  248. package/dist/src/types/index.d.ts.map +1 -1
  249. package/package.json +1 -1
  250. package/workflows/knowhow.md +15 -1
  251. package/workflows/specs-add.md +12 -4
  252. package/dashboard/dist/assets/ChatPage-BjBibfE4.js +0 -22
  253. package/dashboard/dist/assets/CollabPage-8lUMUol_.js +0 -1
  254. package/dashboard/dist/assets/KanbanPage-diY3QmGd.js +0 -21
  255. package/dashboard/dist/assets/McpPage-COjuIf7U.js +0 -21
  256. package/dashboard/dist/assets/SpecsPage-BOwBin_o.js +0 -36
  257. package/dashboard/dist/assets/SupervisorPage-5iRyMU5T.js +0 -6
  258. package/dashboard/dist/assets/WorkflowPage-CmQaRVgL.js +0 -6
  259. package/dashboard/dist/assets/en-C_BD3UCD.js +0 -1
  260. package/dashboard/dist/assets/index-BEUaOz_b.css +0 -1
  261. package/dashboard/dist/assets/index-uIqUCT8y.js +0 -236
  262. package/dashboard/dist/assets/table-DCzuJAFh.js +0 -6
  263. package/dashboard/dist/assets/zh-CN-DvQKfow3.js +0 -1
@@ -0,0 +1,311 @@
1
+ /**
2
+ * Spec Analytics — Injection logging and statistics
3
+ *
4
+ * Records every spec injection call (spec-injector, keyword-spec-injector,
5
+ * spec-injection-plugin) and CLI endpoint usage. Provides aggregated
6
+ * statistics for improvement analysis.
7
+ *
8
+ * Design:
9
+ * - Reuses jsonl-log.ts (appendLine, readAll, tailLast, rotateIfLarge)
10
+ * - Synchronous, never throws — safe for hot-path hooks
11
+ * - Config cached with 30s TTL to avoid repeated file reads
12
+ * - Auto-rotation at configurable max file size
13
+ */
14
+ import { join } from 'node:path';
15
+ import { statSync } from 'node:fs';
16
+ import { appendLine, readAll, tailLast, rotateIfLarge } from '../utils/jsonl-log.js';
17
+ // ---------------------------------------------------------------------------
18
+ // Constants
19
+ // ---------------------------------------------------------------------------
20
+ const DEFAULT_LOG_PATH = '.workflow/spec-analytics.jsonl';
21
+ const DEFAULT_MAX_SIZE = 5 * 1024 * 1024; // 5MB
22
+ const DEFAULT_ARCHIVE_DIR = '.workflow/archive';
23
+ const ROTATION_CHECK_INTERVAL = 50;
24
+ const CONFIG_CACHE_TTL_MS = 30_000;
25
+ // ---------------------------------------------------------------------------
26
+ // Module state
27
+ // ---------------------------------------------------------------------------
28
+ let _seq = 0;
29
+ let _writeCount = 0;
30
+ let _cachedConfig = null;
31
+ // ---------------------------------------------------------------------------
32
+ // Config resolution
33
+ // ---------------------------------------------------------------------------
34
+ function resolveConfig(projectPath, explicit) {
35
+ if (explicit)
36
+ return explicit;
37
+ const now = Date.now();
38
+ if (_cachedConfig && _cachedConfig.projectPath === projectPath && (now - _cachedConfig.timestamp) < CONFIG_CACHE_TTL_MS) {
39
+ return _cachedConfig.config;
40
+ }
41
+ try {
42
+ // Lazy import to avoid circular dependency
43
+ const { readFileSync, existsSync } = require('node:fs');
44
+ const configPath = join(projectPath, '.workflow', 'config.json');
45
+ if (!existsSync(configPath)) {
46
+ const defaultConfig = { enabled: true };
47
+ _cachedConfig = { config: defaultConfig, projectPath, timestamp: now };
48
+ return defaultConfig;
49
+ }
50
+ const raw = JSON.parse(readFileSync(configPath, 'utf-8'));
51
+ const config = raw?.specInjection?.analytics ?? { enabled: true };
52
+ _cachedConfig = { config, projectPath, timestamp: now };
53
+ return config;
54
+ }
55
+ catch {
56
+ return { enabled: true };
57
+ }
58
+ }
59
+ function resolveLogPath(projectPath, config) {
60
+ return join(projectPath, config.logPath ?? DEFAULT_LOG_PATH);
61
+ }
62
+ function resolveArchiveDir(projectPath) {
63
+ return join(projectPath, DEFAULT_ARCHIVE_DIR);
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // Auto-rotation
67
+ // ---------------------------------------------------------------------------
68
+ function maybeRotate(logPath, archiveDir, maxSize) {
69
+ _writeCount++;
70
+ if (_writeCount % ROTATION_CHECK_INTERVAL !== 0)
71
+ return;
72
+ rotateIfLarge(logPath, maxSize, archiveDir);
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Public API — Logging
76
+ // ---------------------------------------------------------------------------
77
+ /**
78
+ * Log a spec injection event. Synchronous, never throws.
79
+ */
80
+ export function logInjectionEvent(projectPath, entry, config) {
81
+ try {
82
+ const resolved = resolveConfig(projectPath, config);
83
+ if (!resolved.enabled)
84
+ return;
85
+ const logPath = resolveLogPath(projectPath, resolved);
86
+ const archiveDir = resolveArchiveDir(projectPath);
87
+ const fullEntry = {
88
+ type: 'injection',
89
+ id: `SINJ-${Date.now()}-${++_seq}`,
90
+ timestamp: new Date().toISOString(),
91
+ ...entry,
92
+ };
93
+ appendLine(logPath, fullEntry);
94
+ maybeRotate(logPath, archiveDir, resolved.maxFileSize ?? DEFAULT_MAX_SIZE);
95
+ }
96
+ catch {
97
+ // Swallow — hot path, never fail the host hook
98
+ }
99
+ }
100
+ /**
101
+ * Log a CLI endpoint call. Synchronous, never throws.
102
+ */
103
+ export function logCliEndpoint(projectPath, command, args, config) {
104
+ try {
105
+ const resolved = resolveConfig(projectPath, config);
106
+ if (!resolved.enabled)
107
+ return;
108
+ const logPath = resolveLogPath(projectPath, resolved);
109
+ const archiveDir = resolveArchiveDir(projectPath);
110
+ const fullEntry = {
111
+ type: 'cli',
112
+ id: `CLI-${Date.now()}-${++_seq}`,
113
+ timestamp: new Date().toISOString(),
114
+ command,
115
+ args,
116
+ };
117
+ appendLine(logPath, fullEntry);
118
+ maybeRotate(logPath, archiveDir, resolved.maxFileSize ?? DEFAULT_MAX_SIZE);
119
+ }
120
+ catch {
121
+ // Swallow
122
+ }
123
+ }
124
+ /**
125
+ * Log a workflow hook invocation. Synchronous, never throws.
126
+ */
127
+ export function logHookInvocation(projectPath, entry, config) {
128
+ try {
129
+ const resolved = resolveConfig(projectPath, config);
130
+ if (!resolved.enabled)
131
+ return;
132
+ const logPath = resolveLogPath(projectPath, resolved);
133
+ const archiveDir = resolveArchiveDir(projectPath);
134
+ const fullEntry = {
135
+ type: 'hook',
136
+ id: `HOOK-${Date.now()}-${++_seq}`,
137
+ timestamp: new Date().toISOString(),
138
+ ...entry,
139
+ };
140
+ appendLine(logPath, fullEntry);
141
+ maybeRotate(logPath, archiveDir, resolved.maxFileSize ?? DEFAULT_MAX_SIZE);
142
+ }
143
+ catch {
144
+ // Swallow
145
+ }
146
+ }
147
+ // ---------------------------------------------------------------------------
148
+ // Public API — Reading
149
+ // ---------------------------------------------------------------------------
150
+ /**
151
+ * Read all analytics entries.
152
+ */
153
+ export function readAnalytics(projectPath, config) {
154
+ const resolved = resolveConfig(projectPath, config);
155
+ const logPath = resolveLogPath(projectPath, resolved);
156
+ return readAll(logPath);
157
+ }
158
+ /**
159
+ * Read last N analytics entries (efficient tail).
160
+ */
161
+ export function readRecentAnalytics(projectPath, n, config) {
162
+ const resolved = resolveConfig(projectPath, config);
163
+ const logPath = resolveLogPath(projectPath, resolved);
164
+ return tailLast(logPath, n);
165
+ }
166
+ /**
167
+ * Get log file size in bytes. Returns 0 if file doesn't exist.
168
+ */
169
+ export function getLogFileSize(projectPath, config) {
170
+ try {
171
+ const resolved = resolveConfig(projectPath, config);
172
+ const logPath = resolveLogPath(projectPath, resolved);
173
+ return statSync(logPath).size;
174
+ }
175
+ catch {
176
+ return 0;
177
+ }
178
+ }
179
+ /**
180
+ * Clear analytics log by rotating it to archive.
181
+ */
182
+ export function clearAnalyticsLog(projectPath, config) {
183
+ const resolved = resolveConfig(projectPath, config);
184
+ const logPath = resolveLogPath(projectPath, resolved);
185
+ const archiveDir = resolveArchiveDir(projectPath);
186
+ // Force rotation regardless of size
187
+ return rotateIfLarge(logPath, 0, archiveDir);
188
+ }
189
+ // ---------------------------------------------------------------------------
190
+ // Public API — Statistics
191
+ // ---------------------------------------------------------------------------
192
+ /**
193
+ * Compute aggregated statistics from log entries. Pure function, no IO.
194
+ */
195
+ export function computeStats(entries, logFileSize = 0) {
196
+ const bySource = {};
197
+ const byAgentType = {};
198
+ const byCategory = {};
199
+ const byBudgetAction = {};
200
+ const keywordCounts = {};
201
+ const cliCounts = {};
202
+ const hookByName = {};
203
+ const hookByPlugin = {};
204
+ let totalInjections = 0;
205
+ let successfulInjections = 0;
206
+ let totalKeywordMatches = 0;
207
+ let totalPromptKeywordsSum = 0;
208
+ let dedupFilteredSum = 0;
209
+ let keywordEvents = 0;
210
+ let hookInvocations = 0;
211
+ let hookDurationSum = 0;
212
+ let hookDurationCount = 0;
213
+ let earliest = '';
214
+ let latest = '';
215
+ for (const entry of entries) {
216
+ // Track time range
217
+ if (!earliest || entry.timestamp < earliest)
218
+ earliest = entry.timestamp;
219
+ if (!latest || entry.timestamp > latest)
220
+ latest = entry.timestamp;
221
+ if (entry.type === 'injection') {
222
+ totalInjections++;
223
+ if (entry.inject)
224
+ successfulInjections++;
225
+ // By source
226
+ const src = entry.source;
227
+ if (!bySource[src])
228
+ bySource[src] = { total: 0, injected: 0 };
229
+ bySource[src].total++;
230
+ if (entry.inject)
231
+ bySource[src].injected++;
232
+ // By agent type (fall back to source name for keyword/plugin entries)
233
+ const agent = entry.agentType ?? entry.inferredCategory ?? `(${entry.source})`;
234
+ if (!byAgentType[agent])
235
+ byAgentType[agent] = { total: 0, injected: 0 };
236
+ byAgentType[agent].total++;
237
+ if (entry.inject)
238
+ byAgentType[agent].injected++;
239
+ // By category
240
+ if (entry.categories) {
241
+ for (const cat of entry.categories) {
242
+ byCategory[cat] = (byCategory[cat] ?? 0) + 1;
243
+ }
244
+ }
245
+ // By budget action
246
+ if (entry.budgetAction) {
247
+ byBudgetAction[entry.budgetAction] = (byBudgetAction[entry.budgetAction] ?? 0) + 1;
248
+ }
249
+ // Keyword stats
250
+ if (entry.matchedKeywords) {
251
+ keywordEvents++;
252
+ totalKeywordMatches += entry.matchedKeywords.length;
253
+ for (const kw of entry.matchedKeywords) {
254
+ keywordCounts[kw] = (keywordCounts[kw] ?? 0) + 1;
255
+ }
256
+ }
257
+ if (entry.totalPromptKeywords != null) {
258
+ totalPromptKeywordsSum += entry.totalPromptKeywords;
259
+ }
260
+ if (entry.dedupFilteredCount != null) {
261
+ dedupFilteredSum += entry.dedupFilteredCount;
262
+ }
263
+ }
264
+ else if (entry.type === 'cli') {
265
+ cliCounts[entry.command] = (cliCounts[entry.command] ?? 0) + 1;
266
+ }
267
+ else if (entry.type === 'hook') {
268
+ hookInvocations++;
269
+ hookByName[entry.hookName] = (hookByName[entry.hookName] ?? 0) + 1;
270
+ if (entry.pluginName) {
271
+ hookByPlugin[entry.pluginName] = (hookByPlugin[entry.pluginName] ?? 0) + 1;
272
+ }
273
+ if (entry.durationMs != null) {
274
+ hookDurationSum += entry.durationMs;
275
+ hookDurationCount++;
276
+ }
277
+ }
278
+ }
279
+ // Top keywords (sorted descending, top 20)
280
+ const topKeywords = Object.entries(keywordCounts)
281
+ .map(([keyword, count]) => ({ keyword, count }))
282
+ .sort((a, b) => b.count - a.count)
283
+ .slice(0, 20);
284
+ return {
285
+ totalInjections,
286
+ successfulInjections,
287
+ failedInjections: totalInjections - successfulInjections,
288
+ hitRate: totalInjections > 0 ? (successfulInjections / totalInjections) * 100 : 0,
289
+ bySource,
290
+ byAgentType,
291
+ byCategory,
292
+ byBudgetAction,
293
+ keywordStats: {
294
+ totalMatches: totalKeywordMatches,
295
+ topKeywords,
296
+ avgMatchedPerPrompt: keywordEvents > 0 ? totalKeywordMatches / keywordEvents : 0,
297
+ dedupFilteredTotal: dedupFilteredSum,
298
+ },
299
+ cliStats: cliCounts,
300
+ hookStats: {
301
+ totalInvocations: hookInvocations,
302
+ byHook: hookByName,
303
+ byPlugin: hookByPlugin,
304
+ avgDurationMs: hookDurationCount > 0 ? hookDurationSum / hookDurationCount : 0,
305
+ },
306
+ timeRange: { earliest, latest },
307
+ totalEntries: entries.length,
308
+ logFileSize,
309
+ };
310
+ }
311
+ //# sourceMappingURL=spec-analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-analytics.js","sourceRoot":"","sources":["../../../src/hooks/spec-analytics.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"spec-injector.d.ts","sourceRoot":"","sources":["../../../src/hooks/spec-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAM7D,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAkCD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,mBAAmB,EAC5B,GAAG,CAAC,EAAE,MAAM,GACX,mBAAmB,CA2CrB"}
1
+ {"version":3,"file":"spec-injector.d.ts","sourceRoot":"","sources":["../../../src/hooks/spec-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAO7D,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAgDD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,mBAAmB,EAC5B,GAAG,CAAC,EAAE,MAAM,GACX,mBAAmB,CA2JrB"}
@@ -8,10 +8,11 @@
8
8
  * Design: Uses `additionalContext` (advisory) rather than rewriting
9
9
  * the prompt — safer and non-destructive.
10
10
  */
11
- import { loadSpecs } from '../tools/spec-loader.js';
11
+ import { loadSpecs, loadExtraDocs } from '../tools/spec-loader.js';
12
12
  import { evaluateContextBudget } from './context-budget.js';
13
13
  import { resolveSelf } from '../tools/team-members.js';
14
14
  import { loadWikiByCategory } from './wiki-role-loader.js';
15
+ import { logInjectionEvent } from './spec-analytics.js';
15
16
  // ---------------------------------------------------------------------------
16
17
  // Agent-type → spec categories mapping (single source of truth)
17
18
  // ---------------------------------------------------------------------------
@@ -22,15 +23,27 @@ const AGENT_CATEGORY_MAP = {
22
23
  'workflow-executor': ['coding'],
23
24
  'universal-executor': ['coding', 'ui'],
24
25
  'test-fix-agent': ['coding', 'test'],
26
+ // Exploration agents → coding + arch specs
27
+ 'Explore': ['coding', 'arch'],
28
+ 'general-purpose': ['coding', 'learning'],
29
+ 'claude-code-guide': ['coding'],
25
30
  // Planning agents → arch specs
26
- 'cli-lite-planning-agent': ['arch'],
31
+ 'cli-lite-planning-agent': ['arch', 'coding'],
27
32
  'action-planning-agent': ['arch'],
28
33
  'workflow-planner': ['arch'],
34
+ 'workflow-collab-planner': ['arch'],
35
+ 'Plan': ['arch', 'coding'],
29
36
  // Review agents → review specs
30
37
  'workflow-reviewer': ['review'],
38
+ 'workflow-review': ['review', 'coding'],
31
39
  // Debug agents → debug specs
32
40
  'debug-explore-agent': ['debug'],
33
41
  'workflow-debugger': ['debug'],
42
+ // Context / research agents
43
+ 'context-search-agent': ['coding', 'arch'],
44
+ 'workflow-research-agent': ['coding'],
45
+ 'workflow-codebase-mapper': ['arch'],
46
+ 'workflow-analyzer': ['coding', 'arch'],
34
47
  // General — used by Codex SessionStart (no agent type available)
35
48
  'general': ['coding', 'learning'],
36
49
  };
@@ -48,20 +61,48 @@ const AGENT_CATEGORY_MAP = {
48
61
  */
49
62
  export function evaluateSpecInjection(agentType, projectPath, sessionId, config, uid) {
50
63
  const categories = resolveCategories(agentType, config);
51
- if (!categories || categories.length === 0)
64
+ if (!categories || categories.length === 0) {
65
+ logInjectionEvent(projectPath, {
66
+ source: 'spec-injector',
67
+ agentType,
68
+ categories: [],
69
+ specCount: 0,
70
+ contentLength: 0,
71
+ inject: false,
72
+ reason: 'no-categories',
73
+ }, config?.analytics);
52
74
  return { inject: false };
75
+ }
53
76
  const resolvedUid = uid ?? resolveUidSafe();
77
+ const kwFilters = resolveKeywordFilters(agentType, config);
54
78
  const sections = [];
55
79
  const allCategories = [];
56
80
  let totalCount = 0;
57
81
  for (const category of categories) {
82
+ // Build loader options with keyword filters and extra spec files
83
+ const loaderOpts = {};
84
+ if (kwFilters.include?.length)
85
+ loaderOpts.includeKeywords = kwFilters.include;
86
+ if (kwFilters.exclude?.length)
87
+ loaderOpts.excludeKeywords = kwFilters.exclude;
88
+ const catDocConfig = config?.categoryDocs?.[category];
89
+ if (catDocConfig?.specFiles?.length)
90
+ loaderOpts.extraSpecFiles = catDocConfig.specFiles;
58
91
  // Load specs by category (primary doc + keyword cross-match + tool discovery)
59
- const specResult = loadSpecs(projectPath, category, resolvedUid);
92
+ const specResult = loadSpecs(projectPath, category, resolvedUid, undefined, undefined, loaderOpts);
60
93
  if (specResult.content) {
61
94
  sections.push(specResult.content);
62
95
  allCategories.push(category);
63
96
  totalCount += specResult.totalLoaded;
64
97
  }
98
+ // Load category-level extra documents
99
+ if (catDocConfig?.docs?.length) {
100
+ const docsResult = loadExtraDocs(projectPath, catDocConfig.docs);
101
+ if (docsResult.content) {
102
+ sections.push(docsResult.content);
103
+ totalCount += docsResult.count;
104
+ }
105
+ }
65
106
  // Wiki category knowledge injection
66
107
  const wikiResult = loadWikiByCategory(projectPath, category);
67
108
  if (wikiResult) {
@@ -69,13 +110,88 @@ export function evaluateSpecInjection(agentType, projectPath, sessionId, config,
69
110
  totalCount += wikiResult.entryCount;
70
111
  }
71
112
  }
72
- if (sections.length === 0)
113
+ // Agent-specific extra documents
114
+ const agentExtras = config?.mapping?.[agentType]?.extras;
115
+ if (agentExtras?.length) {
116
+ const extrasResult = loadExtraDocs(projectPath, agentExtras);
117
+ if (extrasResult.content) {
118
+ sections.push(extrasResult.content);
119
+ totalCount += extrasResult.count;
120
+ }
121
+ }
122
+ // Always-inject (session start): documents, keyword-matched entries, and categories
123
+ if (config?.always) {
124
+ const always = config.always;
125
+ // Always-inject documents
126
+ if (always.docs?.length) {
127
+ const alwaysResult = loadExtraDocs(projectPath, always.docs);
128
+ if (alwaysResult.content) {
129
+ sections.push(alwaysResult.content);
130
+ totalCount += alwaysResult.count;
131
+ }
132
+ }
133
+ // Always-inject keyword-matched entries (load from all specs, filter by keywords)
134
+ if (always.keywords?.length) {
135
+ const kwOpts = { includeKeywords: always.keywords };
136
+ const kwResult = loadSpecs(projectPath, undefined, resolvedUid, undefined, undefined, kwOpts);
137
+ if (kwResult.content) {
138
+ sections.push(kwResult.content);
139
+ totalCount += kwResult.totalLoaded;
140
+ }
141
+ }
142
+ // Always-inject full categories
143
+ if (always.categories?.length) {
144
+ for (const cat of always.categories) {
145
+ if (allCategories.includes(cat))
146
+ continue; // Already loaded above
147
+ const catResult = loadSpecs(projectPath, cat, resolvedUid);
148
+ if (catResult.content) {
149
+ sections.push(catResult.content);
150
+ totalCount += catResult.totalLoaded;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ if (sections.length === 0) {
156
+ logInjectionEvent(projectPath, {
157
+ source: 'spec-injector',
158
+ agentType,
159
+ categories: allCategories,
160
+ specCount: totalCount,
161
+ contentLength: 0,
162
+ inject: false,
163
+ reason: 'no-content',
164
+ }, config?.analytics);
73
165
  return { inject: false };
74
- const rawContent = sections.join('\n\n---\n\n');
166
+ }
167
+ let rawContent = sections.join('\n\n---\n\n');
168
+ // Apply maxContentLength before context budget
169
+ if (config?.maxContentLength && rawContent.length > config.maxContentLength) {
170
+ rawContent = rawContent.slice(0, config.maxContentLength);
171
+ }
75
172
  const budget = evaluateContextBudget(rawContent, sessionId);
76
173
  if (budget.action === 'skip') {
174
+ logInjectionEvent(projectPath, {
175
+ source: 'spec-injector',
176
+ agentType,
177
+ categories: allCategories,
178
+ specCount: totalCount,
179
+ budgetAction: 'skip',
180
+ contentLength: rawContent.length,
181
+ inject: false,
182
+ reason: 'budget-skip',
183
+ }, config?.analytics);
77
184
  return { inject: false, budgetAction: 'skip' };
78
185
  }
186
+ logInjectionEvent(projectPath, {
187
+ source: 'spec-injector',
188
+ agentType,
189
+ categories: allCategories,
190
+ specCount: totalCount,
191
+ budgetAction: budget.action,
192
+ contentLength: budget.content?.length ?? 0,
193
+ inject: true,
194
+ }, config?.analytics);
79
195
  return {
80
196
  inject: true,
81
197
  content: budget.content,
@@ -110,4 +226,22 @@ function resolveCategories(agentType, config) {
110
226
  }
111
227
  return AGENT_CATEGORY_MAP[agentType] ?? null;
112
228
  }
229
+ /**
230
+ * Merge keyword filters from agent-level and global-level config.
231
+ * Agent-level include replaces global include; excludes are merged.
232
+ */
233
+ function resolveKeywordFilters(agentType, config) {
234
+ if (!config)
235
+ return {};
236
+ const agentMapping = config.mapping?.[agentType];
237
+ const globalFilters = config.keywordFilters;
238
+ const include = agentMapping?.includeKeywords ?? globalFilters?.include;
239
+ const agentExclude = agentMapping?.excludeKeywords ?? [];
240
+ const globalExclude = globalFilters?.exclude ?? [];
241
+ const mergedExclude = [...agentExclude, ...globalExclude];
242
+ return {
243
+ include: include?.length ? include : undefined,
244
+ exclude: mergedExclude.length > 0 ? mergedExclude : undefined,
245
+ };
246
+ }
113
247
  //# sourceMappingURL=spec-injector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec-injector.js","sourceRoot":"","sources":["../../../src/hooks/spec-injector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spec-injector.js","sourceRoot":"","sources":["../../../src/hooks/spec-injector.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"spec-keyword-index.d.ts","sourceRoot":"","sources":["../../../src/tools/spec-keyword-index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAgDlF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAEjG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAerG"}
1
+ {"version":3,"file":"spec-keyword-index.d.ts","sourceRoot":"","sources":["../../../src/tools/spec-keyword-index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAsDlF;AAaD;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAEjG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAerG"}
@@ -50,18 +50,35 @@ export function buildKeywordIndex(projectPath) {
50
50
  id: `${file}:${entry.lineStart}`,
51
51
  };
52
52
  for (const kw of entry.keywords) {
53
- const list = index.get(kw);
54
- if (list) {
55
- list.push(indexed);
56
- }
57
- else {
58
- index.set(kw, [indexed]);
53
+ addToIndex(index, kw, indexed);
54
+ // Index CJK sub-tokens so partial matches work
55
+ // e.g. keyword "设计系统" also indexes "设计" and "系统"
56
+ if (/[\u4e00-\u9fff]/.test(kw) && kw.length > 2) {
57
+ for (let n = 2; n <= Math.min(4, kw.length); n++) {
58
+ for (let i = 0; i <= kw.length - n; i++) {
59
+ const sub = kw.substring(i, i + n);
60
+ if (sub !== kw)
61
+ addToIndex(index, sub, indexed);
62
+ }
63
+ }
59
64
  }
60
65
  }
61
66
  }
62
67
  }
63
68
  return index;
64
69
  }
70
+ function addToIndex(index, key, entry) {
71
+ const k = key.toLowerCase();
72
+ const list = index.get(k);
73
+ if (list) {
74
+ // Avoid duplicate entries under the same key
75
+ if (!list.some(e => e.id === entry.id))
76
+ list.push(entry);
77
+ }
78
+ else {
79
+ index.set(k, [entry]);
80
+ }
81
+ }
65
82
  /**
66
83
  * Look up entries matching a keyword.
67
84
  */
@@ -1 +1 @@
1
- {"version":3,"file":"spec-keyword-index.js","sourceRoot":"","sources":["../../../src/tools/spec-keyword-index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spec-keyword-index.js","sourceRoot":"","sources":["../../../src/tools/spec-keyword-index.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,26 @@ export declare function resolveSpecDir(projectPath: string, scope: SpecScope, ui
47
47
  export interface LoadSpecsOptions {
48
48
  /** Override global specs directory (for testing). Defaults to ~/.maestro/specs/ */
49
49
  globalDir?: string;
50
+ /** Keyword whitelist: only include entries matching at least one keyword */
51
+ includeKeywords?: string[];
52
+ /** Keyword blacklist: exclude entries matching any of these keywords */
53
+ excludeKeywords?: string[];
54
+ /** Extra spec filenames to include for the category (dynamic CATEGORY_MAP extension) */
55
+ extraSpecFiles?: string[];
50
56
  }
51
57
  export declare function loadSpecs(projectPath: string, category?: SpecCategory, uid?: string, keyword?: string, scope?: SpecScope, options?: LoadSpecsOptions): SpecLoadResult;
58
+ export interface ExtraDocsResult {
59
+ content: string;
60
+ count: number;
61
+ }
62
+ /**
63
+ * Load additional documents from arbitrary paths.
64
+ *
65
+ * Path resolution:
66
+ * - Starts with `knowhow/` → resolved from `.workflow/knowhow/`
67
+ * - Otherwise → resolved relative to projectPath
68
+ *
69
+ * Returns concatenated markdown content and loaded count.
70
+ */
71
+ export declare function loadExtraDocs(projectPath: string, docPaths?: string[]): ExtraDocsResult;
52
72
  //# sourceMappingURL=spec-loader.d.ts.map