maestro-flow 0.4.3 → 0.4.4

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 (232) hide show
  1. package/dashboard/dist/assets/{ArtifactsPage-iJZtYsmR.js → ArtifactsPage-CVh0Z2I2.js} +3 -3
  2. package/dashboard/dist/assets/{ChatInput-DNnDLdQF.js → ChatInput-CBI3qHQQ.js} +2 -2
  3. package/dashboard/dist/assets/ChatPage-BjJ9CYox.js +22 -0
  4. package/dashboard/dist/assets/CollabPage-CprGGO9y.js +1 -0
  5. package/dashboard/dist/assets/{ExecutionPanel-BKV3GZ7Q.js → ExecutionPanel-CClxD7cH.js} +1 -1
  6. package/dashboard/dist/assets/KanbanPage-copqjdPg.js +16 -0
  7. package/dashboard/dist/assets/MaestroCoordinatePage-CioZjQ9N.js +4 -0
  8. package/dashboard/dist/assets/{MarkdownRenderer-cYFfe1uX.js → MarkdownRenderer-CtUhoxCT.js} +1 -1
  9. package/dashboard/dist/assets/McpPage-BcPPcJpr.js +21 -0
  10. package/dashboard/dist/assets/{MeetingRoomPage-wnvT7wlB.js → MeetingRoomPage-BgmAKxU-.js} +1 -1
  11. package/dashboard/dist/assets/{OutputPanel-DDL90Idy.js → OutputPanel-DgT3gMyp.js} +1 -1
  12. package/dashboard/dist/assets/{ProblemsPanel-zFN9IIs0.js → ProblemsPanel-BmG7rxoG.js} +1 -1
  13. package/dashboard/dist/assets/{RequirementBoardPage-DOPJoT0I.js → RequirementBoardPage-k8YoeQ0r.js} +1 -1
  14. package/dashboard/dist/assets/{RequirementPage-CEVquRgM.js → RequirementPage-Da2354px.js} +1 -1
  15. package/dashboard/dist/assets/{RoomsPage-D5USEWDh.js → RoomsPage-BtqDiYaU.js} +1 -1
  16. package/dashboard/dist/assets/SpecsPage-ByPVH_M3.js +36 -0
  17. package/dashboard/dist/assets/{TeamsPage-DlcEmr_Q.js → TeamsPage-sFDLN30L.js} +1 -1
  18. package/dashboard/dist/assets/{TreeBrowser-Y48Wz-QY.js → TreeBrowser-oEx8YJXV.js} +1 -1
  19. package/dashboard/dist/assets/WorkflowPage-JrX7CVHh.js +6 -0
  20. package/dashboard/dist/assets/{arrow-left-NCUOENvg.js → arrow-left-DYvgSdIH.js} +1 -1
  21. package/dashboard/dist/assets/{check-o7nfGNHf.js → check-jcgYBWVR.js} +1 -1
  22. package/dashboard/dist/assets/{chevron-right-BXySK2fn.js → chevron-right-DvZ5sMOg.js} +1 -1
  23. package/dashboard/dist/assets/{circle-cooAwnAR.js → circle-DYT-zoRZ.js} +1 -1
  24. package/dashboard/dist/assets/{circle-alert-DcSBokh4.js → circle-alert-Bfbv3gt4.js} +1 -1
  25. package/dashboard/dist/assets/{circle-check-Cd-jce4j.js → circle-check-D82WnpbI.js} +1 -1
  26. package/dashboard/dist/assets/{circle-check-big-BN7Mdp4i.js → circle-check-big-CPVD1GKF.js} +1 -1
  27. package/dashboard/dist/assets/{code-BQa9oL1n.js → code-B3bKFGI4.js} +1 -1
  28. package/dashboard/dist/assets/{columns-3-BzgxelGx.js → columns-3-BeMAQCix.js} +1 -1
  29. package/dashboard/dist/assets/{download-swRJnate.js → download-BCtpoWYB.js} +1 -1
  30. package/dashboard/dist/assets/en-2h6fD0j8.js +1 -0
  31. package/dashboard/dist/assets/{folder-DbGbLNFN.js → folder-CTj6SNNu.js} +1 -1
  32. package/dashboard/dist/assets/index-6-yE5Yl9.css +1 -0
  33. package/dashboard/dist/assets/{index-DIoMBMbv.js → index-BxR_3IbJ.js} +1 -1
  34. package/dashboard/dist/assets/{index-DLBN_7fb.js → index-CWBJLu42.js} +1 -1
  35. package/dashboard/dist/assets/index-DpcPd-UG.js +236 -0
  36. package/dashboard/dist/assets/{list-BTRAIvDq.js → list-BMv8pIQn.js} +1 -1
  37. package/dashboard/dist/assets/{loader-NHtB6Mdn.js → loader-DdM4VOgF.js} +1 -1
  38. package/dashboard/dist/assets/{minus-BjMxRTET.js → minus-D15s2E__.js} +1 -1
  39. package/dashboard/dist/assets/{pen-line-C4_O16H0.js → pen-line-DO6o4xWz.js} +1 -1
  40. package/dashboard/dist/assets/{pencil-DTmKhyDY.js → pencil-qGxg9jOe.js} +1 -1
  41. package/dashboard/dist/assets/{proxy-Dtx5p6IO.js → proxy-DOffTzwA.js} +1 -1
  42. package/dashboard/dist/assets/refresh-cw-C9UNdLCy.js +6 -0
  43. package/dashboard/dist/assets/{rows-2-GR1dZtRu.js → rows-2-CifAA5SL.js} +1 -1
  44. package/dashboard/dist/assets/{search-DVtgy2W7.js → search-pe7pU1YN.js} +1 -1
  45. package/dashboard/dist/assets/{shallow-BOmvDNsv.js → shallow-r7YynQYA.js} +1 -1
  46. package/dashboard/dist/assets/table-Bh772iIw.js +6 -0
  47. package/dashboard/dist/assets/{team-types-BPeOvVdA.js → team-types-C_HqX2p2.js} +1 -1
  48. package/dashboard/dist/assets/{terminal-CzogW4cl.js → terminal-EpmtGBlw.js} +1 -1
  49. package/dashboard/dist/assets/{trash-2-52LATVfW.js → trash-2-Xen46iNQ.js} +1 -1
  50. package/dashboard/dist/assets/{users-DLFE2voE.js → users-BLueDPxF.js} +1 -1
  51. package/dashboard/dist/assets/{zap-DhiYlgyZ.js → zap-DsQCPF61.js} +1 -1
  52. package/dashboard/dist/assets/zh-CN-r3AvxxOL.js +1 -0
  53. package/dashboard/dist/index.html +2 -2
  54. package/dashboard/dist-server/dashboard/src/server/routes/settings.js +70 -1
  55. package/dashboard/dist-server/dashboard/src/server/routes/settings.js.map +1 -1
  56. package/dashboard/dist-server/src/types/index.d.ts +48 -6
  57. package/dist/src/commands/coordinate.d.ts.map +1 -1
  58. package/dist/src/commands/coordinate.js +2 -0
  59. package/dist/src/commands/coordinate.js.map +1 -1
  60. package/dist/src/commands/hooks.d.ts.map +1 -1
  61. package/dist/src/commands/hooks.js +201 -6
  62. package/dist/src/commands/hooks.js.map +1 -1
  63. package/dist/src/commands/spec.d.ts.map +1 -1
  64. package/dist/src/commands/spec.js +466 -0
  65. package/dist/src/commands/spec.js.map +1 -1
  66. package/dist/src/config/index.d.ts +5 -1
  67. package/dist/src/config/index.d.ts.map +1 -1
  68. package/dist/src/config/index.js +42 -0
  69. package/dist/src/config/index.js.map +1 -1
  70. package/dist/src/hooks/keyword-spec-injector.d.ts.map +1 -1
  71. package/dist/src/hooks/keyword-spec-injector.js +63 -4
  72. package/dist/src/hooks/keyword-spec-injector.js.map +1 -1
  73. package/dist/src/hooks/plugins/spec-analytics-plugin.d.ts +13 -0
  74. package/dist/src/hooks/plugins/spec-analytics-plugin.d.ts.map +1 -0
  75. package/dist/src/hooks/plugins/spec-analytics-plugin.js +92 -0
  76. package/dist/src/hooks/plugins/spec-analytics-plugin.js.map +1 -0
  77. package/dist/src/hooks/plugins/spec-injection-plugin.d.ts.map +1 -1
  78. package/dist/src/hooks/plugins/spec-injection-plugin.js +57 -4
  79. package/dist/src/hooks/plugins/spec-injection-plugin.js.map +1 -1
  80. package/dist/src/hooks/spec-analytics.d.ts +128 -0
  81. package/dist/src/hooks/spec-analytics.d.ts.map +1 -0
  82. package/dist/src/hooks/spec-analytics.js +311 -0
  83. package/dist/src/hooks/spec-analytics.js.map +1 -0
  84. package/dist/src/hooks/spec-injector.d.ts.map +1 -1
  85. package/dist/src/hooks/spec-injector.js +127 -5
  86. package/dist/src/hooks/spec-injector.js.map +1 -1
  87. package/dist/src/tools/spec-loader.d.ts +20 -0
  88. package/dist/src/tools/spec-loader.d.ts.map +1 -1
  89. package/dist/src/tools/spec-loader.js +58 -7
  90. package/dist/src/tools/spec-loader.js.map +1 -1
  91. package/dist/src/tui/config-ui/ConfigHub.d.ts +1 -1
  92. package/dist/src/tui/config-ui/ConfigHub.d.ts.map +1 -1
  93. package/dist/src/tui/config-ui/ConfigHub.js +16 -10
  94. package/dist/src/tui/config-ui/ConfigHub.js.map +1 -1
  95. package/dist/src/tui/config-ui/ConfigSourcesView.d.ts.map +1 -1
  96. package/dist/src/tui/config-ui/ConfigSourcesView.js +3 -2
  97. package/dist/src/tui/config-ui/ConfigSourcesView.js.map +1 -1
  98. package/dist/src/tui/config-ui/HooksPanel.d.ts.map +1 -1
  99. package/dist/src/tui/config-ui/HooksPanel.js +15 -19
  100. package/dist/src/tui/config-ui/HooksPanel.js.map +1 -1
  101. package/dist/src/tui/config-ui/SkillConfigDashboard.d.ts.map +1 -1
  102. package/dist/src/tui/config-ui/SkillConfigDashboard.js +5 -9
  103. package/dist/src/tui/config-ui/SkillConfigDashboard.js.map +1 -1
  104. package/dist/src/tui/config-ui/SkillParamEditor.d.ts.map +1 -1
  105. package/dist/src/tui/config-ui/SkillParamEditor.js +1 -3
  106. package/dist/src/tui/config-ui/SkillParamEditor.js.map +1 -1
  107. package/dist/src/tui/config-ui/SkillsList.d.ts.map +1 -1
  108. package/dist/src/tui/config-ui/SkillsList.js +7 -9
  109. package/dist/src/tui/config-ui/SkillsList.js.map +1 -1
  110. package/dist/src/tui/config-ui/SpecAnalyticsPanel.d.ts +6 -0
  111. package/dist/src/tui/config-ui/SpecAnalyticsPanel.d.ts.map +1 -0
  112. package/dist/src/tui/config-ui/SpecAnalyticsPanel.js +164 -0
  113. package/dist/src/tui/config-ui/SpecAnalyticsPanel.js.map +1 -0
  114. package/dist/src/tui/config-ui/SpecPanel.d.ts.map +1 -1
  115. package/dist/src/tui/config-ui/SpecPanel.js +918 -20
  116. package/dist/src/tui/config-ui/SpecPanel.js.map +1 -1
  117. package/dist/src/tui/config-ui/index.d.ts +3 -1
  118. package/dist/src/tui/config-ui/index.d.ts.map +1 -1
  119. package/dist/src/tui/config-ui/index.js +4 -0
  120. package/dist/src/tui/config-ui/index.js.map +1 -1
  121. package/dist/src/tui/install-ui/BackupConfig.d.ts.map +1 -1
  122. package/dist/src/tui/install-ui/BackupConfig.js +3 -2
  123. package/dist/src/tui/install-ui/BackupConfig.js.map +1 -1
  124. package/dist/src/tui/install-ui/BlueprintPreview.d.ts.map +1 -1
  125. package/dist/src/tui/install-ui/BlueprintPreview.js +7 -6
  126. package/dist/src/tui/install-ui/BlueprintPreview.js.map +1 -1
  127. package/dist/src/tui/install-ui/ComponentGrid.d.ts.map +1 -1
  128. package/dist/src/tui/install-ui/ComponentGrid.js +3 -2
  129. package/dist/src/tui/install-ui/ComponentGrid.js.map +1 -1
  130. package/dist/src/tui/install-ui/ConfigPanel.d.ts.map +1 -1
  131. package/dist/src/tui/install-ui/ConfigPanel.js +4 -3
  132. package/dist/src/tui/install-ui/ConfigPanel.js.map +1 -1
  133. package/dist/src/tui/install-ui/CyberItem.d.ts.map +1 -1
  134. package/dist/src/tui/install-ui/CyberItem.js +7 -6
  135. package/dist/src/tui/install-ui/CyberItem.js.map +1 -1
  136. package/dist/src/tui/install-ui/CyberdeckBlueprint.d.ts.map +1 -1
  137. package/dist/src/tui/install-ui/CyberdeckBlueprint.js +2 -1
  138. package/dist/src/tui/install-ui/CyberdeckBlueprint.js.map +1 -1
  139. package/dist/src/tui/install-ui/ExecutionView.d.ts.map +1 -1
  140. package/dist/src/tui/install-ui/ExecutionView.js +3 -2
  141. package/dist/src/tui/install-ui/ExecutionView.js.map +1 -1
  142. package/dist/src/tui/install-ui/GradientHeader.d.ts.map +1 -1
  143. package/dist/src/tui/install-ui/GradientHeader.js +2 -1
  144. package/dist/src/tui/install-ui/GradientHeader.js.map +1 -1
  145. package/dist/src/tui/install-ui/HooksConfig.d.ts.map +1 -1
  146. package/dist/src/tui/install-ui/HooksConfig.js +8 -8
  147. package/dist/src/tui/install-ui/HooksConfig.js.map +1 -1
  148. package/dist/src/tui/install-ui/InstallConfirm.d.ts.map +1 -1
  149. package/dist/src/tui/install-ui/InstallConfirm.js +4 -3
  150. package/dist/src/tui/install-ui/InstallConfirm.js.map +1 -1
  151. package/dist/src/tui/install-ui/InstallExecution.d.ts.map +1 -1
  152. package/dist/src/tui/install-ui/InstallExecution.js +3 -2
  153. package/dist/src/tui/install-ui/InstallExecution.js.map +1 -1
  154. package/dist/src/tui/install-ui/InstallFlow.d.ts.map +1 -1
  155. package/dist/src/tui/install-ui/InstallFlow.js +3 -2
  156. package/dist/src/tui/install-ui/InstallFlow.js.map +1 -1
  157. package/dist/src/tui/install-ui/InstallHub.d.ts.map +1 -1
  158. package/dist/src/tui/install-ui/InstallHub.js +9 -8
  159. package/dist/src/tui/install-ui/InstallHub.js.map +1 -1
  160. package/dist/src/tui/install-ui/InstallResult.d.ts.map +1 -1
  161. package/dist/src/tui/install-ui/InstallResult.js +3 -2
  162. package/dist/src/tui/install-ui/InstallResult.js.map +1 -1
  163. package/dist/src/tui/install-ui/McpConfig.d.ts.map +1 -1
  164. package/dist/src/tui/install-ui/McpConfig.js +4 -3
  165. package/dist/src/tui/install-ui/McpConfig.js.map +1 -1
  166. package/dist/src/tui/install-ui/ResultDashboard.d.ts.map +1 -1
  167. package/dist/src/tui/install-ui/ResultDashboard.js +3 -2
  168. package/dist/src/tui/install-ui/ResultDashboard.js.map +1 -1
  169. package/dist/src/tui/install-ui/ReviewPanel.d.ts.map +1 -1
  170. package/dist/src/tui/install-ui/ReviewPanel.js +2 -1
  171. package/dist/src/tui/install-ui/ReviewPanel.js.map +1 -1
  172. package/dist/src/tui/install-ui/StatuslineConfig.d.ts.map +1 -1
  173. package/dist/src/tui/install-ui/StatuslineConfig.js +3 -2
  174. package/dist/src/tui/install-ui/StatuslineConfig.js.map +1 -1
  175. package/dist/src/tui/install-ui/StepSelector.d.ts.map +1 -1
  176. package/dist/src/tui/install-ui/StepSelector.js +11 -10
  177. package/dist/src/tui/install-ui/StepSelector.js.map +1 -1
  178. package/dist/src/tui/overlay-ui/OverlayList.d.ts.map +1 -1
  179. package/dist/src/tui/overlay-ui/OverlayList.js +8 -12
  180. package/dist/src/tui/overlay-ui/OverlayList.js.map +1 -1
  181. package/dist/src/tui/shared/components.d.ts +56 -0
  182. package/dist/src/tui/shared/components.d.ts.map +1 -0
  183. package/dist/src/tui/shared/components.js +55 -0
  184. package/dist/src/tui/shared/components.js.map +1 -0
  185. package/dist/src/tui/shared/helpers.d.ts +24 -0
  186. package/dist/src/tui/shared/helpers.d.ts.map +1 -0
  187. package/dist/src/tui/shared/helpers.js +49 -0
  188. package/dist/src/tui/shared/helpers.js.map +1 -0
  189. package/dist/src/tui/shared/index.d.ts +4 -0
  190. package/dist/src/tui/shared/index.d.ts.map +1 -0
  191. package/dist/src/tui/shared/index.js +7 -0
  192. package/dist/src/tui/shared/index.js.map +1 -0
  193. package/dist/src/tui/shared/tokens.d.ts +79 -0
  194. package/dist/src/tui/shared/tokens.d.ts.map +1 -0
  195. package/dist/src/tui/shared/tokens.js +81 -0
  196. package/dist/src/tui/shared/tokens.js.map +1 -0
  197. package/dist/src/tui/tools-ui/CommandReference.d.ts.map +1 -1
  198. package/dist/src/tui/tools-ui/CommandReference.js +2 -4
  199. package/dist/src/tui/tools-ui/CommandReference.js.map +1 -1
  200. package/dist/src/tui/tools-ui/ConfigSources.d.ts.map +1 -1
  201. package/dist/src/tui/tools-ui/ConfigSources.js +3 -2
  202. package/dist/src/tui/tools-ui/ConfigSources.js.map +1 -1
  203. package/dist/src/tui/tools-ui/RegisterSettings.d.ts.map +1 -1
  204. package/dist/src/tui/tools-ui/RegisterSettings.js +2 -1
  205. package/dist/src/tui/tools-ui/RegisterSettings.js.map +1 -1
  206. package/dist/src/tui/tools-ui/RoleMappings.d.ts.map +1 -1
  207. package/dist/src/tui/tools-ui/RoleMappings.js +3 -5
  208. package/dist/src/tui/tools-ui/RoleMappings.js.map +1 -1
  209. package/dist/src/tui/tools-ui/ToolsDashboard.d.ts.map +1 -1
  210. package/dist/src/tui/tools-ui/ToolsDashboard.js +3 -5
  211. package/dist/src/tui/tools-ui/ToolsDashboard.js.map +1 -1
  212. package/dist/src/tui/tools-ui/ToolsOverview.d.ts.map +1 -1
  213. package/dist/src/tui/tools-ui/ToolsOverview.js +3 -5
  214. package/dist/src/tui/tools-ui/ToolsOverview.js.map +1 -1
  215. package/dist/src/tui/uninstall-ui/UninstallFlow.d.ts.map +1 -1
  216. package/dist/src/tui/uninstall-ui/UninstallFlow.js +8 -7
  217. package/dist/src/tui/uninstall-ui/UninstallFlow.js.map +1 -1
  218. package/dist/src/types/index.d.ts +48 -6
  219. package/dist/src/types/index.d.ts.map +1 -1
  220. package/package.json +1 -1
  221. package/dashboard/dist/assets/ChatPage-BjBibfE4.js +0 -22
  222. package/dashboard/dist/assets/CollabPage-8lUMUol_.js +0 -1
  223. package/dashboard/dist/assets/KanbanPage-diY3QmGd.js +0 -21
  224. package/dashboard/dist/assets/McpPage-COjuIf7U.js +0 -21
  225. package/dashboard/dist/assets/SpecsPage-BOwBin_o.js +0 -36
  226. package/dashboard/dist/assets/SupervisorPage-5iRyMU5T.js +0 -6
  227. package/dashboard/dist/assets/WorkflowPage-CmQaRVgL.js +0 -6
  228. package/dashboard/dist/assets/en-C_BD3UCD.js +0 -1
  229. package/dashboard/dist/assets/index-BEUaOz_b.css +0 -1
  230. package/dashboard/dist/assets/index-uIqUCT8y.js +0 -236
  231. package/dashboard/dist/assets/table-DCzuJAFh.js +0 -6
  232. 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;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,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
  // ---------------------------------------------------------------------------
