zora-agent 0.9.3 → 0.9.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 (245) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +103 -92
  3. package/dist/cli/audit-commands.d.ts.map +1 -1
  4. package/dist/cli/audit-commands.js +3 -1
  5. package/dist/cli/audit-commands.js.map +1 -1
  6. package/dist/cli/daemon.js +86 -28
  7. package/dist/cli/daemon.js.map +1 -1
  8. package/dist/cli/edit-commands.d.ts.map +1 -1
  9. package/dist/cli/edit-commands.js +3 -1
  10. package/dist/cli/edit-commands.js.map +1 -1
  11. package/dist/cli/hook-commands.d.ts +9 -0
  12. package/dist/cli/hook-commands.d.ts.map +1 -0
  13. package/dist/cli/hook-commands.js +106 -0
  14. package/dist/cli/hook-commands.js.map +1 -0
  15. package/dist/cli/index.js +91 -36
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/init-command.d.ts.map +1 -1
  18. package/dist/cli/init-command.js +107 -8
  19. package/dist/cli/init-command.js.map +1 -1
  20. package/dist/cli/memory-commands.d.ts +1 -1
  21. package/dist/cli/memory-commands.d.ts.map +1 -1
  22. package/dist/cli/memory-commands.js +213 -1
  23. package/dist/cli/memory-commands.js.map +1 -1
  24. package/dist/cli/presets.d.ts.map +1 -1
  25. package/dist/cli/presets.js +2 -1
  26. package/dist/cli/presets.js.map +1 -1
  27. package/dist/cli/skill-commands.d.ts.map +1 -1
  28. package/dist/cli/skill-commands.js +4 -2
  29. package/dist/cli/skill-commands.js.map +1 -1
  30. package/dist/cli/steer-commands.d.ts.map +1 -1
  31. package/dist/cli/steer-commands.js +6 -4
  32. package/dist/cli/steer-commands.js.map +1 -1
  33. package/dist/cli/team-commands.d.ts.map +1 -1
  34. package/dist/cli/team-commands.js +3 -1
  35. package/dist/cli/team-commands.js.map +1 -1
  36. package/dist/config/defaults.d.ts.map +1 -1
  37. package/dist/config/defaults.js +12 -2
  38. package/dist/config/defaults.js.map +1 -1
  39. package/dist/config/loader.d.ts +23 -0
  40. package/dist/config/loader.d.ts.map +1 -1
  41. package/dist/config/loader.js +64 -3
  42. package/dist/config/loader.js.map +1 -1
  43. package/dist/config/policy-loader.d.ts +14 -0
  44. package/dist/config/policy-loader.d.ts.map +1 -1
  45. package/dist/config/policy-loader.js +33 -0
  46. package/dist/config/policy-loader.js.map +1 -1
  47. package/dist/dashboard/frontend/dist/assets/index-BcOGj1EF.css +1 -0
  48. package/dist/dashboard/frontend/dist/assets/index-BtiFO9YN.js +261 -0
  49. package/dist/dashboard/frontend/dist/assets/index-Cfjy5acU.css +1 -0
  50. package/dist/dashboard/frontend/dist/assets/index-D41hcjgc.js +253 -0
  51. package/dist/dashboard/frontend/dist/assets/index-D83BawFd.css +1 -0
  52. package/dist/dashboard/frontend/dist/assets/index-DAODjoxu.css +1 -0
  53. package/dist/dashboard/frontend/dist/assets/index-DB-Eu5oV.js +253 -0
  54. package/dist/dashboard/frontend/dist/assets/index-W0VVEDu6.js +253 -0
  55. package/dist/dashboard/frontend/dist/index.html +17 -0
  56. package/dist/dashboard/server.d.ts +19 -2
  57. package/dist/dashboard/server.d.ts.map +1 -1
  58. package/dist/dashboard/server.js +121 -20
  59. package/dist/dashboard/server.js.map +1 -1
  60. package/dist/hooks/hook-runner.d.ts +55 -0
  61. package/dist/hooks/hook-runner.d.ts.map +1 -0
  62. package/dist/hooks/hook-runner.js +120 -0
  63. package/dist/hooks/hook-runner.js.map +1 -0
  64. package/dist/hooks/hook-types.d.ts +82 -0
  65. package/dist/hooks/hook-types.d.ts.map +1 -0
  66. package/dist/hooks/hook-types.js +20 -0
  67. package/dist/hooks/hook-types.js.map +1 -0
  68. package/dist/hooks/index.d.ts +6 -0
  69. package/dist/hooks/index.d.ts.map +1 -0
  70. package/dist/hooks/index.js +6 -0
  71. package/dist/hooks/index.js.map +1 -0
  72. package/dist/memory/context-compressor.d.ts +108 -0
  73. package/dist/memory/context-compressor.d.ts.map +1 -0
  74. package/dist/memory/context-compressor.js +307 -0
  75. package/dist/memory/context-compressor.js.map +1 -0
  76. package/dist/memory/index.d.ts +1 -0
  77. package/dist/memory/index.d.ts.map +1 -1
  78. package/dist/memory/index.js +1 -0
  79. package/dist/memory/index.js.map +1 -1
  80. package/dist/memory/memory-manager.d.ts +88 -4
  81. package/dist/memory/memory-manager.d.ts.map +1 -1
  82. package/dist/memory/memory-manager.js +299 -7
  83. package/dist/memory/memory-manager.js.map +1 -1
  84. package/dist/memory/observation-store.d.ts +75 -0
  85. package/dist/memory/observation-store.d.ts.map +1 -0
  86. package/dist/memory/observation-store.js +162 -0
  87. package/dist/memory/observation-store.js.map +1 -0
  88. package/dist/memory/observer-worker.d.ts +34 -0
  89. package/dist/memory/observer-worker.d.ts.map +1 -0
  90. package/dist/memory/observer-worker.js +161 -0
  91. package/dist/memory/observer-worker.js.map +1 -0
  92. package/dist/memory/reflector-worker.d.ts +40 -0
  93. package/dist/memory/reflector-worker.d.ts.map +1 -0
  94. package/dist/memory/reflector-worker.js +185 -0
  95. package/dist/memory/reflector-worker.js.map +1 -0
  96. package/dist/memory/salience-scorer.d.ts +16 -6
  97. package/dist/memory/salience-scorer.d.ts.map +1 -1
  98. package/dist/memory/salience-scorer.js +42 -22
  99. package/dist/memory/salience-scorer.js.map +1 -1
  100. package/dist/memory/structured-memory.d.ts +36 -1
  101. package/dist/memory/structured-memory.d.ts.map +1 -1
  102. package/dist/memory/structured-memory.js +207 -8
  103. package/dist/memory/structured-memory.js.map +1 -1
  104. package/dist/memory/token-estimator.d.ts +31 -0
  105. package/dist/memory/token-estimator.d.ts.map +1 -0
  106. package/dist/memory/token-estimator.js +77 -0
  107. package/dist/memory/token-estimator.js.map +1 -0
  108. package/dist/memory/validation-pipeline.d.ts +37 -0
  109. package/dist/memory/validation-pipeline.d.ts.map +1 -0
  110. package/dist/memory/validation-pipeline.js +106 -0
  111. package/dist/memory/validation-pipeline.js.map +1 -0
  112. package/dist/orchestrator/auth-monitor.d.ts.map +1 -1
  113. package/dist/orchestrator/auth-monitor.js +3 -1
  114. package/dist/orchestrator/auth-monitor.js.map +1 -1
  115. package/dist/orchestrator/execution-loop.d.ts +23 -0
  116. package/dist/orchestrator/execution-loop.d.ts.map +1 -1
  117. package/dist/orchestrator/execution-loop.js +60 -19
  118. package/dist/orchestrator/execution-loop.js.map +1 -1
  119. package/dist/orchestrator/failover-controller.d.ts +26 -2
  120. package/dist/orchestrator/failover-controller.d.ts.map +1 -1
  121. package/dist/orchestrator/failover-controller.js +143 -23
  122. package/dist/orchestrator/failover-controller.js.map +1 -1
  123. package/dist/orchestrator/orchestrator.d.ts +70 -7
  124. package/dist/orchestrator/orchestrator.d.ts.map +1 -1
  125. package/dist/orchestrator/orchestrator.js +417 -92
  126. package/dist/orchestrator/orchestrator.js.map +1 -1
  127. package/dist/orchestrator/retry-queue.d.ts.map +1 -1
  128. package/dist/orchestrator/retry-queue.js +24 -9
  129. package/dist/orchestrator/retry-queue.js.map +1 -1
  130. package/dist/orchestrator/router.d.ts +16 -1
  131. package/dist/orchestrator/router.d.ts.map +1 -1
  132. package/dist/orchestrator/router.js +79 -20
  133. package/dist/orchestrator/router.js.map +1 -1
  134. package/dist/orchestrator/session-manager.d.ts +26 -1
  135. package/dist/orchestrator/session-manager.d.ts.map +1 -1
  136. package/dist/orchestrator/session-manager.js +88 -4
  137. package/dist/orchestrator/session-manager.js.map +1 -1
  138. package/dist/providers/circuit-breaker.d.ts +78 -0
  139. package/dist/providers/circuit-breaker.d.ts.map +1 -0
  140. package/dist/providers/circuit-breaker.js +129 -0
  141. package/dist/providers/circuit-breaker.js.map +1 -0
  142. package/dist/providers/claude-provider.d.ts +27 -11
  143. package/dist/providers/claude-provider.d.ts.map +1 -1
  144. package/dist/providers/claude-provider.js +164 -45
  145. package/dist/providers/claude-provider.js.map +1 -1
  146. package/dist/providers/gemini-provider.d.ts +9 -1
  147. package/dist/providers/gemini-provider.d.ts.map +1 -1
  148. package/dist/providers/gemini-provider.js +97 -48
  149. package/dist/providers/gemini-provider.js.map +1 -1
  150. package/dist/providers/index.d.ts +1 -0
  151. package/dist/providers/index.d.ts.map +1 -1
  152. package/dist/providers/index.js +1 -0
  153. package/dist/providers/index.js.map +1 -1
  154. package/dist/providers/ollama-provider.d.ts +7 -0
  155. package/dist/providers/ollama-provider.d.ts.map +1 -1
  156. package/dist/providers/ollama-provider.js +89 -18
  157. package/dist/providers/ollama-provider.js.map +1 -1
  158. package/dist/routines/heartbeat.d.ts +10 -2
  159. package/dist/routines/heartbeat.d.ts.map +1 -1
  160. package/dist/routines/heartbeat.js +42 -5
  161. package/dist/routines/heartbeat.js.map +1 -1
  162. package/dist/routines/routine-manager.d.ts.map +1 -1
  163. package/dist/routines/routine-manager.js +22 -15
  164. package/dist/routines/routine-manager.js.map +1 -1
  165. package/dist/security/audit-logger.d.ts.map +1 -1
  166. package/dist/security/audit-logger.js +5 -7
  167. package/dist/security/audit-logger.js.map +1 -1
  168. package/dist/security/policy-engine.d.ts +33 -17
  169. package/dist/security/policy-engine.d.ts.map +1 -1
  170. package/dist/security/policy-engine.js +68 -181
  171. package/dist/security/policy-engine.js.map +1 -1
  172. package/dist/security/policy-serializer.d.ts +19 -0
  173. package/dist/security/policy-serializer.d.ts.map +1 -0
  174. package/dist/security/policy-serializer.js +100 -0
  175. package/dist/security/policy-serializer.js.map +1 -0
  176. package/dist/security/shell-validator.d.ts +42 -0
  177. package/dist/security/shell-validator.d.ts.map +1 -0
  178. package/dist/security/shell-validator.js +231 -0
  179. package/dist/security/shell-validator.js.map +1 -0
  180. package/dist/skills/index.d.ts +1 -0
  181. package/dist/skills/index.d.ts.map +1 -1
  182. package/dist/skills/index.js +1 -0
  183. package/dist/skills/index.js.map +1 -1
  184. package/dist/skills/skill-loader.d.ts +38 -2
  185. package/dist/skills/skill-loader.d.ts.map +1 -1
  186. package/dist/skills/skill-loader.js +83 -2
  187. package/dist/skills/skill-loader.js.map +1 -1
  188. package/dist/skills/subagent-loader.d.ts +66 -0
  189. package/dist/skills/subagent-loader.d.ts.map +1 -0
  190. package/dist/skills/subagent-loader.js +143 -0
  191. package/dist/skills/subagent-loader.js.map +1 -0
  192. package/dist/steering/flag-manager.d.ts +20 -0
  193. package/dist/steering/flag-manager.d.ts.map +1 -1
  194. package/dist/steering/flag-manager.js +94 -11
  195. package/dist/steering/flag-manager.js.map +1 -1
  196. package/dist/steering/steering-manager.d.ts +11 -0
  197. package/dist/steering/steering-manager.d.ts.map +1 -1
  198. package/dist/steering/steering-manager.js +23 -0
  199. package/dist/steering/steering-manager.js.map +1 -1
  200. package/dist/steering/telegram-gateway.d.ts +4 -1
  201. package/dist/steering/telegram-gateway.d.ts.map +1 -1
  202. package/dist/steering/telegram-gateway.js +49 -10
  203. package/dist/steering/telegram-gateway.js.map +1 -1
  204. package/dist/teams/bridge-watchdog.d.ts.map +1 -1
  205. package/dist/teams/bridge-watchdog.js +5 -3
  206. package/dist/teams/bridge-watchdog.js.map +1 -1
  207. package/dist/teams/gemini-bridge.d.ts.map +1 -1
  208. package/dist/teams/gemini-bridge.js +9 -4
  209. package/dist/teams/gemini-bridge.js.map +1 -1
  210. package/dist/tools/index.d.ts +2 -0
  211. package/dist/tools/index.d.ts.map +1 -1
  212. package/dist/tools/index.js +2 -0
  213. package/dist/tools/index.js.map +1 -1
  214. package/dist/tools/memory-tools.d.ts +16 -0
  215. package/dist/tools/memory-tools.d.ts.map +1 -0
  216. package/dist/tools/memory-tools.js +207 -0
  217. package/dist/tools/memory-tools.js.map +1 -0
  218. package/dist/tools/notifications.d.ts.map +1 -1
  219. package/dist/tools/notifications.js +3 -1
  220. package/dist/tools/notifications.js.map +1 -1
  221. package/dist/tools/tool-factory.d.ts +36 -0
  222. package/dist/tools/tool-factory.d.ts.map +1 -0
  223. package/dist/tools/tool-factory.js +55 -0
  224. package/dist/tools/tool-factory.js.map +1 -0
  225. package/dist/types.d.ts +213 -1
  226. package/dist/types.d.ts.map +1 -1
  227. package/dist/types.js +47 -1
  228. package/dist/types.js.map +1 -1
  229. package/dist/utils/errors.d.ts +21 -0
  230. package/dist/utils/errors.d.ts.map +1 -0
  231. package/dist/utils/errors.js +29 -0
  232. package/dist/utils/errors.js.map +1 -0
  233. package/dist/utils/event-filter.d.ts +25 -0
  234. package/dist/utils/event-filter.d.ts.map +1 -0
  235. package/dist/utils/event-filter.js +61 -0
  236. package/dist/utils/event-filter.js.map +1 -0
  237. package/dist/utils/logger.d.ts +33 -36
  238. package/dist/utils/logger.d.ts.map +1 -1
  239. package/dist/utils/logger.js +60 -130
  240. package/dist/utils/logger.js.map +1 -1
  241. package/dist/utils/validate-job-id.d.ts +6 -0
  242. package/dist/utils/validate-job-id.d.ts.map +1 -0
  243. package/dist/utils/validate-job-id.js +10 -0
  244. package/dist/utils/validate-job-id.js.map +1 -0
  245. package/package.json +12 -3
