@snoglobe/helios 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +222 -0
  3. package/dist/app.d.ts +9 -0
  4. package/dist/app.d.ts.map +1 -0
  5. package/dist/app.js +289 -0
  6. package/dist/app.js.map +1 -0
  7. package/dist/core/agent-loop.d.ts +16 -0
  8. package/dist/core/agent-loop.d.ts.map +1 -0
  9. package/dist/core/agent-loop.js +64 -0
  10. package/dist/core/agent-loop.js.map +1 -0
  11. package/dist/core/monitor.d.ts +15 -0
  12. package/dist/core/monitor.d.ts.map +1 -0
  13. package/dist/core/monitor.js +40 -0
  14. package/dist/core/monitor.js.map +1 -0
  15. package/dist/core/orchestrator.d.ts +51 -0
  16. package/dist/core/orchestrator.d.ts.map +1 -0
  17. package/dist/core/orchestrator.js +235 -0
  18. package/dist/core/orchestrator.js.map +1 -0
  19. package/dist/core/state-machine.d.ts +19 -0
  20. package/dist/core/state-machine.d.ts.map +1 -0
  21. package/dist/core/state-machine.js +42 -0
  22. package/dist/core/state-machine.js.map +1 -0
  23. package/dist/core/stickies.d.ts +20 -0
  24. package/dist/core/stickies.d.ts.map +1 -0
  25. package/dist/core/stickies.js +41 -0
  26. package/dist/core/stickies.js.map +1 -0
  27. package/dist/index.d.ts +3 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +68 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/memory/context-gate.d.ts +49 -0
  32. package/dist/memory/context-gate.d.ts.map +1 -0
  33. package/dist/memory/context-gate.js +109 -0
  34. package/dist/memory/context-gate.js.map +1 -0
  35. package/dist/memory/experiment-tracker.d.ts +21 -0
  36. package/dist/memory/experiment-tracker.d.ts.map +1 -0
  37. package/dist/memory/experiment-tracker.js +117 -0
  38. package/dist/memory/experiment-tracker.js.map +1 -0
  39. package/dist/memory/memory-store.d.ts +37 -0
  40. package/dist/memory/memory-store.d.ts.map +1 -0
  41. package/dist/memory/memory-store.js +150 -0
  42. package/dist/memory/memory-store.js.map +1 -0
  43. package/dist/memory/token-estimator.d.ts +7 -0
  44. package/dist/memory/token-estimator.d.ts.map +1 -0
  45. package/dist/memory/token-estimator.js +30 -0
  46. package/dist/memory/token-estimator.js.map +1 -0
  47. package/dist/metrics/analyzer.d.ts +15 -0
  48. package/dist/metrics/analyzer.d.ts.map +1 -0
  49. package/dist/metrics/analyzer.js +67 -0
  50. package/dist/metrics/analyzer.js.map +1 -0
  51. package/dist/metrics/collector.d.ts +23 -0
  52. package/dist/metrics/collector.d.ts.map +1 -0
  53. package/dist/metrics/collector.js +60 -0
  54. package/dist/metrics/collector.js.map +1 -0
  55. package/dist/metrics/parser.d.ts +21 -0
  56. package/dist/metrics/parser.d.ts.map +1 -0
  57. package/dist/metrics/parser.js +43 -0
  58. package/dist/metrics/parser.js.map +1 -0
  59. package/dist/metrics/parsers/csv.d.ts +8 -0
  60. package/dist/metrics/parsers/csv.d.ts.map +1 -0
  61. package/dist/metrics/parsers/csv.js +37 -0
  62. package/dist/metrics/parsers/csv.js.map +1 -0
  63. package/dist/metrics/parsers/json.d.ts +8 -0
  64. package/dist/metrics/parsers/json.d.ts.map +1 -0
  65. package/dist/metrics/parsers/json.js +42 -0
  66. package/dist/metrics/parsers/json.js.map +1 -0
  67. package/dist/metrics/parsers/stdout.d.ts +3 -0
  68. package/dist/metrics/parsers/stdout.d.ts.map +1 -0
  69. package/dist/metrics/parsers/stdout.js +79 -0
  70. package/dist/metrics/parsers/stdout.js.map +1 -0
  71. package/dist/metrics/parsers/tensorboard.d.ts +16 -0
  72. package/dist/metrics/parsers/tensorboard.d.ts.map +1 -0
  73. package/dist/metrics/parsers/tensorboard.js +22 -0
  74. package/dist/metrics/parsers/tensorboard.js.map +1 -0
  75. package/dist/metrics/store.d.ts +33 -0
  76. package/dist/metrics/store.d.ts.map +1 -0
  77. package/dist/metrics/store.js +141 -0
  78. package/dist/metrics/store.js.map +1 -0
  79. package/dist/providers/auth/auth-manager.d.ts +22 -0
  80. package/dist/providers/auth/auth-manager.d.ts.map +1 -0
  81. package/dist/providers/auth/auth-manager.js +77 -0
  82. package/dist/providers/auth/auth-manager.js.map +1 -0
  83. package/dist/providers/auth/token-store.d.ts +14 -0
  84. package/dist/providers/auth/token-store.d.ts.map +1 -0
  85. package/dist/providers/auth/token-store.js +55 -0
  86. package/dist/providers/auth/token-store.js.map +1 -0
  87. package/dist/providers/claude/provider.d.ts +46 -0
  88. package/dist/providers/claude/provider.d.ts.map +1 -0
  89. package/dist/providers/claude/provider.js +606 -0
  90. package/dist/providers/claude/provider.js.map +1 -0
  91. package/dist/providers/openai/callback-server.d.ts +11 -0
  92. package/dist/providers/openai/callback-server.d.ts.map +1 -0
  93. package/dist/providers/openai/callback-server.js +58 -0
  94. package/dist/providers/openai/callback-server.js.map +1 -0
  95. package/dist/providers/openai/oauth.d.ts +16 -0
  96. package/dist/providers/openai/oauth.d.ts.map +1 -0
  97. package/dist/providers/openai/oauth.js +110 -0
  98. package/dist/providers/openai/oauth.js.map +1 -0
  99. package/dist/providers/openai/provider.d.ts +29 -0
  100. package/dist/providers/openai/provider.d.ts.map +1 -0
  101. package/dist/providers/openai/provider.js +363 -0
  102. package/dist/providers/openai/provider.js.map +1 -0
  103. package/dist/providers/retry.d.ts +6 -0
  104. package/dist/providers/retry.d.ts.map +1 -0
  105. package/dist/providers/retry.js +13 -0
  106. package/dist/providers/retry.js.map +1 -0
  107. package/dist/providers/sse.d.ts +6 -0
  108. package/dist/providers/sse.d.ts.map +1 -0
  109. package/dist/providers/sse.js +35 -0
  110. package/dist/providers/sse.js.map +1 -0
  111. package/dist/providers/types.d.ts +102 -0
  112. package/dist/providers/types.d.ts.map +1 -0
  113. package/dist/providers/types.js +11 -0
  114. package/dist/providers/types.js.map +1 -0
  115. package/dist/remote/config.d.ts +14 -0
  116. package/dist/remote/config.d.ts.map +1 -0
  117. package/dist/remote/config.js +81 -0
  118. package/dist/remote/config.js.map +1 -0
  119. package/dist/remote/connection-pool.d.ts +26 -0
  120. package/dist/remote/connection-pool.d.ts.map +1 -0
  121. package/dist/remote/connection-pool.js +268 -0
  122. package/dist/remote/connection-pool.js.map +1 -0
  123. package/dist/remote/executor.d.ts +23 -0
  124. package/dist/remote/executor.d.ts.map +1 -0
  125. package/dist/remote/executor.js +53 -0
  126. package/dist/remote/executor.js.map +1 -0
  127. package/dist/remote/file-sync.d.ts +19 -0
  128. package/dist/remote/file-sync.d.ts.map +1 -0
  129. package/dist/remote/file-sync.js +44 -0
  130. package/dist/remote/file-sync.js.map +1 -0
  131. package/dist/remote/types.d.ts +33 -0
  132. package/dist/remote/types.d.ts.map +1 -0
  133. package/dist/remote/types.js +2 -0
  134. package/dist/remote/types.js.map +1 -0
  135. package/dist/scheduler/sleep-manager.d.ts +33 -0
  136. package/dist/scheduler/sleep-manager.d.ts.map +1 -0
  137. package/dist/scheduler/sleep-manager.js +132 -0
  138. package/dist/scheduler/sleep-manager.js.map +1 -0
  139. package/dist/scheduler/ssh-batcher.d.ts +23 -0
  140. package/dist/scheduler/ssh-batcher.d.ts.map +1 -0
  141. package/dist/scheduler/ssh-batcher.js +98 -0
  142. package/dist/scheduler/ssh-batcher.js.map +1 -0
  143. package/dist/scheduler/state-store.d.ts +8 -0
  144. package/dist/scheduler/state-store.d.ts.map +1 -0
  145. package/dist/scheduler/state-store.js +48 -0
  146. package/dist/scheduler/state-store.js.map +1 -0
  147. package/dist/scheduler/trigger-scheduler.d.ts +24 -0
  148. package/dist/scheduler/trigger-scheduler.d.ts.map +1 -0
  149. package/dist/scheduler/trigger-scheduler.js +142 -0
  150. package/dist/scheduler/trigger-scheduler.js.map +1 -0
  151. package/dist/scheduler/triggers/file.d.ts +4 -0
  152. package/dist/scheduler/triggers/file.d.ts.map +1 -0
  153. package/dist/scheduler/triggers/file.js +39 -0
  154. package/dist/scheduler/triggers/file.js.map +1 -0
  155. package/dist/scheduler/triggers/metric.d.ts +4 -0
  156. package/dist/scheduler/triggers/metric.d.ts.map +1 -0
  157. package/dist/scheduler/triggers/metric.js +74 -0
  158. package/dist/scheduler/triggers/metric.js.map +1 -0
  159. package/dist/scheduler/triggers/process-exit.d.ts +4 -0
  160. package/dist/scheduler/triggers/process-exit.d.ts.map +1 -0
  161. package/dist/scheduler/triggers/process-exit.js +13 -0
  162. package/dist/scheduler/triggers/process-exit.js.map +1 -0
  163. package/dist/scheduler/triggers/resource.d.ts +4 -0
  164. package/dist/scheduler/triggers/resource.d.ts.map +1 -0
  165. package/dist/scheduler/triggers/resource.js +54 -0
  166. package/dist/scheduler/triggers/resource.js.map +1 -0
  167. package/dist/scheduler/triggers/timer.d.ts +3 -0
  168. package/dist/scheduler/triggers/timer.d.ts.map +1 -0
  169. package/dist/scheduler/triggers/timer.js +4 -0
  170. package/dist/scheduler/triggers/timer.js.map +1 -0
  171. package/dist/scheduler/triggers/types.d.ts +95 -0
  172. package/dist/scheduler/triggers/types.d.ts.map +1 -0
  173. package/dist/scheduler/triggers/types.js +11 -0
  174. package/dist/scheduler/triggers/types.js.map +1 -0
  175. package/dist/store/database.d.ts +5 -0
  176. package/dist/store/database.d.ts.map +1 -0
  177. package/dist/store/database.js +29 -0
  178. package/dist/store/database.js.map +1 -0
  179. package/dist/store/migrations.d.ts +3 -0
  180. package/dist/store/migrations.d.ts.map +1 -0
  181. package/dist/store/migrations.js +124 -0
  182. package/dist/store/migrations.js.map +1 -0
  183. package/dist/store/preferences.d.ts +7 -0
  184. package/dist/store/preferences.d.ts.map +1 -0
  185. package/dist/store/preferences.js +26 -0
  186. package/dist/store/preferences.js.map +1 -0
  187. package/dist/store/session-store.d.ts +29 -0
  188. package/dist/store/session-store.d.ts.map +1 -0
  189. package/dist/store/session-store.js +103 -0
  190. package/dist/store/session-store.js.map +1 -0
  191. package/dist/tools/clear-metrics.d.ts +5 -0
  192. package/dist/tools/clear-metrics.d.ts.map +1 -0
  193. package/dist/tools/clear-metrics.js +27 -0
  194. package/dist/tools/clear-metrics.js.map +1 -0
  195. package/dist/tools/compare-runs.d.ts +4 -0
  196. package/dist/tools/compare-runs.d.ts.map +1 -0
  197. package/dist/tools/compare-runs.js +77 -0
  198. package/dist/tools/compare-runs.js.map +1 -0
  199. package/dist/tools/consult.d.ts +3 -0
  200. package/dist/tools/consult.d.ts.map +1 -0
  201. package/dist/tools/consult.js +62 -0
  202. package/dist/tools/consult.js.map +1 -0
  203. package/dist/tools/file-ops.d.ts +6 -0
  204. package/dist/tools/file-ops.d.ts.map +1 -0
  205. package/dist/tools/file-ops.js +158 -0
  206. package/dist/tools/file-ops.js.map +1 -0
  207. package/dist/tools/kill-task.d.ts +6 -0
  208. package/dist/tools/kill-task.d.ts.map +1 -0
  209. package/dist/tools/kill-task.js +55 -0
  210. package/dist/tools/kill-task.js.map +1 -0
  211. package/dist/tools/list-machines.d.ts +4 -0
  212. package/dist/tools/list-machines.d.ts.map +1 -0
  213. package/dist/tools/list-machines.js +24 -0
  214. package/dist/tools/list-machines.js.map +1 -0
  215. package/dist/tools/memory-tools.d.ts +8 -0
  216. package/dist/tools/memory-tools.d.ts.map +1 -0
  217. package/dist/tools/memory-tools.js +122 -0
  218. package/dist/tools/memory-tools.js.map +1 -0
  219. package/dist/tools/metrics-query.d.ts +4 -0
  220. package/dist/tools/metrics-query.d.ts.map +1 -0
  221. package/dist/tools/metrics-query.js +69 -0
  222. package/dist/tools/metrics-query.js.map +1 -0
  223. package/dist/tools/monitor.d.ts +5 -0
  224. package/dist/tools/monitor.d.ts.map +1 -0
  225. package/dist/tools/monitor.js +64 -0
  226. package/dist/tools/monitor.js.map +1 -0
  227. package/dist/tools/remote-exec.d.ts +6 -0
  228. package/dist/tools/remote-exec.d.ts.map +1 -0
  229. package/dist/tools/remote-exec.js +98 -0
  230. package/dist/tools/remote-exec.js.map +1 -0
  231. package/dist/tools/remote-sync.d.ts +5 -0
  232. package/dist/tools/remote-sync.d.ts.map +1 -0
  233. package/dist/tools/remote-sync.js +57 -0
  234. package/dist/tools/remote-sync.js.map +1 -0
  235. package/dist/tools/show-metrics.d.ts +4 -0
  236. package/dist/tools/show-metrics.d.ts.map +1 -0
  237. package/dist/tools/show-metrics.js +69 -0
  238. package/dist/tools/show-metrics.js.map +1 -0
  239. package/dist/tools/sleep.d.ts +4 -0
  240. package/dist/tools/sleep.d.ts.map +1 -0
  241. package/dist/tools/sleep.js +116 -0
  242. package/dist/tools/sleep.js.map +1 -0
  243. package/dist/tools/task-output.d.ts +5 -0
  244. package/dist/tools/task-output.d.ts.map +1 -0
  245. package/dist/tools/task-output.js +51 -0
  246. package/dist/tools/task-output.js.map +1 -0
  247. package/dist/tools/web-fetch.d.ts +3 -0
  248. package/dist/tools/web-fetch.d.ts.map +1 -0
  249. package/dist/tools/web-fetch.js +112 -0
  250. package/dist/tools/web-fetch.js.map +1 -0
  251. package/dist/ui/commands.d.ts +7 -0
  252. package/dist/ui/commands.d.ts.map +1 -0
  253. package/dist/ui/commands.js +21 -0
  254. package/dist/ui/commands.js.map +1 -0
  255. package/dist/ui/components/gradient-edge.d.ts +7 -0
  256. package/dist/ui/components/gradient-edge.d.ts.map +1 -0
  257. package/dist/ui/components/gradient-edge.js +33 -0
  258. package/dist/ui/components/gradient-edge.js.map +1 -0
  259. package/dist/ui/components/input-bar.d.ts +8 -0
  260. package/dist/ui/components/input-bar.d.ts.map +1 -0
  261. package/dist/ui/components/input-bar.js +139 -0
  262. package/dist/ui/components/input-bar.js.map +1 -0
  263. package/dist/ui/components/key-hint-rule.d.ts +2 -0
  264. package/dist/ui/components/key-hint-rule.d.ts.map +1 -0
  265. package/dist/ui/components/key-hint-rule.js +19 -0
  266. package/dist/ui/components/key-hint-rule.js.map +1 -0
  267. package/dist/ui/components/overlay-header.d.ts +6 -0
  268. package/dist/ui/components/overlay-header.d.ts.map +1 -0
  269. package/dist/ui/components/overlay-header.js +10 -0
  270. package/dist/ui/components/overlay-header.js.map +1 -0
  271. package/dist/ui/components/status-bar.d.ts +11 -0
  272. package/dist/ui/components/status-bar.d.ts.map +1 -0
  273. package/dist/ui/components/status-bar.js +55 -0
  274. package/dist/ui/components/status-bar.js.map +1 -0
  275. package/dist/ui/format.d.ts +12 -0
  276. package/dist/ui/format.d.ts.map +1 -0
  277. package/dist/ui/format.js +36 -0
  278. package/dist/ui/format.js.map +1 -0
  279. package/dist/ui/layout.d.ts +48 -0
  280. package/dist/ui/layout.d.ts.map +1 -0
  281. package/dist/ui/layout.js +857 -0
  282. package/dist/ui/layout.js.map +1 -0
  283. package/dist/ui/markdown.d.ts +7 -0
  284. package/dist/ui/markdown.d.ts.map +1 -0
  285. package/dist/ui/markdown.js +67 -0
  286. package/dist/ui/markdown.js.map +1 -0
  287. package/dist/ui/mouse-filter.d.ts +21 -0
  288. package/dist/ui/mouse-filter.d.ts.map +1 -0
  289. package/dist/ui/mouse-filter.js +66 -0
  290. package/dist/ui/mouse-filter.js.map +1 -0
  291. package/dist/ui/overlays/metrics-overlay.d.ts +11 -0
  292. package/dist/ui/overlays/metrics-overlay.d.ts.map +1 -0
  293. package/dist/ui/overlays/metrics-overlay.js +86 -0
  294. package/dist/ui/overlays/metrics-overlay.js.map +1 -0
  295. package/dist/ui/overlays/task-overlay.d.ts +12 -0
  296. package/dist/ui/overlays/task-overlay.d.ts.map +1 -0
  297. package/dist/ui/overlays/task-overlay.js +77 -0
  298. package/dist/ui/overlays/task-overlay.js.map +1 -0
  299. package/dist/ui/panels/conversation.d.ts +8 -0
  300. package/dist/ui/panels/conversation.d.ts.map +1 -0
  301. package/dist/ui/panels/conversation.js +216 -0
  302. package/dist/ui/panels/conversation.js.map +1 -0
  303. package/dist/ui/panels/metrics-dashboard.d.ts +8 -0
  304. package/dist/ui/panels/metrics-dashboard.d.ts.map +1 -0
  305. package/dist/ui/panels/metrics-dashboard.js +56 -0
  306. package/dist/ui/panels/metrics-dashboard.js.map +1 -0
  307. package/dist/ui/panels/sleep-panel.d.ts +7 -0
  308. package/dist/ui/panels/sleep-panel.d.ts.map +1 -0
  309. package/dist/ui/panels/sleep-panel.js +48 -0
  310. package/dist/ui/panels/sleep-panel.js.map +1 -0
  311. package/dist/ui/panels/sticky-notes.d.ts +8 -0
  312. package/dist/ui/panels/sticky-notes.d.ts.map +1 -0
  313. package/dist/ui/panels/sticky-notes.js +49 -0
  314. package/dist/ui/panels/sticky-notes.js.map +1 -0
  315. package/dist/ui/panels/task-list.d.ts +8 -0
  316. package/dist/ui/panels/task-list.d.ts.map +1 -0
  317. package/dist/ui/panels/task-list.js +39 -0
  318. package/dist/ui/panels/task-list.js.map +1 -0
  319. package/dist/ui/theme.d.ts +25 -0
  320. package/dist/ui/theme.d.ts.map +1 -0
  321. package/dist/ui/theme.js +50 -0
  322. package/dist/ui/theme.js.map +1 -0
  323. package/dist/version.d.ts +9 -0
  324. package/dist/version.d.ts.map +1 -0
  325. package/dist/version.js +62 -0
  326. package/dist/version.js.map +1 -0
  327. package/package.json +59 -0