@@ -48,20 +49,48 @@ const AGENT_CATEGORY_MAP = {
48
49
  */
49
50
  export function evaluateSpecInjection(agentType, projectPath, sessionId, config, uid) {
50
51
  const categories = resolveCategories(agentType, config);
51
- if (!categories || categories.length === 0)
52
+ if (!categories || categories.length === 0) {
53
+ logInjectionEvent(projectPath, {
54
+ source: 'spec-injector',
55
+ agentType,
56
+ categories: [],
57
+ specCount: 0,
58
+ contentLength: 0,
59
+ inject: false,
60
+ reason: 'no-categories',
61
+ }, config?.analytics);
52
62
  return { inject: false };
63
+ }
53
64
  const resolvedUid = uid ?? resolveUidSafe();
65
+ const kwFilters = resolveKeywordFilters(agentType, config);
54
66
  const sections = [];
55
67
  const allCategories = [];
56
68
  let totalCount = 0;
57
69
  for (const category of categories) {
70
+ // Build loader options with keyword filters and extra spec files
71
+ const loaderOpts = {};
72
+ if (kwFilters.include?.length)
73
+ loaderOpts.includeKeywords = kwFilters.include;
74
+ if (kwFilters.exclude?.length)
75
+ loaderOpts.excludeKeywords = kwFilters.exclude;
76
+ const catDocConfig = config?.categoryDocs?.[category];
77
+ if (catDocConfig?.specFiles?.length)
78
+ loaderOpts.extraSpecFiles = catDocConfig.specFiles;
58
79
  // Load specs by category (primary doc + keyword cross-match + tool discovery)
59
- const specResult = loadSpecs(projectPath, category, resolvedUid);
80
+ const specResult = loadSpecs(projectPath, category, resolvedUid, undefined, undefined, loaderOpts);
60
81
  if (specResult.content) {
61
82
  sections.push(specResult.content);
62
83
  allCategories.push(category);
63
84
  totalCount += specResult.totalLoaded;
64
85
  }
86
+ // Load category-level extra documents
87
+ if (catDocConfig?.docs?.length) {
88
+ const docsResult = loadExtraDocs(projectPath, catDocConfig.docs);
89
+ if (docsResult.content) {
90
+ sections.push(docsResult.content);
91
+ totalCount += docsResult.count;
92
+ }
93
+ }
65
94
  // Wiki category knowledge injection
66
95
  const wikiResult = loadWikiByCategory(projectPath, category);
67
96
  if (wikiResult) {
@@ -69,13 +98,88 @@ export function evaluateSpecInjection(agentType, projectPath, sessionId, config,
69
98
  totalCount += wikiResult.entryCount;
70
99
  }
71
100
  }
72
- if (sections.length === 0)
101
+ // Agent-specific extra documents
102
+ const agentExtras = config?.mapping?.[agentType]?.extras;
103
+ if (agentExtras?.length) {
104
+ const extrasResult = loadExtraDocs(projectPath, agentExtras);
105
+ if (extrasResult.content) {
106
+ sections.push(extrasResult.content);
107
+ totalCount += extrasResult.count;
108
+ }
109
+ }
110
+ // Always-inject (session start): documents, keyword-matched entries, and categories
111
+ if (config?.always) {
112
+ const always = config.always;
113
+ // Always-inject documents
114
+ if (always.docs?.length) {
115
+ const alwaysResult = loadExtraDocs(projectPath, always.docs);
116
+ if (alwaysResult.content) {
117
+ sections.push(alwaysResult.content);
118
+ totalCount += alwaysResult.count;
119
+ }
120
+ }
121
+ // Always-inject keyword-matched entries (load from all specs, filter by keywords)
122
+ if (always.keywords?.length) {
123
+ const kwOpts = { includeKeywords: always.keywords };
124
+ const kwResult = loadSpecs(projectPath, undefined, resolvedUid, undefined, undefined, kwOpts);
125
+ if (kwResult.content) {
126
+ sections.push(kwResult.content);
127
+ totalCount += kwResult.totalLoaded;
128
+ }
129
+ }
130
+ // Always-inject full categories
131
+ if (always.categories?.length) {
132
+ for (const cat of always.categories) {
133
+ if (allCategories.includes(cat))
134
+ continue; // Already loaded above
135
+ const catResult = loadSpecs(projectPath, cat, resolvedUid);
136
+ if (catResult.content) {
137
+ sections.push(catResult.content);
138
+ totalCount += catResult.totalLoaded;
139
+ }
140
+ }
141
+ }
142
+ }
143
+ if (sections.length === 0) {
144
+ logInjectionEvent(projectPath, {
145
+ source: 'spec-injector',
146
+ agentType,
147
+ categories: allCategories,
148
+ specCount: totalCount,
149
+ contentLength: 0,
150
+ inject: false,
151
+ reason: 'no-content',
152
+ }, config?.analytics);
73
153
  return { inject: false };
74
- const rawContent = sections.join('\n\n---\n\n');
154
+ }
155
+ let rawContent = sections.join('\n\n---\n\n');
156
+ // Apply maxContentLength before context budget
157
+ if (config?.maxContentLength && rawContent.length > config.maxContentLength) {
158
+ rawContent = rawContent.slice(0, config.maxContentLength);
159
+ }
75
160
  const budget = evaluateContextBudget(rawContent, sessionId);
76
161
  if (budget.action === 'skip') {
162
+ logInjectionEvent(projectPath, {
163
+ source: 'spec-injector',
164
+ agentType,
165
+ categories: allCategories,
166
+ specCount: totalCount,
167
+ budgetAction: 'skip',
168
+ contentLength: rawContent.length,
169
+ inject: false,
170
+ reason: 'budget-skip',
171
+ }, config?.analytics);
77
172
  return { inject: false, budgetAction: 'skip' };
78
173
  }
174
+ logInjectionEvent(projectPath, {
175
+ source: 'spec-injector',
176
+ agentType,
177
+ categories: allCategories,
178
+ specCount: totalCount,
179
+ budgetAction: budget.action,
180
+ contentLength: budget.content?.length ?? 0,
181
+ inject: true,
182
+ }, config?.analytics);
79
183
  return {
80
184
  inject: true,
81
185
  content: budget.content,
@@ -110,4 +214,22 @@ function resolveCategories(agentType, config) {
110
214
  }
111
215
  return AGENT_CATEGORY_MAP[agentType] ?? null;
112
216
  }
217
+ /**
218
+ * Merge keyword filters from agent-level and global-level config.
219
+ * Agent-level include replaces global include; excludes are merged.
220
+ */
221
+ function resolveKeywordFilters(agentType, config) {
222
+ if (!config)
223
+ return {};
224
+ const agentMapping = config.mapping?.[agentType];
225
+ const globalFilters = config.keywordFilters;
226
+ const include = agentMapping?.includeKeywords ?? globalFilters?.include;
227
+ const agentExclude = agentMapping?.excludeKeywords ?? [];
228
+ const globalExclude = globalFilters?.exclude ?? [];
229
+ const mergedExclude = [...agentExclude, ...globalExclude];
230
+ return {
231
+ include: include?.length ? include : undefined,
232
+ exclude: mergedExclude.length > 0 ? mergedExclude : undefined,
233
+ };
234
+ }
113
235
  //# 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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"}
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"spec-loader.d.ts","sourceRoot":"","sources":["../../../src/tools/spec-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,IAAI,CAAC;AAE/F,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEnE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CASrD,CAAC;AAGF,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAcvD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAW1F;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,cAAc,CAqDrK"}
1
+ {"version":3,"file":"spec-loader.d.ts","sourceRoot":"","sources":["../../../src/tools/spec-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,IAAI,CAAC;AAE/F,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEnE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CASrD,CAAC;AAGF,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAcvD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAW1F;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,wFAAwF;IACxF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,cAAc,CAqDrK;AA6WD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,eAAe,CA0BvF"}