@@ -0,0 +1,66 @@
1
+ /**
2
+ * SubagentLoader — Discovers and loads subagent definitions from filesystem.
3
+ *
4
+ * TYPE-10: Subagents are defined in SUBAGENT.md files within directory hierarchies:
5
+ * 1. Project — `.zora/subagents/<name>/SUBAGENT.md`
6
+ * 2. Global — `~/.zora/subagents/<name>/SUBAGENT.md`
7
+ *
8
+ * Each subagent definition specifies:
9
+ * - name: unique identifier
10
+ * - description: what the subagent does
11
+ * - allowedTools: subset of tools the subagent can use
12
+ * - systemPrompt: optional system prompt override
13
+ *
14
+ * Subagent isolation rules (from ia-agents pattern):
15
+ * - Each subagent gets its own execution context
16
+ * - Declared tool subset (not the full tool set)
17
+ * - No access to parent conversation history
18
+ * - Cannot spawn nested subagents (delegate_to_subagent is excluded)
19
+ */
20
+ import type { SkillLayer } from './skill-loader.js';
21
+ export interface SubagentInfo {
22
+ name: string;
23
+ description: string;
24
+ allowedTools: string[];
25
+ systemPrompt: string;
26
+ path: string;
27
+ layer: SkillLayer;
28
+ }
29
+ /**
30
+ * Parses YAML frontmatter from a SUBAGENT.md file.
31
+ * Extracts: description, allowed_tools (comma-separated), system_prompt.
32
+ * The body of the markdown (after frontmatter) becomes the system prompt
33
+ * if no explicit system_prompt frontmatter field is present.
34
+ */
35
+ export declare function parseSubagentFrontmatter(content: string): {
36
+ description: string;
37
+ allowedTools: string[];
38
+ systemPrompt: string;
39
+ };
40
+ /**
41
+ * Returns subagent layer directories in precedence order.
42
+ * Only project and global layers — no built-in subagents.
43
+ */
44
+ export declare function getSubagentLayers(cwd?: string): Array<{
45
+ dir: string;
46
+ layer: SkillLayer;
47
+ }>;
48
+ /**
49
+ * Loads subagent definitions from project and global layers.
50
+ * First-match-wins deduplication (project overrides global).
51
+ *
52
+ * Subagent isolation is enforced:
53
+ * - Tools like 'delegate_to_subagent' are always stripped from allowedTools
54
+ * - Each subagent should be spawned with its own execution context
55
+ *
56
+ * @param options.cwd Override for project directory
57
+ * @param options.layers Override layer directories (useful for testing)
58
+ */
59
+ export declare function loadSubagents(options?: {
60
+ cwd?: string;
61
+ layers?: Array<{
62
+ dir: string;
63
+ layer: SkillLayer;
64
+ }>;
65
+ }): Promise<SubagentInfo[]>;
66
+ //# sourceMappingURL=subagent-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-loader.d.ts","sourceRoot":"","sources":["../../src/skills/subagent-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;CACnB;AAID;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,CAsCA;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC,CAQzF;AAkDD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CACpD,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgB1B"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * SubagentLoader — Discovers and loads subagent definitions from filesystem.
3
+ *
4
+ * TYPE-10: Subagents are defined in SUBAGENT.md files within directory hierarchies:
5
+ * 1. Project — `.zora/subagents/<name>/SUBAGENT.md`
6
+ * 2. Global — `~/.zora/subagents/<name>/SUBAGENT.md`
7
+ *
8
+ * Each subagent definition specifies:
9
+ * - name: unique identifier
10
+ * - description: what the subagent does
11
+ * - allowedTools: subset of tools the subagent can use
12
+ * - systemPrompt: optional system prompt override
13
+ *
14
+ * Subagent isolation rules (from ia-agents pattern):
15
+ * - Each subagent gets its own execution context
16
+ * - Declared tool subset (not the full tool set)
17
+ * - No access to parent conversation history
18
+ * - Cannot spawn nested subagents (delegate_to_subagent is excluded)
19
+ */
20
+ import fs from 'node:fs/promises';
21
+ import path from 'node:path';
22
+ import os from 'node:os';
23
+ // ─── Frontmatter Parser ─────────────────────────────────────────────
24
+ /**
25
+ * Parses YAML frontmatter from a SUBAGENT.md file.
26
+ * Extracts: description, allowed_tools (comma-separated), system_prompt.
27
+ * The body of the markdown (after frontmatter) becomes the system prompt
28
+ * if no explicit system_prompt frontmatter field is present.
29
+ */
30
+ export function parseSubagentFrontmatter(content) {
31
+ const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)/);
32
+ if (!match) {
33
+ return { description: '', allowedTools: [], systemPrompt: content.trim() };
34
+ }
35
+ const frontmatter = match[1];
36
+ const body = match[2]?.trim() ?? '';
37
+ let description = '';
38
+ let allowedTools = [];
39
+ let systemPrompt = '';
40
+ for (const line of frontmatter.split('\n')) {
41
+ const colonIdx = line.indexOf(':');
42
+ if (colonIdx <= 0)
43
+ continue;
44
+ const key = line.slice(0, colonIdx).trim();
45
+ const value = line.slice(colonIdx + 1).trim();
46
+ switch (key) {
47
+ case 'description':
48
+ description = value;
49
+ break;
50
+ case 'allowed_tools':
51
+ allowedTools = value.split(',').map(t => t.trim()).filter(Boolean);
52
+ break;
53
+ case 'system_prompt':
54
+ systemPrompt = value;
55
+ break;
56
+ }
57
+ }
58
+ // Body becomes system prompt if no explicit system_prompt in frontmatter
59
+ if (!systemPrompt && body) {
60
+ systemPrompt = body;
61
+ }
62
+ return { description, allowedTools, systemPrompt };
63
+ }
64
+ // ─── Layer Directories ──────────────────────────────────────────────
65
+ /**
66
+ * Returns subagent layer directories in precedence order.
67
+ * Only project and global layers — no built-in subagents.
68
+ */
69
+ export function getSubagentLayers(cwd) {
70
+ const projectDir = path.join(cwd ?? process.cwd(), '.zora', 'subagents');
71
+ const globalDir = path.join(os.homedir(), '.zora', 'subagents');
72
+ return [
73
+ { dir: projectDir, layer: 'project' },
74
+ { dir: globalDir, layer: 'global' },
75
+ ];
76
+ }
77
+ // ─── Subagent Scanner ───────────────────────────────────────────────
78
+ /** Blocked tools that subagents can never use (nesting prevention). */
79
+ const BLOCKED_SUBAGENT_TOOLS = ['delegate_to_subagent', 'spawn_subagent'];
80
+ /**
81
+ * Scans a single directory for SUBAGENT.md files.
82
+ */
83
+ async function scanSubagentLayer(dir, layer) {
84
+ const subagents = [];
85
+ let entries;
86
+ try {
87
+ entries = await fs.readdir(dir);
88
+ }
89
+ catch {
90
+ return subagents;
91
+ }
92
+ for (const entry of entries) {
93
+ const subagentPath = path.join(dir, entry, 'SUBAGENT.md');
94
+ try {
95
+ const stat = await fs.stat(path.join(dir, entry));
96
+ if (!stat.isDirectory())
97
+ continue;
98
+ const content = await fs.readFile(subagentPath, 'utf-8');
99
+ const parsed = parseSubagentFrontmatter(content);
100
+ // Filter out blocked tools (nesting prevention)
101
+ const allowedTools = parsed.allowedTools.filter(t => !BLOCKED_SUBAGENT_TOOLS.includes(t));
102
+ subagents.push({
103
+ name: entry,
104
+ description: parsed.description || `Subagent: ${entry}`,
105
+ allowedTools,
106
+ systemPrompt: parsed.systemPrompt,
107
+ path: subagentPath,
108
+ layer,
109
+ });
110
+ }
111
+ catch {
112
+ // Skip directories without SUBAGENT.md
113
+ }
114
+ }
115
+ return subagents;
116
+ }
117
+ /**
118
+ * Loads subagent definitions from project and global layers.
119
+ * First-match-wins deduplication (project overrides global).
120
+ *
121
+ * Subagent isolation is enforced:
122
+ * - Tools like 'delegate_to_subagent' are always stripped from allowedTools
123
+ * - Each subagent should be spawned with its own execution context
124
+ *
125
+ * @param options.cwd Override for project directory
126
+ * @param options.layers Override layer directories (useful for testing)
127
+ */
128
+ export async function loadSubagents(options) {
129
+ const layers = options?.layers ?? getSubagentLayers(options?.cwd);
130
+ const seen = new Set();
131
+ const result = [];
132
+ for (const { dir, layer } of layers) {
133
+ const subagents = await scanSubagentLayer(dir, layer);
134
+ for (const subagent of subagents) {
135
+ if (!seen.has(subagent.name)) {
136
+ seen.add(subagent.name);
137
+ result.push(subagent);
138
+ }
139
+ }
140
+ }
141
+ return result.sort((a, b) => a.name.localeCompare(b.name));
142
+ }
143
+ //# sourceMappingURL=subagent-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-loader.js","sourceRoot":"","sources":["../../src/skills/subagent-loader.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,19 @@ export interface FlagEntry {
16
16
  timestamp: string;