@@ -0,0 +1,21 @@
1
+ import type { MemoryStore } from "./memory-store.js";
2
+ import type { AgentEvent } from "../providers/types.js";
3
+ /**
4
+ * Auto-populates /experiments/ in memory when remote_exec_background is called.
5
+ * Listens to tool_call and tool_result events from the orchestrator.
6
+ */
7
+ export declare class ExperimentTracker {
8
+ private memory;
9
+ private experimentCount;
10
+ private pendingCalls;
11
+ private experiments;
12
+ constructor(memory: MemoryStore);
13
+ private getNextCount;
14
+ /** Call this for every AgentEvent from the orchestrator. */
15
+ onEvent(event: AgentEvent): void;
16
+ /** Update an experiment with final results (call when a task completes). */
17
+ updateExperiment(machineId: string, pid: number, exitCode: number, metrics?: Record<string, number>): void;
18
+ /** Get all pending experiment keys. */
19
+ getPendingKeys(): string[];
20
+ }
21
+ //# sourceMappingURL=experiment-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experiment-tracker.d.ts","sourceRoot":"","sources":["../../src/memory/experiment-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAaxD;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,WAAW,CAAwC;gBAE/C,MAAM,EAAE,WAAW;IAI/B,OAAO,CAAC,YAAY;IAUpB,4DAA4D;IAC5D,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAmDhC,4EAA4E;IAC5E,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,IAAI;IAqCP,uCAAuC;IACvC,cAAc,IAAI,MAAM,EAAE;CAG3B"}
@@ -0,0 +1,117 @@
1
+ import { truncate } from "../ui/format.js";
2
+ /**
3
+ * Auto-populates /experiments/ in memory when remote_exec_background is called.
4
+ * Listens to tool_call and tool_result events from the orchestrator.
5
+ */
6
+ export class ExperimentTracker {
7
+ memory;
8
+ experimentCount = null; // null = not yet initialized
9
+ pendingCalls = new Map();
10
+ experiments = new Map(); // "machine:pid" → experiment
11
+ constructor(memory) {
12
+ this.memory = memory;
13
+ }
14
+ getNextCount() {
15
+ if (this.experimentCount === null) {
16
+ // Lazy init — session ID should be set by now
17
+ const existing = this.memory.ls("/experiments/");
18
+ this.experimentCount = existing.length;
19
+ }
20
+ this.experimentCount++;
21
+ return this.experimentCount;
22
+ }
23
+ /** Call this for every AgentEvent from the orchestrator. */
24
+ onEvent(event) {
25
+ if (event.type === "tool_call" && event.name === "remote_exec_background") {
26
+ this.pendingCalls.set(event.id, event.args);
27
+ }
28
+ if (event.type === "tool_result" && this.pendingCalls.has(event.callId)) {
29
+ const args = this.pendingCalls.get(event.callId);
30
+ this.pendingCalls.delete(event.callId);
31
+ if (event.isError)
32
+ return;
33
+ try {
34
+ const result = JSON.parse(event.result);
35
+ if (!result.pid)
36
+ return;
37
+ const num = String(this.getNextCount()).padStart(2, "0");
38
+ const name = slugify(args.command);
39
+ const path = `/experiments/${num}-${name}`;
40
+ const key = `${result.machine_id ?? args.machine_id}:${result.pid}`;
41
+ const experiment = {
42
+ name: `${num}-${name}`,
43
+ machineId: (result.machine_id ?? args.machine_id),
44
+ pid: result.pid,
45
+ command: args.command,
46
+ metricNames: args.metric_names,
47
+ metricPatterns: args.metric_patterns,
48
+ startedAt: Date.now(),
49
+ };
50
+ this.experiments.set(key, experiment);
51
+ const gist = `${experiment.machineId}:${experiment.pid} — ${truncate(experiment.command, 50)}`;
52
+ const content = [
53
+ `command: ${experiment.command}`,
54
+ `machine: ${experiment.machineId}`,
55
+ `pid: ${experiment.pid}`,
56
+ experiment.metricNames ? `metrics: ${experiment.metricNames.join(", ")}` : null,
57
+ `status: running`,
58
+ `started: ${new Date(experiment.startedAt).toISOString()}`,
59
+ ]
60
+ .filter(Boolean)
61
+ .join("\n");
62
+ this.memory.write(path, gist, content);
63
+ }
64
+ catch {
65
+ // Parse failure — skip
66
+ }
67
+ }
68
+ }
69
+ /** Update an experiment with final results (call when a task completes). */
70
+ updateExperiment(machineId, pid, exitCode, metrics) {
71
+ const key = `${machineId}:${pid}`;
72
+ const experiment = this.experiments.get(key);
73
+ if (!experiment)
74
+ return;
75
+ // Find the existing path
76
+ const nodes = this.memory.ls("/experiments/");
77
+ const node = nodes.find((n) => n.gist.startsWith(key));
78
+ if (!node)
79
+ return;
80
+ const metricStr = metrics
81
+ ? Object.entries(metrics)
82
+ .map(([k, v]) => `${k}=${v}`)
83
+ .join(", ")
84
+ : "none";
85
+ const status = exitCode === 0 ? "completed" : `failed (exit ${exitCode})`;
86
+ const gist = `${key} — ${truncate(experiment.command, 50)} → ${metricStr} (${status})`;
87
+ const content = [
88
+ `command: ${experiment.command}`,
89
+ `machine: ${experiment.machineId}`,
90
+ `pid: ${experiment.pid}`,
91
+ experiment.metricNames ? `metrics_config: ${experiment.metricNames.join(", ")}` : null,
92
+ `status: ${status}`,
93
+ `started: ${new Date(experiment.startedAt).toISOString()}`,
94
+ `finished: ${new Date().toISOString()}`,
95
+ `exit_code: ${exitCode}`,
96
+ metrics ? `final_metrics: ${JSON.stringify(metrics)}` : null,
97
+ ]
98
+ .filter(Boolean)
99
+ .join("\n");
100
+ this.memory.write(node.path, gist, content);
101
+ this.experiments.delete(key);
102
+ }
103
+ /** Get all pending experiment keys. */
104
+ getPendingKeys() {
105
+ return [...this.experiments.keys()];
106
+ }
107
+ }
108
+ function slugify(cmd) {
109
+ // Take the first meaningful word from the command
110
+ const words = cmd
111
+ .replace(/[^a-zA-Z0-9\s_-]/g, "")
112
+ .split(/\s+/)
113
+ .filter(Boolean)
114
+ .slice(0, 3);
115
+ return words.join("-").toLowerCase().slice(0, 30) || "run";
116
+ }
117
+ //# sourceMappingURL=experiment-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experiment-tracker.js","sourceRoot":"","sources":["../../src/memory/experiment-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export interface MemoryNode {
2
+ path: string;
3
+ gist: string;
4
+ content: string | null;
5
+ isDir: boolean;
6
+ createdAt: number;
7
+ updatedAt: number;
8
+ }
9
+ export declare class MemoryStore {
10
+ private sessionId;
11
+ constructor(sessionId: string);
12
+ setSession(sessionId: string): void;
13
+ /** List children of a directory path. */
14
+ ls(dirPath?: string): MemoryNode[];
15
+ /** Recursively list all nodes under a path, returning paths + gists only. */
16
+ tree(dirPath?: string): Array<{
17
+ path: string;
18
+ gist: string;
19
+ isDir: boolean;
20
+ }>;
21
+ /** Read a node's full content. */
22
+ read(path: string): MemoryNode | null;
23
+ /** Write or update a node. Auto-creates parent directories. */
24
+ write(path: string, gist: string, content?: string | null): void;
25
+ /** Remove a node and all children (if directory). */
26
+ rm(path: string): number;
27
+ /** Check if a path exists. */
28
+ exists(path: string): boolean;
29
+ /** Count all nodes for this session. */
30
+ count(): number;
31
+ /** Build a formatted tree string (paths + gists) for checkpoint briefings. */
32
+ formatTree(dirPath?: string): string;
33
+ /** Clear all memory for this session. */
34
+ clear(): void;
35
+ private ensureParents;
36
+ }
37
+ //# sourceMappingURL=memory-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/memory/memory-store.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAS;gBAEd,SAAS,EAAE,MAAM;IAI7B,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAInC,yCAAyC;IACzC,EAAE,CAAC,OAAO,SAAM,GAAG,UAAU,EAAE;IA0B/B,6EAA6E;IAC7E,IAAI,CAAC,OAAO,SAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAoB1E,kCAAkC;IAClC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAarC,+DAA+D;IAC/D,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAmBhE,qDAAqD;IACrD,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAcxB,8BAA8B;IAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQ7B,wCAAwC;IACxC,KAAK,IAAI,MAAM;IAQf,8EAA8E;IAC9E,UAAU,CAAC,OAAO,SAAM,GAAG,MAAM;IAiBjC,yCAAyC;IACzC,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,aAAa;CAetB"}
@@ -0,0 +1,150 @@
1
+ import { getDb } from "../store/database.js";
2
+ export class MemoryStore {
3
+ sessionId;
4
+ constructor(sessionId) {
5
+ this.sessionId = sessionId;
6
+ }
7
+ setSession(sessionId) {
8
+ this.sessionId = sessionId;
9
+ }
10
+ /** List children of a directory path. */
11
+ ls(dirPath = "/") {
12
+ const normalized = normalizeDirPath(dirPath);
13
+ const db = getDb();
14
+ // Find direct children: paths that start with dirPath and have no further slashes
15
+ // For "/", children are like "/goal", "/experiments/"
16
+ // For "/experiments/", children are like "/experiments/01-baseline"
17
+ const rows = db
18
+ .prepare(`SELECT path, gist, content, is_dir, created_at, updated_at
19
+ FROM memory_nodes
20
+ WHERE session_id = ? AND path LIKE ? AND path != ?`)
21
+ .all(this.sessionId, normalized + "%", normalized);
22
+ // Filter to direct children only
23
+ return rows
24
+ .filter((row) => {
25
+ const relPath = row.path.slice(normalized.length);
26
+ // Direct child: no slashes, or exactly one trailing slash (directory)
27
+ const slashCount = (relPath.match(/\//g) || []).length;
28
+ return slashCount === 0 || (slashCount === 1 && relPath.endsWith("/"));
29
+ })
30
+ .map(rowToNode);
31
+ }
32
+ /** Recursively list all nodes under a path, returning paths + gists only. */
33
+ tree(dirPath = "/") {
34
+ const normalized = normalizeDirPath(dirPath);
35
+ const db = getDb();
36
+ const rows = db
37
+ .prepare(`SELECT path, gist, is_dir
38
+ FROM memory_nodes
39
+ WHERE session_id = ? AND path LIKE ? AND path != ?
40
+ ORDER BY path`)
41
+ .all(this.sessionId, normalized + "%", normalized);
42
+ return rows.map((row) => ({
43
+ path: row.path,
44
+ gist: row.gist,
45
+ isDir: row.is_dir === 1,
46
+ }));
47
+ }
48
+ /** Read a node's full content. */
49
+ read(path) {
50
+ const db = getDb();
51
+ const row = db
52
+ .prepare(`SELECT path, gist, content, is_dir, created_at, updated_at
53
+ FROM memory_nodes
54
+ WHERE session_id = ? AND path = ?`)
55
+ .get(this.sessionId, path);
56
+ return row ? rowToNode(row) : null;
57
+ }
58
+ /** Write or update a node. Auto-creates parent directories. */
59
+ write(path, gist, content) {
60
+ const db = getDb();
61
+ const now = Date.now();
62
+ const isDir = content === undefined || content === null;
63
+ // Auto-create parent directories
64
+ this.ensureParents(path);
65
+ db.prepare(`INSERT INTO memory_nodes (session_id, path, gist, content, is_dir, created_at, updated_at)
66
+ VALUES (?, ?, ?, ?, ?, ?, ?)
67
+ ON CONFLICT(session_id, path) DO UPDATE SET
68
+ gist = excluded.gist,
69
+ content = excluded.content,
70
+ is_dir = excluded.is_dir,
71
+ updated_at = excluded.updated_at`).run(this.sessionId, path, gist, isDir ? null : content, isDir ? 1 : 0, now, now);
72
+ }
73
+ /** Remove a node and all children (if directory). */
74
+ rm(path) {
75
+ const db = getDb();
76
+ // Delete exact match + any children
77
+ const result = db
78
+ .prepare(`DELETE FROM memory_nodes
79
+ WHERE session_id = ? AND (path = ? OR path LIKE ?)`)
80
+ .run(this.sessionId, path, path.endsWith("/") ? path + "%" : path + "/%");
81
+ return result.changes;
82
+ }
83
+ /** Check if a path exists. */
84
+ exists(path) {
85
+ const db = getDb();
86
+ const row = db
87
+ .prepare("SELECT 1 FROM memory_nodes WHERE session_id = ? AND path = ?")
88
+ .get(this.sessionId, path);
89
+ return !!row;
90
+ }
91
+ /** Count all nodes for this session. */
92
+ count() {
93
+ const db = getDb();
94
+ const row = db
95
+ .prepare("SELECT COUNT(*) as c FROM memory_nodes WHERE session_id = ?")
96
+ .get(this.sessionId);
97
+ return row.c;
98
+ }
99
+ /** Build a formatted tree string (paths + gists) for checkpoint briefings. */
100
+ formatTree(dirPath = "/") {
101
+ const nodes = this.tree(dirPath);
102
+ if (nodes.length === 0)
103
+ return "(empty)";
104
+ const lines = [];
105
+ for (const node of nodes) {
106
+ // Indent based on depth
107
+ const depth = node.path.split("/").filter(Boolean).length - 1;
108
+ const indent = " ".repeat(depth);
109
+ const name = node.isDir
110
+ ? node.path.split("/").filter(Boolean).pop() + "/"
111
+ : node.path.split("/").filter(Boolean).pop();
112
+ lines.push(`${indent}${name}: ${node.gist}`);
113
+ }
114
+ return lines.join("\n");
115
+ }
116
+ /** Clear all memory for this session. */
117
+ clear() {
118
+ const db = getDb();
119
+ db.prepare("DELETE FROM memory_nodes WHERE session_id = ?").run(this.sessionId);
120
+ }
121
+ ensureParents(path) {
122
+ const parts = path.split("/").filter(Boolean);
123
+ // For "/a/b/c", ensure "/a/" and "/a/b/" exist
124
+ for (let i = 1; i < parts.length; i++) {
125
+ const parentPath = "/" + parts.slice(0, i).join("/") + "/";
126
+ if (!this.exists(parentPath)) {
127
+ const db = getDb();
128
+ const now = Date.now();
129
+ db.prepare(`INSERT OR IGNORE INTO memory_nodes (session_id, path, gist, content, is_dir, created_at, updated_at)
130
+ VALUES (?, ?, ?, NULL, 1, ?, ?)`).run(this.sessionId, parentPath, parts[i - 1], now, now);
131
+ }
132
+ }
133
+ }
134
+ }
135
+ function normalizeDirPath(path) {
136
+ if (path === "/")
137
+ return "/";
138
+ return path.endsWith("/") ? path : path + "/";
139
+ }
140
+ function rowToNode(row) {
141
+ return {
142
+ path: row.path,
143
+ gist: row.gist,
144
+ content: row.content,
145
+ isDir: row.is_dir === 1,
146
+ createdAt: row.created_at,
147
+ updatedAt: row.updated_at,
148
+ };
149
+ }
150
+ //# sourceMappingURL=memory-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../src/memory/memory-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /** Rough token estimation: ~4 chars per token (standard heuristic). */
2
+ export declare function estimateTokens(text: string): number;
3
+ /** Get context budget (80% of model limit) in tokens. */
4
+ export declare function getContextBudget(model: string): number;
5
+ /** Checkpoint threshold — 85% of budget. */
6
+ export declare function getCheckpointThreshold(model: string): number;
7
+ //# sourceMappingURL=token-estimator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-estimator.d.ts","sourceRoot":"","sources":["../../src/memory/token-estimator.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAoBD,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,4CAA4C;AAC5C,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D"}
@@ -0,0 +1,30 @@
1
+ /** Rough token estimation: ~4 chars per token (standard heuristic). */
2
+ export function estimateTokens(text) {
3
+ return Math.ceil(text.length / 4);
4
+ }
5
+ /** Per-model context window sizes. */
6
+ const MODEL_LIMITS = {
7
+ // Claude (200k)
8
+ "claude-opus-4-6": 200_000,
9
+ "claude-sonnet-4-6": 200_000,
10
+ // OpenAI (~400k)
11
+ "gpt-5.4": 400_000,
12
+ "gpt-5.3-codex": 400_000,
13
+ "gpt-5.3-codex-spark": 400_000,
14
+ "gpt-5.2-codex": 400_000,
15
+ "gpt-5.2": 400_000,
16
+ "gpt-5.1-codex-max": 400_000,
17
+ "gpt-5.1-codex": 400_000,
18
+ "gpt-5.1": 400_000,
19
+ };
20
+ const DEFAULT_LIMIT = 200_000;
21
+ /** Get context budget (80% of model limit) in tokens. */
22
+ export function getContextBudget(model) {
23
+ const limit = MODEL_LIMITS[model] ?? DEFAULT_LIMIT;
24
+ return Math.floor(limit * 0.8);
25
+ }
26
+ /** Checkpoint threshold — 85% of budget. */
27
+ export function getCheckpointThreshold(model) {
28
+ return Math.floor(getContextBudget(model) * 0.85);
29
+ }
30
+ //# sourceMappingURL=token-estimator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-estimator.js","sourceRoot":"","sources":["../../src/memory/token-estimator.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,sCAAsC;AACtC,MAAM,YAAY,GAA2B;IAC3C,gBAAgB;IAChB,iBAAiB,EAAE,OAAO;IAC1B,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB;IACjB,SAAS,EAAE,OAAO;IAClB,eAAe,EAAE,OAAO;IACxB,qBAAqB,EAAE,OAAO;IAC9B,eAAe,EAAE,OAAO;IACxB,SAAS,EAAE,OAAO;IAClB,mBAAmB,EAAE,OAAO;IAC5B,eAAe,EAAE,OAAO;IACxB,SAAS,EAAE,OAAO;CACnB,CAAC;AAEF,MAAM,aAAa,GAAG,OAAO,CAAC;AAE9B,yDAAyD;AACzD,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC;IACnD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { MetricPoint } from "./store.js";
2
+ export interface AnalysisResult {
3
+ trend: "decreasing" | "plateau" | "increasing" | "unstable" | "insufficient_data";
4
+ slope: number;
5
+ currentValue: number;
6
+ meanValue: number;
7
+ stdDev: number;
8
+ hasNaN: boolean;
9
+ hasInf: boolean;
10
+ }
11
+ /**
12
+ * Analyze a metric time series for trends.
13
+ */
14
+ export declare function analyzeMetric(points: MetricPoint[], windowSize?: number): AnalysisResult;
15
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/metrics/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,mBAAmB,CAAC;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,WAAW,EAAE,EACrB,UAAU,SAAK,GACd,cAAc,CAmDhB"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Analyze a metric time series for trends.
3
+ */
4
+ export function analyzeMetric(points, windowSize = 20) {
5
+ if (points.length < 3) {
6
+ return {
7
+ trend: "insufficient_data",
8
+ slope: 0,
9
+ currentValue: points.length > 0 ? points[points.length - 1].value : 0,
10
+ meanValue: 0,
11
+ stdDev: 0,
12
+ hasNaN: false,
13
+ hasInf: false,
14
+ };
15
+ }
16
+ const values = points.slice(-windowSize).map((p) => p.value);
17
+ const hasNaN = values.some(isNaN);
18
+ const hasInf = values.some((v) => !isFinite(v));
19
+ const validValues = values.filter((v) => isFinite(v) && !isNaN(v));
20
+ if (validValues.length < 3) {
21
+ return {
22
+ trend: "unstable",
23
+ slope: 0,
24
+ currentValue: values[values.length - 1],
25
+ meanValue: 0,
26
+ stdDev: 0,
27
+ hasNaN,
28
+ hasInf,
29
+ };
30
+ }
31
+ const mean = validValues.reduce((a, b) => a + b, 0) / validValues.length;
32
+ const variance = validValues.reduce((sum, v) => sum + (v - mean) ** 2, 0) /
33
+ validValues.length;
34
+ const stdDev = Math.sqrt(variance);
35
+ const slope = linearRegressionSlope(validValues);
36
+ const currentValue = validValues[validValues.length - 1];
37
+ // Determine trend
38
+ const slopeThreshold = stdDev * 0.1 || 1e-6;
39
+ let trend;
40
+ if (Math.abs(slope) < slopeThreshold) {
41
+ trend = "plateau";
42
+ }
43
+ else if (slope < 0) {
44
+ trend = "decreasing";
45
+ }
46
+ else {
47
+ trend = "increasing";
48
+ }
49
+ return { trend, slope, currentValue, meanValue: mean, stdDev, hasNaN, hasInf };
50
+ }
51
+ /**
52
+ * Simple linear regression slope.
53
+ * x = [0, 1, 2, ...], y = values
54
+ */
55
+ function linearRegressionSlope(values) {
56
+ const n = values.length;
57
+ const xMean = (n - 1) / 2;
58
+ const yMean = values.reduce((a, b) => a + b, 0) / n;
59
+ let numerator = 0;
60
+ let denominator = 0;
61
+ for (let i = 0; i < n; i++) {
62
+ numerator += (i - xMean) * (values[i] - yMean);
63
+ denominator += (i - xMean) ** 2;
64
+ }
65
+ return denominator === 0 ? 0 : numerator / denominator;
66
+ }
67
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/metrics/analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ConnectionPool } from "../remote/connection-pool.js";
2
+ import { MetricStore, type MetricPoint } from "./store.js";
3
+ import { type MetricPatterns } from "./parser.js";
4
+ export interface CollectorSource {
5
+ taskId: string;
6
+ machineId: string;
7
+ logPath: string;
8
+ patterns: MetricPatterns;
9
+ }
10
+ export declare class MetricCollector {
11
+ private pool;
12
+ private store;
13
+ private sources;
14
+ private lastLineCount;
15
+ constructor(pool: ConnectionPool, store: MetricStore);
16
+ addSource(source: CollectorSource): void;
17
+ removeSource(taskId: string): void;
18
+ /** Reset all sources and line tracking (e.g. on metrics clear) */
19
+ reset(): void;
20
+ collectAll(): Promise<MetricPoint[]>;
21
+ private collect;
22
+ }
23
+ //# sourceMappingURL=collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/metrics/collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,KAAK,cAAc,EAAqB,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,qBAAa,eAAe;IAKxB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,KAAK;IALf,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,aAAa,CAA6B;gBAGxC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,WAAW;IAG5B,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAOxC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IASlC,kEAAkE;IAClE,KAAK,IAAI,IAAI;IAKP,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAkB5B,OAAO;CAuBtB"}
@@ -0,0 +1,60 @@
1
+ import { parseWithPatterns } from "./parser.js";
2
+ export class MetricCollector {
3
+ pool;
4
+ store;
5
+ sources = [];
6
+ lastLineCount = new Map();
7
+ constructor(pool, store) {
8
+ this.pool = pool;
9
+ this.store = store;
10
+ }
11
+ addSource(source) {
12
+ const exists = this.sources.some((s) => s.taskId === source.taskId);
13
+ if (!exists) {
14
+ this.sources.push(source);
15
+ }
16
+ }
17
+ removeSource(taskId) {
18
+ this.sources = this.sources.filter((s) => s.taskId !== taskId);
19
+ for (const key of this.lastLineCount.keys()) {
20
+ if (key.startsWith(taskId + ":")) {
21
+ this.lastLineCount.delete(key);
22
+ }
23
+ }
24
+ }
25
+ /** Reset all sources and line tracking (e.g. on metrics clear) */
26
+ reset() {
27
+ this.sources = [];
28
+ this.lastLineCount.clear();
29
+ }
30
+ async collectAll() {
31
+ const allPoints = [];
32
+ for (const source of this.sources) {
33
+ try {
34
+ const points = await this.collect(source);
35
+ if (points.length > 0) {
36
+ this.store.insertBatch(source.taskId, source.machineId, points);
37
+ allPoints.push(...points);
38
+ }
39
+ }
40
+ catch {
41
+ // Silently skip failed collections
42
+ }
43
+ }
44
+ return allPoints;
45
+ }
46
+ async collect(source) {
47
+ const key = `${source.taskId}:${source.logPath}`;
48
+ const lastCount = this.lastLineCount.get(key) ?? 0;
49
+ const wcResult = await this.pool.exec(source.machineId, `wc -l < '${source.logPath.replace(/'/g, "'\\''")}'`);
50
+ const totalLines = parseInt(wcResult.stdout.trim(), 10);
51
+ if (isNaN(totalLines) || totalLines <= lastCount) {
52
+ return [];
53
+ }
54
+ const newLineCount = totalLines - lastCount;
55
+ const output = await this.pool.tailFile(source.machineId, source.logPath, newLineCount);
56
+ this.lastLineCount.set(key, totalLines);
57
+ return parseWithPatterns(output, source.patterns);
58
+ }
59
+ }
60
+ //# sourceMappingURL=collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector.js","sourceRoot":"","sources":["../../src/metrics/collector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { MetricPoint } from "./store.js";
2
+ /**
3
+ * Parse metrics from log output using caller-supplied patterns.
4
+ *
5
+ * Two modes:
6
+ * - metric_names: ["loss", "lr"] → auto-generates key=value regexes
7
+ * - metric_patterns: { "loss": "Loss:\\s*([\\d.e+-]+)" } → custom regexes
8
+ *
9
+ * Each pattern must have exactly one capture group for the numeric value.
10
+ */
11
+ export interface MetricPatterns {
12
+ /** Map of metric name → regex string with one capture group for the value */
13
+ patterns: Record<string, RegExp>;
14
+ }
15
+ /** Build MetricPatterns from a list of names (assumes key=value format) */
16
+ export declare function patternsFromNames(names: string[]): MetricPatterns;
17
+ /** Build MetricPatterns from a map of name → regex string */
18
+ export declare function patternsFromRegexes(regexMap: Record<string, string>): MetricPatterns;
19
+ /** Parse log output using the given patterns */
20
+ export declare function parseWithPatterns(output: string, mp: MetricPatterns): MetricPoint[];
21
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/metrics/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;GAQG;AAEH,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,CAUjE;AAED,6DAA6D;AAC7D,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,cAAc,CAMhB;AAED,gDAAgD;AAChD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,cAAc,GACjB,WAAW,EAAE,CAsBf"}