17
17
  resolvedAt?: string;
18
18
  }
19
+ export interface FlagFileDiagnostic {
20
+ file: string;
21
+ status: 'loaded' | 'failed';
22
+ errorType?: 'not_found' | 'permission' | 'parse_error' | 'read_error';
23
+ reason?: string;
24
+ timestamp: number;
25
+ }
26
+ export interface FlagConfigStatus {
27
+ filesLoaded: number;
28
+ filesFailed: number;
29
+ failedFiles: FlagFileDiagnostic[];
30
+ timestamp: number;
31
+ }
19
32
  export interface FlagManagerOptions {
20
33
  timeoutMs: number;
21
34
  notifyFn?: (msg: string) => void;
@@ -25,7 +38,14 @@ export declare class FlagManager {
25
38
  private readonly _timeoutMs;
26
39
  private readonly _notifyFn?;
27
40
  private readonly _timers;
41
+ private readonly _diagnostics;
42
+ private _filesLoaded;
43
+ private _filesFailed;
28
44
  constructor(flagsDir: string, options: FlagManagerOptions);
45
+ /**
46
+ * Returns diagnostic status of flag file loading operations.
47
+ */
48
+ getConfigStatus(): FlagConfigStatus;
29
49
  /**
30
50
  * Creates a new flag for a decision. Starts the timeout clock.
31
51
  */
@@ -1 +1 @@
1
- {"version":3,"file":"flag-manager.d.ts","sourceRoot":"","sources":["../../src/steering/flag-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,gBAAgB,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAwB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyD;gBAErE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;IAMzD;;OAEG;IACG,IAAI,CACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC;IA+BlB;;OAEG;IACG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IA6BpD;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;YAerE,QAAQ;YAmCR,YAAY;CAqB3B"}
1
+ {"version":3,"file":"flag-manager.d.ts","sourceRoot":"","sources":["../../src/steering/flag-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,gBAAgB,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,SAAS,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAwB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyD;IACjF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA4B;IACzD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;gBAEb,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;IAMzD;;OAEG;IACH,eAAe,IAAI,gBAAgB;IASnC;;OAEG;IACG,IAAI,CACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC;IAgClB;;OAEG;IACG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAmEpD;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;YAgCrE,QAAQ;YA2CR,YAAY;CAgC3B"}
@@ -9,20 +9,37 @@
9
9
  import fs from 'node:fs/promises';
10
10
  import path from 'node:path';
11
11
  import { writeAtomic } from '../utils/fs.js';
12
+ import { getLogger } from '../utils/logger.js';
13
+ import { validateJobId } from '../utils/validate-job-id.js';
12
14
  export class FlagManager {
13
15
  _flagsDir;
14
16
  _timeoutMs;
15
17
  _notifyFn;
16
18
  _timers = new Map();
19
+ _diagnostics = [];
20
+ _filesLoaded = 0;
21
+ _filesFailed = 0;
17
22
  constructor(flagsDir, options) {
18
23
  this._flagsDir = flagsDir;
19
24
  this._timeoutMs = options.timeoutMs;
20
25
  this._notifyFn = options.notifyFn;
21
26
  }
27
+ /**
28
+ * Returns diagnostic status of flag file loading operations.
29
+ */
30
+ getConfigStatus() {
31
+ return {
32
+ filesLoaded: this._filesLoaded,
33
+ filesFailed: this._filesFailed,
34
+ failedFiles: this._diagnostics.filter(d => d.status === 'failed'),
35
+ timestamp: Date.now(),
36
+ };
37
+ }
22
38
  /**
23
39
  * Creates a new flag for a decision. Starts the timeout clock.
24
40
  */
25
41
  async flag(jobId, question, defaultAction) {
42
+ validateJobId(jobId);
26
43
  await fs.mkdir(this._flagsDir, { recursive: true });
27
44
  const flagId = `flag_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
28
45
  const entry = {
@@ -50,30 +67,64 @@ export class FlagManager {
50
67
  * Lists all flags, optionally filtered by job ID.
51
68
  */
52
69
  async getFlags(jobId) {
70
+ const logger = getLogger();
53
71
  try {
54
72
  const files = await fs.readdir(this._flagsDir);
55
73
  const flags = [];
56
74
  for (const file of files) {
57
75
  if (!file.endsWith('.json'))
58
76
  continue;
77
+ const filePath = path.join(this._flagsDir, file);
59
78
  try {
60
- const content = await fs.readFile(path.join(this._flagsDir, file), 'utf8');
79
+ const content = await fs.readFile(filePath, 'utf8');
61
80
  const entry = JSON.parse(content);
62
81
  if (!jobId || entry.jobId === jobId) {
63
82
  flags.push(entry);
64
83
  }
84
+ this._filesLoaded++;
85
+ this._diagnostics.push({ file, status: 'loaded', timestamp: Date.now() });
65
86
  }
66
87
  catch (err) {
67
- // R30: Log malformed flag files instead of silently skipping
68
- console.warn(`[FlagManager] Failed to read flag file ${file}:`, err instanceof Error ? err.message : String(err));
88
+ const errMsg = err instanceof Error ? err.message : String(err);
89
+ const code = err.code;
90
+ const errorType = err instanceof SyntaxError
91
+ ? 'parse_error'
92
+ : code === 'ENOENT'
93
+ ? 'not_found'
94
+ : code === 'EACCES'
95
+ ? 'permission'
96
+ : 'read_error';
97
+ logger.warn({ path: filePath, errorType, error: errMsg }, 'Failed to load flag file');
98
+ this._filesFailed++;
99
+ this._diagnostics.push({
100
+ file,
101
+ status: 'failed',
102
+ errorType,
103
+ reason: errMsg,
104
+ timestamp: Date.now(),
105
+ });
69
106
  }
70
107
  }
71
108
  return flags;
72
109
  }
73
110
  catch (err) {
74
- // R30: Log directory read errors instead of silently returning empty
75
- if (err.code !== 'ENOENT') {
76
- console.warn(`[FlagManager] Failed to read flags directory:`, err instanceof Error ? err.message : String(err));
111
+ const code = err.code;
112
+ if (code !== 'ENOENT') {
113
+ const errMsg = err instanceof Error ? err.message : String(err);
114
+ const errorType = code === 'ENOENT'
115
+ ? 'not_found'
116
+ : code === 'EACCES'
117
+ ? 'permission'
118
+ : 'read_error';
119
+ logger.warn({ path: this._flagsDir, errorType, error: errMsg }, 'Failed to read flags directory');
120
+ this._filesFailed++;
121
+ this._diagnostics.push({
122
+ file: this._flagsDir,
123
+ status: 'failed',
124
+ errorType,
125
+ reason: errMsg,
126
+ timestamp: Date.now(),
127
+ });
77
128
  }
78
129
  return [];
79
130
  }
@@ -94,6 +145,7 @@ export class FlagManager {
94
145
  * Returns the current decision status for a flag.
95
146
  */
96
147
  async getFlagDecision(flagId) {
148
+ const logger = getLogger();
97
149
  const flagPath = path.join(this._flagsDir, `${flagId}.json`);
98
150
  try {
99
151
  const content = await fs.readFile(flagPath, 'utf8');
@@ -105,8 +157,21 @@ export class FlagManager {
105
157
  return 'rejected';
106
158
  }
107
159
  catch (err) {
108
- // R30: Log flag read errors instead of silently defaulting
109
- console.warn(`[FlagManager] Failed to read flag ${flagId}:`, err instanceof Error ? err.message : String(err));
160
+ const errMsg = err instanceof Error ? err.message : String(err);
161
+ const code = err.code;
162
+ const errorType = err instanceof SyntaxError
163
+ ? 'parse_error'
164
+ : code === 'ENOENT'
165
+ ? 'not_found'
166
+ : 'read_error';
167
+ logger.warn({ flagId, path: flagPath, errorType, error: errMsg }, 'Failed to read flag decision');
168
+ this._diagnostics.push({
169
+ file: `${flagId}.json`,
170
+ status: 'failed',
171
+ errorType,
172
+ reason: errMsg,
173
+ timestamp: Date.now(),
174
+ });
110
175
  return 'pending';
111
176
  }
112
177
  }
@@ -117,6 +182,7 @@ export class FlagManager {
117
182
  clearTimeout(timer);
118
183
  this._timers.delete(flagId);
119
184
  }
185
+ const logger = getLogger();
120
186
  const flagPath = path.join(this._flagsDir, `${flagId}.json`);
121
187
  let content;
122
188
  try {
@@ -125,7 +191,15 @@ export class FlagManager {
125
191
  catch {
126
192
  throw new Error(`Flag not found: ${flagId}`);
127
193
  }
128
- const entry = JSON.parse(content);
194
+ let entry;
195
+ try {
196
+ entry = JSON.parse(content);
197
+ }
198
+ catch (err) {
199
+ const errMsg = err instanceof Error ? err.message : String(err);
200
+ logger.warn({ flagId, path: flagPath, errorType: 'parse_error', error: errMsg }, 'Corrupted flag file during resolve');
201
+ throw new Error(`Corrupted flag file: ${flagId}`);
202
+ }
129
203
  // Only resolve if still pending to avoid TOCTOU race
130
204
  if (entry.status !== 'pending_review') {
131
205
  return; // Already resolved
@@ -138,6 +212,7 @@ export class FlagManager {
138
212
  await writeAtomic(flagPath, JSON.stringify(entry, null, 2));
139
213
  }
140
214
  async _autoResolve(flagId, defaultAction) {
215
+ const logger = getLogger();
141
216
  this._timers.delete(flagId);
142
217
  const flagPath = path.join(this._flagsDir, `${flagId}.json`);
143
218
  try {
@@ -152,8 +227,16 @@ export class FlagManager {
152
227
  await writeAtomic(flagPath, JSON.stringify(entry, null, 2));
153
228
  }
154
229
  catch (err) {
155
- // R30: Log auto-resolve errors instead of silently swallowing
156
- console.warn(`[FlagManager] Failed to auto-resolve flag ${flagId}:`, err instanceof Error ? err.message : String(err));
230
+ const errMsg = err instanceof Error ? err.message : String(err);
231
+ const errorType = err instanceof SyntaxError ? 'parse_error' : 'read_error';
232
+ logger.warn({ flagId, path: flagPath, errorType, error: errMsg }, 'Failed to auto-resolve flag');
233
+ this._diagnostics.push({
234
+ file: `${flagId}.json`,
235
+ status: 'failed',
236
+ errorType,
237
+ reason: errMsg,
238
+ timestamp: Date.now(),
239
+ });
157
240
  }
158
241
  }
159
242
  }
@@ -1 +1 @@
1
- {"version":3,"file":"flag-manager.js","sourceRoot":"","sources":["../../src/steering/flag-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flag-manager.js","sourceRoot":"","sources":["../../src/steering/flag-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAiC5D,MAAM,OAAO,WAAW;IACL,SAAS,CAAS;IAClB,UAAU,CAAS;IACnB,SAAS,CAAyB;IAClC,OAAO,GAA+C,IAAI,GAAG,EAAE,CAAC;IAChE,YAAY,GAAyB,EAAE,CAAC;IACjD,YAAY,GAAG,CAAC,CAAC;IACjB,YAAY,GAAG,CAAC,CAAC;IAEzB,YAAY,QAAgB,EAAE,OAA2B;QACvD,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;YACjE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CACR,KAAa,EACb,QAAgB,EAChB,aAAqB;QAErB,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAE9E,MAAM,KAAK,GAAc;YACvB,MAAM;YACN,KAAK;YACL,QAAQ;YACR,aAAa;YACb,YAAY,EAAE,aAAa;YAC3B,MAAM,EAAE,gBAAgB;YACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;QAC7D,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAE5D,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC,SAAS,CAAC,wBAAwB,KAAK,KAAK,QAAQ,cAAc,aAAa,GAAG,CAAC,CAAC;QAC3F,CAAC;QAED,sBAAsB;QACtB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAChD,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAc;QAC3B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAgB,EAAE,CAAC;YAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAAE,SAAS;gBACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBACjD,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;oBACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC;oBAC/C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;wBACpC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACpB,CAAC;oBACD,IAAI,CAAC,YAAY,EAAE,CAAC;oBACpB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC5E,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAChE,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;oBACjD,MAAM,SAAS,GAAG,GAAG,YAAY,WAAW;wBAC1C,CAAC,CAAC,aAAsB;wBACxB,CAAC,CAAC,IAAI,KAAK,QAAQ;4BACjB,CAAC,CAAC,WAAoB;4BACtB,CAAC,CAAC,IAAI,KAAK,QAAQ;gCACjB,CAAC,CAAC,YAAqB;gCACvB,CAAC,CAAC,YAAqB,CAAC;oBAE9B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,0BAA0B,CAAC,CAAC;oBAEtF,IAAI,CAAC,YAAY,EAAE,CAAC;oBACpB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;wBACrB,IAAI;wBACJ,MAAM,EAAE,QAAQ;wBAChB,SAAS;wBACT,MAAM,EAAE,MAAM;wBACd,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;qBACtB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;YACjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAChE,MAAM,SAAS,GAAG,IAAI,KAAK,QAAQ;oBACjC,CAAC,CAAC,WAAoB;oBACtB,CAAC,CAAC,IAAI,KAAK,QAAQ;wBACjB,CAAC,CAAC,YAAqB;wBACvB,CAAC,CAAC,YAAqB,CAAC;gBAE5B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gCAAgC,CAAC,CAAC;gBAElG,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS;oBACpB,MAAM,EAAE,QAAQ;oBAChB,SAAS;oBACT,MAAM,EAAE,MAAM;oBACd,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC,CAAC;YACL,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,MAAc;QACzC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,MAAc;QAClC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC;YAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB;gBAAE,OAAO,SAAS,CAAC;YACxD,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;gBAAE,OAAO,UAAU,CAAC;YACnF,OAAO,UAAU,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;YACjD,MAAM,SAAS,GAAG,GAAG,YAAY,WAAW;gBAC1C,CAAC,CAAC,aAAsB;gBACxB,CAAC,CAAC,IAAI,KAAK,QAAQ;oBACjB,CAAC,CAAC,WAAoB;oBACtB,CAAC,CAAC,YAAqB,CAAC;YAE5B,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,8BAA8B,CAAC,CAAC;YAElG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBACrB,IAAI,EAAE,GAAG,MAAM,OAAO;gBACtB,MAAM,EAAE,QAAQ;gBAChB,SAAS;gBACT,MAAM,EAAE,MAAM;gBACd,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ,CACpB,MAAc,EACd,MAA+B,EAC/B,MAAe;QAEf,uBAAuB;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;QAC7D,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,KAAgB,CAAC;QACrB,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,oCAAoC,CAAC,CAAC;YACvH,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,qDAAqD;QACrD,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;YACtC,OAAO,CAAC,mBAAmB;QAC7B,CAAC;QAED,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACtB,KAAK,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5C,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC;QAC9B,CAAC;QAED,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,aAAqB;QAC9D,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC;YAE/C,qCAAqC;YACrC,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB;gBAAE,OAAO;YAE9C,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC;YAC3B,KAAK,CAAC,YAAY,GAAG,aAAa,CAAC;YACnC,KAAK,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAE5C,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,MAAM,SAAS,GAAG,GAAG,YAAY,WAAW,CAAC,CAAC,CAAC,aAAsB,CAAC,CAAC,CAAC,YAAqB,CAAC;YAE9F,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,6BAA6B,CAAC,CAAC;YAEjG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBACrB,IAAI,EAAE,GAAG,MAAM,OAAO;gBACtB,MAAM,EAAE,QAAQ;gBAChB,SAAS;gBACT,MAAM,EAAE,MAAM;gBACd,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
@@ -9,6 +9,8 @@
9
9
  import type { SteeringMessage } from './types.js';
10
10
  export declare class SteeringManager {
11
11
  private readonly _steeringDir;
12
+ /** Debounce cache for getPendingMessages — avoids per-event readdir calls. */
13
+ private _pendingCache;
12
14
  constructor(baseDir?: string);
13
15
  /**
14
16
  * Initializes the steering directory.
@@ -24,6 +26,15 @@ export declare class SteeringManager {
24
26
  getPendingMessages(jobId: string): Promise<(SteeringMessage & {
25
27
  id: string;
26
28
  })[]>;
29
+ /**
30
+ * Returns cached pending messages if the last poll was within maxAgeMs.
31
+ * Avoids per-event readdir + file read during streaming.
32
+ */
33
+ cachedGetPendingMessages(jobId: string, maxAgeMs?: number): Promise<(SteeringMessage & {
34
+ id: string;
35
+ })[]>;
36
+ /** Invalidate the pending messages cache for a job (call after archiving). */
37
+ invalidatePendingCache(jobId: string): void;
27
38
  /**
28
39
  * Acknowledges or archives a steering message.
29
40
  */
@@ -1 +1 @@
1
- {"version":3,"file":"steering-manager.d.ts","sourceRoot":"","sources":["../../src/steering/steering-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EACV,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,OAAO,GAAE,MAAyC;IAI9D;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAc9D;;OAEG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,eAAe,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAmBtF;;OAEG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAavD,OAAO;CAQtB"}
1
+ {"version":3,"file":"steering-manager.d.ts","sourceRoot":"","sources":["../../src/steering/steering-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EACV,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,8EAA8E;IAC9E,OAAO,CAAC,aAAa,CAAiG;gBAE1G,OAAO,GAAE,MAAyC;IAI9D;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAe9D;;OAEG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,eAAe,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAoBtF;;;OAGG;IACG,wBAAwB,CAC5B,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,MAAa,GACtB,OAAO,CAAC,CAAC,eAAe,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAWhD,8EAA8E;IAC9E,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3C;;OAEG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAcvD,OAAO;CAQtB"}
@@ -10,8 +10,11 @@ import path from 'node:path';
10
10
  import os from 'node:os';
11
11
  import fs from 'node:fs/promises';
12
12
  import { writeAtomic } from '../utils/fs.js';
13
+ import { validateJobId } from '../utils/validate-job-id.js';
13
14
  export class SteeringManager {
14
15
  _steeringDir;
16
+ /** Debounce cache for getPendingMessages — avoids per-event readdir calls. */
17
+ _pendingCache = new Map();
15
18
  constructor(baseDir = path.join(os.homedir(), '.zora')) {
16
19
  this._steeringDir = path.join(baseDir, 'steering');
17
20
  }
@@ -27,6 +30,7 @@ export class SteeringManager {
27
30
  * Injects a steering message for a specific job.
28
31
  */
29
32
  async injectMessage(message) {
33
+ validateJobId(message.jobId);
30
34
  const messageId = `steer_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
31
35
  const jobDir = path.join(this._steeringDir, message.jobId);
32
36
  if (!(await this._exists(jobDir))) {
@@ -40,6 +44,7 @@ export class SteeringManager {
40
44
  * Retrieves all unread/pending steering messages for a job.
41
45
  */
42
46
  async getPendingMessages(jobId) {
47
+ validateJobId(jobId);
43
48
  const jobDir = path.join(this._steeringDir, jobId);
44
49
  if (!(await this._exists(jobDir)))
45
50
  return [];
@@ -53,10 +58,28 @@ export class SteeringManager {
53
58
  }
54
59
  return messages.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
55
60
  }
61
+ /**
62
+ * Returns cached pending messages if the last poll was within maxAgeMs.
63
+ * Avoids per-event readdir + file read during streaming.
64
+ */
65
+ async cachedGetPendingMessages(jobId, maxAgeMs = 2000) {
66
+ const cached = this._pendingCache.get(jobId);
67
+ if (cached && (Date.now() - cached.timestamp) < maxAgeMs) {
68
+ return cached.messages;
69
+ }
70
+ const messages = await this.getPendingMessages(jobId);
71
+ this._pendingCache.set(jobId, { messages, timestamp: Date.now() });
72
+ return messages;
73
+ }
74
+ /** Invalidate the pending messages cache for a job (call after archiving). */
75
+ invalidatePendingCache(jobId) {
76
+ this._pendingCache.delete(jobId);
77
+ }
56
78
  /**
57
79
  * Acknowledges or archives a steering message.
58
80
  */
59
81
  async archiveMessage(jobId, messageId) {
82
+ validateJobId(jobId);
60
83
  const messagePath = path.join(this._steeringDir, jobId, `${messageId}.json`);
61
84
  const archiveDir = path.join(this._steeringDir, jobId, 'archive');
62
85
  if (!(await this._exists(archiveDir))) {
@@ -1 +1 @@
1
- {"version":3,"file":"steering-manager.js","sourceRoot":"","sources":["../../src/steering/steering-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"steering-manager.js","sourceRoot":"","sources":["../../src/steering/steering-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAK5D,MAAM,OAAO,eAAe;IACT,YAAY,CAAS;IACtC,8EAA8E;IACtE,aAAa,GAAuF,IAAI,GAAG,EAAE,CAAC;IAEtH,YAAY,UAAkB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC;QAC5D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,OAAwB;QAC1C,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,SAAS,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAClF,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAE3D,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAClC,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;QAC3D,MAAM,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEvF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,kBAAkB,CAAC,KAAa;QACpC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QAE7C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,EAAE,CAAC;QAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;gBACnE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC5B,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAClE,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,wBAAwB,CAC5B,KAAa,EACb,WAAmB,IAAI;QAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,QAAQ,EAAE,CAAC;YACzD,OAAO,MAAM,CAAC,QAAQ,CAAC;QACzB,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,8EAA8E;IAC9E,sBAAsB,CAAC,KAAa;QAClC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,KAAa,EAAE,SAAiB;QACnD,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;QAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAElE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YACtC,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YACpC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
@@ -7,22 +7,25 @@
7
7
  * - Injects steer messages into SteeringManager.
8
8
  */
9
9
  import type { SteeringManager } from './steering-manager.js';
10
+ import type { SessionManager } from '../orchestrator/session-manager.js';
10
11
  import type { SteeringConfig } from '../types.js';
11
12
  export interface TelegramConfig extends SteeringConfig {
12
13
  bot_token?: string;
13
14
  allowed_users: string[];
14
15
  enabled: boolean;
16
+ mode?: 'polling' | 'webhook';
15
17
  }
16
18
  export declare class TelegramGateway {
17
19
  private readonly _bot;
18
20
  private readonly _steeringManager;
21
+ private readonly _sessionManager?;
19
22
  private readonly _allowedUsers;
20
23
  private constructor();
21
24
  /**
22
25
  * Factory method — loads node-telegram-bot-api dynamically.
23
26
  * Throws a clear error if the optional dep isn't installed.
24
27
  */
25
- static create(config: TelegramConfig, steeringManager: SteeringManager): Promise<TelegramGateway>;
28
+ static create(config: TelegramConfig, steeringManager: SteeringManager, sessionManager?: SessionManager): Promise<TelegramGateway>;
26
29
  private _setupHandlers;
27
30
  /**
28
31
  * Stops the bot.
@@ -1 +1 @@
1
- {"version":3,"file":"telegram-gateway.d.ts","sourceRoot":"","sources":["../../src/steering/telegram-gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAc;IAE5C,OAAO;IAQP;;;OAGG;WACU,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAqBvG,OAAO,CAAC,cAAc;IA+DtB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
1
+ {"version":3,"file":"telegram-gateway.d.ts","sourceRoot":"","sources":["../../src/steering/telegram-gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CAC9B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAiB;IAClD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAc;IAE5C,OAAO;IASP;;;OAGG;WACU,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAgCxI,OAAO,CAAC,cAAc;IAyFtB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}