@bradygaster/squad-sdk 0.6.2 → 0.8.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 (306) hide show
  1. package/README.md +296 -296
  2. package/dist/adapter/client.d.ts +225 -0
  3. package/dist/adapter/client.d.ts.map +1 -0
  4. package/dist/adapter/client.js +397 -0
  5. package/dist/adapter/client.js.map +1 -0
  6. package/dist/adapter/errors.d.ts +260 -0
  7. package/dist/adapter/errors.d.ts.map +1 -0
  8. package/dist/adapter/errors.js +362 -0
  9. package/dist/adapter/errors.js.map +1 -0
  10. package/dist/adapter/types.d.ts +779 -0
  11. package/dist/adapter/types.d.ts.map +1 -0
  12. package/dist/adapter/types.js +11 -0
  13. package/dist/adapter/types.js.map +1 -0
  14. package/dist/agents/charter-compiler.d.ts +102 -0
  15. package/dist/agents/charter-compiler.d.ts.map +1 -0
  16. package/dist/agents/charter-compiler.js +157 -0
  17. package/dist/agents/charter-compiler.js.map +1 -0
  18. package/dist/agents/history-shadow.d.ts +80 -0
  19. package/dist/agents/history-shadow.d.ts.map +1 -0
  20. package/dist/agents/history-shadow.js +239 -0
  21. package/dist/agents/history-shadow.js.map +1 -0
  22. package/dist/agents/index.d.ts +68 -0
  23. package/dist/agents/index.d.ts.map +1 -0
  24. package/dist/agents/index.js +74 -0
  25. package/dist/agents/index.js.map +1 -0
  26. package/dist/agents/lifecycle.d.ts +138 -0
  27. package/dist/agents/lifecycle.d.ts.map +1 -0
  28. package/dist/agents/lifecycle.js +258 -0
  29. package/dist/agents/lifecycle.js.map +1 -0
  30. package/dist/agents/model-selector.d.ts +80 -0
  31. package/dist/agents/model-selector.d.ts.map +1 -0
  32. package/dist/agents/model-selector.js +198 -0
  33. package/dist/agents/model-selector.js.map +1 -0
  34. package/dist/agents/onboarding.d.ts +65 -0
  35. package/dist/agents/onboarding.d.ts.map +1 -0
  36. package/dist/agents/onboarding.js +373 -0
  37. package/dist/agents/onboarding.js.map +1 -0
  38. package/dist/build/bundle.d.ts +32 -0
  39. package/dist/build/bundle.d.ts.map +1 -0
  40. package/dist/build/bundle.js +97 -0
  41. package/dist/build/bundle.js.map +1 -0
  42. package/dist/build/ci-pipeline.d.ts +51 -0
  43. package/dist/build/ci-pipeline.d.ts.map +1 -0
  44. package/dist/build/ci-pipeline.js +180 -0
  45. package/dist/build/ci-pipeline.js.map +1 -0
  46. package/dist/build/github-dist.d.ts +37 -0
  47. package/dist/build/github-dist.d.ts.map +1 -0
  48. package/dist/build/github-dist.js +117 -0
  49. package/dist/build/github-dist.js.map +1 -0
  50. package/dist/build/index.d.ts +11 -0
  51. package/dist/build/index.d.ts.map +1 -0
  52. package/dist/build/index.js +11 -0
  53. package/dist/build/index.js.map +1 -0
  54. package/dist/build/install-migration.d.ts +28 -0
  55. package/dist/build/install-migration.d.ts.map +1 -0
  56. package/dist/build/install-migration.js +103 -0
  57. package/dist/build/install-migration.js.map +1 -0
  58. package/dist/build/npm-package.d.ts +54 -0
  59. package/dist/build/npm-package.d.ts.map +1 -0
  60. package/dist/build/npm-package.js +128 -0
  61. package/dist/build/npm-package.js.map +1 -0
  62. package/dist/build/release.d.ts +108 -0
  63. package/dist/build/release.d.ts.map +1 -0
  64. package/dist/build/release.js +295 -0
  65. package/dist/build/release.js.map +1 -0
  66. package/dist/build/versioning.d.ts +38 -0
  67. package/dist/build/versioning.d.ts.map +1 -0
  68. package/dist/build/versioning.js +113 -0
  69. package/dist/build/versioning.js.map +1 -0
  70. package/dist/casting/casting-engine.d.ts +60 -0
  71. package/dist/casting/casting-engine.d.ts.map +1 -0
  72. package/dist/casting/casting-engine.js +223 -0
  73. package/dist/casting/casting-engine.js.map +1 -0
  74. package/dist/casting/casting-history.d.ts +54 -0
  75. package/dist/casting/casting-history.d.ts.map +1 -0
  76. package/dist/casting/casting-history.js +63 -0
  77. package/dist/casting/casting-history.js.map +1 -0
  78. package/dist/casting/index.d.ts +46 -0
  79. package/dist/casting/index.d.ts.map +1 -0
  80. package/dist/casting/index.js +37 -0
  81. package/dist/casting/index.js.map +1 -0
  82. package/dist/client/event-bus.d.ts +29 -0
  83. package/dist/client/event-bus.d.ts.map +1 -0
  84. package/dist/client/event-bus.js +53 -0
  85. package/dist/client/event-bus.js.map +1 -0
  86. package/dist/client/index.d.ts +100 -0
  87. package/dist/client/index.d.ts.map +1 -0
  88. package/dist/client/index.js +170 -0
  89. package/dist/client/index.js.map +1 -0
  90. package/dist/client/session-pool.d.ts +66 -0
  91. package/dist/client/session-pool.d.ts.map +1 -0
  92. package/dist/client/session-pool.js +145 -0
  93. package/dist/client/session-pool.js.map +1 -0
  94. package/dist/config/agent-doc.d.ts +43 -0
  95. package/dist/config/agent-doc.d.ts.map +1 -0
  96. package/dist/config/agent-doc.js +158 -0
  97. package/dist/config/agent-doc.js.map +1 -0
  98. package/dist/config/agent-source.d.ts +95 -0
  99. package/dist/config/agent-source.d.ts.map +1 -0
  100. package/dist/config/agent-source.js +274 -0
  101. package/dist/config/agent-source.js.map +1 -0
  102. package/dist/config/doc-sync.d.ts +66 -0
  103. package/dist/config/doc-sync.d.ts.map +1 -0
  104. package/dist/config/doc-sync.js +270 -0
  105. package/dist/config/doc-sync.js.map +1 -0
  106. package/dist/config/feature-audit.d.ts +49 -0
  107. package/dist/config/feature-audit.d.ts.map +1 -0
  108. package/dist/config/feature-audit.js +148 -0
  109. package/dist/config/feature-audit.js.map +1 -0
  110. package/dist/config/index.d.ts +15 -0
  111. package/dist/config/index.d.ts.map +1 -0
  112. package/dist/config/index.js +15 -0
  113. package/dist/config/index.js.map +1 -0
  114. package/dist/config/init.d.ts +61 -0
  115. package/dist/config/init.d.ts.map +1 -0
  116. package/dist/config/init.js +369 -0
  117. package/dist/config/init.js.map +1 -0
  118. package/dist/config/legacy-fallback.d.ts +83 -0
  119. package/dist/config/legacy-fallback.d.ts.map +1 -0
  120. package/dist/config/legacy-fallback.js +212 -0
  121. package/dist/config/legacy-fallback.js.map +1 -0
  122. package/dist/config/markdown-migration.d.ts +157 -0
  123. package/dist/config/markdown-migration.d.ts.map +1 -0
  124. package/dist/config/markdown-migration.js +434 -0
  125. package/dist/config/markdown-migration.js.map +1 -0
  126. package/dist/config/migration.d.ts +123 -0
  127. package/dist/config/migration.d.ts.map +1 -0
  128. package/dist/config/migration.js +273 -0
  129. package/dist/config/migration.js.map +1 -0
  130. package/dist/config/migrations/index.d.ts +36 -0
  131. package/dist/config/migrations/index.d.ts.map +1 -0
  132. package/dist/config/migrations/index.js +216 -0
  133. package/dist/config/migrations/index.js.map +1 -0
  134. package/dist/config/models.d.ts +134 -0
  135. package/dist/config/models.d.ts.map +1 -0
  136. package/dist/config/models.js +354 -0
  137. package/dist/config/models.js.map +1 -0
  138. package/dist/config/routing.d.ts +118 -0
  139. package/dist/config/routing.d.ts.map +1 -0
  140. package/dist/config/routing.js +247 -0
  141. package/dist/config/routing.js.map +1 -0
  142. package/dist/config/schema.d.ts +72 -0
  143. package/dist/config/schema.d.ts.map +1 -0
  144. package/dist/config/schema.js +63 -0
  145. package/dist/config/schema.js.map +1 -0
  146. package/dist/coordinator/coordinator.d.ts +82 -0
  147. package/dist/coordinator/coordinator.d.ts.map +1 -0
  148. package/dist/coordinator/coordinator.js +174 -0
  149. package/dist/coordinator/coordinator.js.map +1 -0
  150. package/dist/coordinator/direct-response.d.ts +83 -0
  151. package/dist/coordinator/direct-response.d.ts.map +1 -0
  152. package/dist/coordinator/direct-response.js +187 -0
  153. package/dist/coordinator/direct-response.js.map +1 -0
  154. package/dist/coordinator/fan-out.d.ts +83 -0
  155. package/dist/coordinator/fan-out.d.ts.map +1 -0
  156. package/dist/coordinator/fan-out.js +161 -0
  157. package/dist/coordinator/fan-out.js.map +1 -0
  158. package/dist/coordinator/index.d.ts +47 -0
  159. package/dist/coordinator/index.d.ts.map +1 -0
  160. package/dist/coordinator/index.js +54 -0
  161. package/dist/coordinator/index.js.map +1 -0
  162. package/dist/coordinator/response-tiers.d.ts +49 -0
  163. package/dist/coordinator/response-tiers.d.ts.map +1 -0
  164. package/dist/coordinator/response-tiers.js +149 -0
  165. package/dist/coordinator/response-tiers.js.map +1 -0
  166. package/dist/hooks/index.d.ts +103 -0
  167. package/dist/hooks/index.d.ts.map +1 -0
  168. package/dist/hooks/index.js +279 -0
  169. package/dist/hooks/index.js.map +1 -0
  170. package/dist/index.d.ts +24 -1
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +23 -3
  173. package/dist/index.js.map +1 -1
  174. package/dist/marketplace/backend.d.ts +35 -0
  175. package/dist/marketplace/backend.d.ts.map +1 -0
  176. package/dist/marketplace/backend.js +99 -0
  177. package/dist/marketplace/backend.js.map +1 -0
  178. package/dist/marketplace/browser.d.ts +33 -0
  179. package/dist/marketplace/browser.d.ts.map +1 -0
  180. package/dist/marketplace/browser.js +97 -0
  181. package/dist/marketplace/browser.js.map +1 -0
  182. package/dist/marketplace/extension-adapter.d.ts +51 -0
  183. package/dist/marketplace/extension-adapter.d.ts.map +1 -0
  184. package/dist/marketplace/extension-adapter.js +81 -0
  185. package/dist/marketplace/extension-adapter.js.map +1 -0
  186. package/dist/marketplace/index.d.ts +51 -0
  187. package/dist/marketplace/index.d.ts.map +1 -0
  188. package/dist/marketplace/index.js +108 -0
  189. package/dist/marketplace/index.js.map +1 -0
  190. package/dist/marketplace/packaging.d.ts +25 -0
  191. package/dist/marketplace/packaging.d.ts.map +1 -0
  192. package/dist/marketplace/packaging.js +117 -0
  193. package/dist/marketplace/packaging.js.map +1 -0
  194. package/dist/marketplace/schema.d.ts +50 -0
  195. package/dist/marketplace/schema.d.ts.map +1 -0
  196. package/dist/marketplace/schema.js +120 -0
  197. package/dist/marketplace/schema.js.map +1 -0
  198. package/dist/marketplace/security.d.ts +26 -0
  199. package/dist/marketplace/security.d.ts.map +1 -0
  200. package/dist/marketplace/security.js +199 -0
  201. package/dist/marketplace/security.js.map +1 -0
  202. package/dist/parsers.d.ts +15 -0
  203. package/dist/parsers.d.ts.map +1 -0
  204. package/dist/parsers.js +15 -0
  205. package/dist/parsers.js.map +1 -0
  206. package/dist/ralph/index.d.ts +56 -0
  207. package/dist/ralph/index.d.ts.map +1 -0
  208. package/dist/ralph/index.js +61 -0
  209. package/dist/ralph/index.js.map +1 -0
  210. package/dist/resolution.d.ts +47 -0
  211. package/dist/resolution.d.ts.map +1 -0
  212. package/dist/resolution.js +106 -0
  213. package/dist/resolution.js.map +1 -0
  214. package/dist/runtime/benchmarks.d.ts +121 -0
  215. package/dist/runtime/benchmarks.d.ts.map +1 -0
  216. package/dist/runtime/benchmarks.js +251 -0
  217. package/dist/runtime/benchmarks.js.map +1 -0
  218. package/dist/runtime/config.d.ts +313 -0
  219. package/dist/runtime/config.d.ts.map +1 -0
  220. package/dist/runtime/config.js +466 -0
  221. package/dist/runtime/config.js.map +1 -0
  222. package/dist/runtime/cost-tracker.d.ts +73 -0
  223. package/dist/runtime/cost-tracker.d.ts.map +1 -0
  224. package/dist/runtime/cost-tracker.js +157 -0
  225. package/dist/runtime/cost-tracker.js.map +1 -0
  226. package/dist/runtime/event-bus.d.ts +190 -0
  227. package/dist/runtime/event-bus.d.ts.map +1 -0
  228. package/dist/runtime/event-bus.js +218 -0
  229. package/dist/runtime/event-bus.js.map +1 -0
  230. package/dist/runtime/health.d.ts +66 -0
  231. package/dist/runtime/health.d.ts.map +1 -0
  232. package/dist/runtime/health.js +111 -0
  233. package/dist/runtime/health.js.map +1 -0
  234. package/dist/runtime/i18n.d.ts +54 -0
  235. package/dist/runtime/i18n.d.ts.map +1 -0
  236. package/dist/runtime/i18n.js +126 -0
  237. package/dist/runtime/i18n.js.map +1 -0
  238. package/dist/runtime/offline.d.ts +64 -0
  239. package/dist/runtime/offline.d.ts.map +1 -0
  240. package/dist/runtime/offline.js +108 -0
  241. package/dist/runtime/offline.js.map +1 -0
  242. package/dist/runtime/streaming.d.ts +97 -0
  243. package/dist/runtime/streaming.d.ts.map +1 -0
  244. package/dist/runtime/streaming.js +156 -0
  245. package/dist/runtime/streaming.js.map +1 -0
  246. package/dist/runtime/telemetry.d.ts +82 -0
  247. package/dist/runtime/telemetry.d.ts.map +1 -0
  248. package/dist/runtime/telemetry.js +120 -0
  249. package/dist/runtime/telemetry.js.map +1 -0
  250. package/dist/sharing/agent-repo.d.ts +33 -0
  251. package/dist/sharing/agent-repo.d.ts.map +1 -0
  252. package/dist/sharing/agent-repo.js +79 -0
  253. package/dist/sharing/agent-repo.js.map +1 -0
  254. package/dist/sharing/cache.d.ts +36 -0
  255. package/dist/sharing/cache.d.ts.map +1 -0
  256. package/dist/sharing/cache.js +85 -0
  257. package/dist/sharing/cache.js.map +1 -0
  258. package/dist/sharing/conflicts.d.ts +32 -0
  259. package/dist/sharing/conflicts.d.ts.map +1 -0
  260. package/dist/sharing/conflicts.js +121 -0
  261. package/dist/sharing/conflicts.js.map +1 -0
  262. package/dist/sharing/export.d.ts +50 -0
  263. package/dist/sharing/export.d.ts.map +1 -0
  264. package/dist/sharing/export.js +156 -0
  265. package/dist/sharing/export.js.map +1 -0
  266. package/dist/sharing/history-split.d.ts +34 -0
  267. package/dist/sharing/history-split.d.ts.map +1 -0
  268. package/dist/sharing/history-split.js +101 -0
  269. package/dist/sharing/history-split.js.map +1 -0
  270. package/dist/sharing/import.d.ts +37 -0
  271. package/dist/sharing/import.d.ts.map +1 -0
  272. package/dist/sharing/import.js +138 -0
  273. package/dist/sharing/import.js.map +1 -0
  274. package/dist/sharing/index.d.ts +11 -0
  275. package/dist/sharing/index.d.ts.map +1 -0
  276. package/dist/sharing/index.js +11 -0
  277. package/dist/sharing/index.js.map +1 -0
  278. package/dist/sharing/versioning.d.ts +32 -0
  279. package/dist/sharing/versioning.d.ts.map +1 -0
  280. package/dist/sharing/versioning.js +64 -0
  281. package/dist/sharing/versioning.js.map +1 -0
  282. package/dist/skills/index.d.ts +49 -0
  283. package/dist/skills/index.d.ts.map +1 -0
  284. package/dist/skills/index.js +85 -0
  285. package/dist/skills/index.js.map +1 -0
  286. package/dist/skills/skill-loader.d.ts +56 -0
  287. package/dist/skills/skill-loader.d.ts.map +1 -0
  288. package/dist/skills/skill-loader.js +106 -0
  289. package/dist/skills/skill-loader.js.map +1 -0
  290. package/dist/skills/skill-source.d.ts +63 -0
  291. package/dist/skills/skill-source.d.ts.map +1 -0
  292. package/dist/skills/skill-source.js +199 -0
  293. package/dist/skills/skill-source.js.map +1 -0
  294. package/dist/tools/index.d.ts +87 -0
  295. package/dist/tools/index.d.ts.map +1 -0
  296. package/dist/tools/index.js +419 -0
  297. package/dist/tools/index.js.map +1 -0
  298. package/dist/types.d.ts +43 -0
  299. package/dist/types.d.ts.map +1 -0
  300. package/dist/types.js +8 -0
  301. package/dist/types.js.map +1 -0
  302. package/dist/utils/normalize-eol.d.ts +6 -0
  303. package/dist/utils/normalize-eol.d.ts.map +1 -0
  304. package/dist/utils/normalize-eol.js +8 -0
  305. package/dist/utils/normalize-eol.js.map +1 -0
  306. package/package.json +115 -39
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Ralph — Work Monitor (PRD 8)
3
+ *
4
+ * Persistent SDK session that monitors agent work in real time.
5
+ * Replaces ephemeral polling spawns with an event-driven observer
6
+ * that accumulates knowledge across monitoring cycles.
7
+ *
8
+ * Three monitoring layers:
9
+ * 1. In-session: Event subscriptions via EventBus
10
+ * 2. Watchdog: Periodic health checks on session pool
11
+ * 3. Cloud heartbeat: External health signal (future)
12
+ */
13
+ import type { EventBus } from '../client/event-bus.js';
14
+ export interface MonitorConfig {
15
+ /** Team root directory */
16
+ teamRoot: string;
17
+ /** Health check interval (ms, default: 30000) */
18
+ healthCheckInterval?: number;
19
+ /** Stale session threshold (ms, default: 300000) */
20
+ staleSessionThreshold?: number;
21
+ /** Path to persist monitor state for crash recovery */
22
+ statePath?: string;
23
+ }
24
+ export interface AgentWorkStatus {
25
+ agentName: string;
26
+ sessionId: string;
27
+ status: 'working' | 'idle' | 'stale' | 'error';
28
+ lastActivity: Date;
29
+ currentTask?: string;
30
+ milestones: string[];
31
+ }
32
+ export interface MonitorState {
33
+ /** Timestamp of last health check */
34
+ lastHealthCheck: Date | null;
35
+ /** Per-agent work status */
36
+ agents: Map<string, AgentWorkStatus>;
37
+ /** Accumulated observations across cycles */
38
+ observations: string[];
39
+ }
40
+ export declare class RalphMonitor {
41
+ private config;
42
+ private state;
43
+ private eventBus;
44
+ constructor(config: MonitorConfig);
45
+ /** Start monitoring — subscribe to EventBus and begin health checks */
46
+ start(eventBus: EventBus): Promise<void>;
47
+ /** Handle an incoming event from the EventBus */
48
+ private handleEvent;
49
+ /** Run a health check across all tracked agent sessions */
50
+ healthCheck(): Promise<AgentWorkStatus[]>;
51
+ /** Get current work status for all agents */
52
+ getStatus(): AgentWorkStatus[];
53
+ /** Stop monitoring and persist final state */
54
+ stop(): Promise<void>;
55
+ }
56
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ralph/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,wBAAwB,CAAC;AAInE,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IAEjB,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,oDAAoD;IACpD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,YAAY,EAAE,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,eAAe,EAAE,IAAI,GAAG,IAAI,CAAC;IAC7B,4BAA4B;IAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACrC,6CAA6C;IAC7C,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,QAAQ,CAAyB;gBAE7B,MAAM,EAAE,aAAa;IAWjC,uEAAuE;IACjE,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9C,iDAAiD;IACjD,OAAO,CAAC,WAAW;IAMnB,2DAA2D;IACrD,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAQ/C,6CAA6C;IAC7C,SAAS,IAAI,eAAe,EAAE;IAI9B,8CAA8C;IACxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAK5B"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Ralph — Work Monitor (PRD 8)
3
+ *
4
+ * Persistent SDK session that monitors agent work in real time.
5
+ * Replaces ephemeral polling spawns with an event-driven observer
6
+ * that accumulates knowledge across monitoring cycles.
7
+ *
8
+ * Three monitoring layers:
9
+ * 1. In-session: Event subscriptions via EventBus
10
+ * 2. Watchdog: Periodic health checks on session pool
11
+ * 3. Cloud heartbeat: External health signal (future)
12
+ */
13
+ // --- Ralph Monitor ---
14
+ export class RalphMonitor {
15
+ config;
16
+ state;
17
+ eventBus = null;
18
+ constructor(config) {
19
+ this.config = config;
20
+ this.state = {
21
+ lastHealthCheck: null,
22
+ agents: new Map(),
23
+ observations: [],
24
+ };
25
+ // TODO: PRD 8 — Load persisted state from statePath if exists
26
+ // TODO: PRD 8 — Initialize as persistent SDK session via resumeSession('squad-ralph')
27
+ }
28
+ /** Start monitoring — subscribe to EventBus and begin health checks */
29
+ async start(eventBus) {
30
+ this.eventBus = eventBus;
31
+ // TODO: PRD 8 — Subscribe to session lifecycle events
32
+ // TODO: PRD 8 — Subscribe to agent.milestone events
33
+ // TODO: PRD 8 — Start periodic health check timer
34
+ // TODO: PRD 8 — Register onSessionStart hook to track new agents
35
+ }
36
+ /** Handle an incoming event from the EventBus */
37
+ handleEvent(event) {
38
+ // TODO: PRD 8 — Update agent work status based on event type
39
+ // TODO: PRD 8 — Extract [MILESTONE] markers from agent output
40
+ // TODO: PRD 8 — Detect stale sessions and flag for coordinator
41
+ }
42
+ /** Run a health check across all tracked agent sessions */
43
+ async healthCheck() {
44
+ // TODO: PRD 8 — Check each session's last activity timestamp
45
+ // TODO: PRD 8 — Mark stale sessions (no activity > threshold)
46
+ // TODO: PRD 8 — Persist state to statePath for crash recovery
47
+ this.state.lastHealthCheck = new Date();
48
+ return Array.from(this.state.agents.values());
49
+ }
50
+ /** Get current work status for all agents */
51
+ getStatus() {
52
+ return Array.from(this.state.agents.values());
53
+ }
54
+ /** Stop monitoring and persist final state */
55
+ async stop() {
56
+ // TODO: PRD 8 — Unsubscribe from EventBus
57
+ // TODO: PRD 8 — Stop health check timer
58
+ // TODO: PRD 8 — Persist final state to statePath
59
+ }
60
+ }
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ralph/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAsCH,wBAAwB;AAExB,MAAM,OAAO,YAAY;IACf,MAAM,CAAgB;IACtB,KAAK,CAAe;IACpB,QAAQ,GAAoB,IAAI,CAAC;IAEzC,YAAY,MAAqB;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG;YACX,eAAe,EAAE,IAAI;YACrB,MAAM,EAAE,IAAI,GAAG,EAAE;YACjB,YAAY,EAAE,EAAE;SACjB,CAAC;QACF,8DAA8D;QAC9D,sFAAsF;IACxF,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,KAAK,CAAC,QAAkB;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,sDAAsD;QACtD,oDAAoD;QACpD,kDAAkD;QAClD,iEAAiE;IACnE,CAAC;IAED,iDAAiD;IACzC,WAAW,CAAC,KAAiB;QACnC,6DAA6D;QAC7D,8DAA8D;QAC9D,+DAA+D;IACjE,CAAC;IAED,2DAA2D;IAC3D,KAAK,CAAC,WAAW;QACf,6DAA6D;QAC7D,8DAA8D;QAC9D,8DAA8D;QAC9D,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,6CAA6C;IAC7C,SAAS;QACP,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,8CAA8C;IAC9C,KAAK,CAAC,IAAI;QACR,0CAA0C;QAC1C,wCAAwC;QACxC,iDAAiD;IACnD,CAAC;CACF"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Squad directory resolution — walk-up and global path algorithms.
3
+ *
4
+ * resolveSquad() — find .squad/ by walking up from startDir to .git boundary
5
+ * resolveGlobalSquadPath() — platform-specific global config directory
6
+ *
7
+ * @module resolution
8
+ */
9
+ /**
10
+ * Walk up the directory tree from `startDir` looking for a `.squad/` directory.
11
+ *
12
+ * Stops at the repository root (the directory containing `.git`).
13
+ * Returns the **absolute path** to the `.squad/` directory, or `null` if none is found.
14
+ *
15
+ * Handles nested repos, worktrees (`.git` file pointing elsewhere), and symlinks.
16
+ *
17
+ * @param startDir - Directory to start searching from. Defaults to `process.cwd()`.
18
+ * @returns Absolute path to `.squad/` or `null`.
19
+ */
20
+ export declare function resolveSquad(startDir?: string): string | null;
21
+ /**
22
+ * Return the platform-specific global Squad configuration directory.
23
+ *
24
+ * | Platform | Path |
25
+ * |----------|--------------------------------------------|
26
+ * | Windows | `%APPDATA%/squad/` |
27
+ * | macOS | `~/Library/Application Support/squad/` |
28
+ * | Linux | `$XDG_CONFIG_HOME/squad/` (default `~/.config/squad/`) |
29
+ *
30
+ * The directory is created (recursively) if it does not already exist.
31
+ *
32
+ * @returns Absolute path to the global squad config directory.
33
+ */
34
+ export declare function resolveGlobalSquadPath(): string;
35
+ /**
36
+ * Validate that a file path is within `.squad/` or the system temp directory.
37
+ *
38
+ * Use this guard before writing any scratch/temp/state files to ensure Squad
39
+ * never clutters the repo root or arbitrary filesystem locations.
40
+ *
41
+ * @param filePath - Absolute path to validate.
42
+ * @param squadRoot - Absolute path to the `.squad/` directory (e.g. from `resolveSquad()`).
43
+ * @returns The resolved absolute `filePath` if it is safe.
44
+ * @throws If `filePath` is outside `.squad/` and not in the system temp directory.
45
+ */
46
+ export declare function ensureSquadPath(filePath: string, squadRoot: string): string;
47
+ //# sourceMappingURL=resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2B7D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAuB/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmB3E"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Squad directory resolution — walk-up and global path algorithms.
3
+ *
4
+ * resolveSquad() — find .squad/ by walking up from startDir to .git boundary
5
+ * resolveGlobalSquadPath() — platform-specific global config directory
6
+ *
7
+ * @module resolution
8
+ */
9
+ import fs from 'node:fs';
10
+ import path from 'node:path';
11
+ import os from 'node:os';
12
+ /**
13
+ * Walk up the directory tree from `startDir` looking for a `.squad/` directory.
14
+ *
15
+ * Stops at the repository root (the directory containing `.git`).
16
+ * Returns the **absolute path** to the `.squad/` directory, or `null` if none is found.
17
+ *
18
+ * Handles nested repos, worktrees (`.git` file pointing elsewhere), and symlinks.
19
+ *
20
+ * @param startDir - Directory to start searching from. Defaults to `process.cwd()`.
21
+ * @returns Absolute path to `.squad/` or `null`.
22
+ */
23
+ export function resolveSquad(startDir) {
24
+ let current = path.resolve(startDir ?? process.cwd());
25
+ // eslint-disable-next-line no-constant-condition
26
+ while (true) {
27
+ const candidate = path.join(current, '.squad');
28
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
29
+ return candidate;
30
+ }
31
+ // Stop if we hit a .git boundary (directory or worktree file)
32
+ const gitMarker = path.join(current, '.git');
33
+ if (fs.existsSync(gitMarker)) {
34
+ // We've reached the repo root — don't walk higher
35
+ return null;
36
+ }
37
+ const parent = path.dirname(current);
38
+ // Filesystem root reached — nowhere left to walk
39
+ if (parent === current) {
40
+ return null;
41
+ }
42
+ current = parent;
43
+ }
44
+ }
45
+ /**
46
+ * Return the platform-specific global Squad configuration directory.
47
+ *
48
+ * | Platform | Path |
49
+ * |----------|--------------------------------------------|
50
+ * | Windows | `%APPDATA%/squad/` |
51
+ * | macOS | `~/Library/Application Support/squad/` |
52
+ * | Linux | `$XDG_CONFIG_HOME/squad/` (default `~/.config/squad/`) |
53
+ *
54
+ * The directory is created (recursively) if it does not already exist.
55
+ *
56
+ * @returns Absolute path to the global squad config directory.
57
+ */
58
+ export function resolveGlobalSquadPath() {
59
+ const platform = process.platform;
60
+ let base;
61
+ if (platform === 'win32') {
62
+ // %APPDATA% is always set on Windows; fall back to %LOCALAPPDATA%, then homedir
63
+ base = process.env['APPDATA']
64
+ ?? process.env['LOCALAPPDATA']
65
+ ?? path.join(os.homedir(), 'AppData', 'Roaming');
66
+ }
67
+ else if (platform === 'darwin') {
68
+ base = path.join(os.homedir(), 'Library', 'Application Support');
69
+ }
70
+ else {
71
+ // Linux / other POSIX — respect XDG_CONFIG_HOME
72
+ base = process.env['XDG_CONFIG_HOME'] ?? path.join(os.homedir(), '.config');
73
+ }
74
+ const globalDir = path.join(base, 'squad');
75
+ if (!fs.existsSync(globalDir)) {
76
+ fs.mkdirSync(globalDir, { recursive: true });
77
+ }
78
+ return globalDir;
79
+ }
80
+ /**
81
+ * Validate that a file path is within `.squad/` or the system temp directory.
82
+ *
83
+ * Use this guard before writing any scratch/temp/state files to ensure Squad
84
+ * never clutters the repo root or arbitrary filesystem locations.
85
+ *
86
+ * @param filePath - Absolute path to validate.
87
+ * @param squadRoot - Absolute path to the `.squad/` directory (e.g. from `resolveSquad()`).
88
+ * @returns The resolved absolute `filePath` if it is safe.
89
+ * @throws If `filePath` is outside `.squad/` and not in the system temp directory.
90
+ */
91
+ export function ensureSquadPath(filePath, squadRoot) {
92
+ const resolved = path.resolve(filePath);
93
+ const resolvedSquad = path.resolve(squadRoot);
94
+ const resolvedTmp = path.resolve(os.tmpdir());
95
+ // Allow paths inside the .squad/ directory
96
+ if (resolved === resolvedSquad || resolved.startsWith(resolvedSquad + path.sep)) {
97
+ return resolved;
98
+ }
99
+ // Allow paths inside the system temp directory
100
+ if (resolved === resolvedTmp || resolved.startsWith(resolvedTmp + path.sep)) {
101
+ return resolved;
102
+ }
103
+ throw new Error(`Path "${resolved}" is outside the .squad/ directory ("${resolvedSquad}"). ` +
104
+ 'All squad scratch/temp/state files must be written inside .squad/ or the system temp directory.');
105
+ }
106
+ //# sourceMappingURL=resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution.js","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,QAAiB;IAC5C,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAEtD,iDAAiD;IACjD,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE/C,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACrE,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,8DAA8D;QAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,kDAAkD;YAClD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAErC,iDAAiD;QACjD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,IAAY,CAAC;IAEjB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,gFAAgF;QAChF,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;eACxB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;eAC3B,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,gDAAgD;QAChD,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAE3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,SAAiB;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAE9C,2CAA2C;IAC3C,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,CAAC,UAAU,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAChF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,+CAA+C;IAC/C,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,CAAC,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5E,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,SAAS,QAAQ,wCAAwC,aAAa,MAAM;QAC5E,iGAAiG,CAClG,CAAC;AACJ,CAAC"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * M6-11: Performance profiling & benchmarks
3
+ * Provides benchmark utilities to measure Squad operation timings.
4
+ *
5
+ * @module runtime/benchmarks
6
+ */
7
+ /**
8
+ * Result of a single benchmark run.
9
+ */
10
+ export interface BenchmarkResult {
11
+ /** Benchmark name */
12
+ name: string;
13
+ /** Number of iterations run */
14
+ iterations: number;
15
+ /** Average time in ms */
16
+ avg: number;
17
+ /** Minimum time in ms */
18
+ min: number;
19
+ /** Maximum time in ms */
20
+ max: number;
21
+ /** 95th percentile time in ms */
22
+ p95: number;
23
+ /** 99th percentile time in ms */
24
+ p99: number;
25
+ }
26
+ /**
27
+ * Timing summary returned by individual benchmark functions.
28
+ */
29
+ export interface TimingResult {
30
+ avg: number;
31
+ min: number;
32
+ max: number;
33
+ p95: number;
34
+ }
35
+ /**
36
+ * Full benchmark report returned by `runAll`.
37
+ */
38
+ export interface BenchmarkReport {
39
+ results: BenchmarkResult[];
40
+ totalTime: number;
41
+ timestamp: string;
42
+ }
43
+ /**
44
+ * An async operation that can be benchmarked.
45
+ */
46
+ export type BenchmarkFn = () => Promise<void> | void;
47
+ /**
48
+ * Calculate percentile from a sorted array of numbers.
49
+ */
50
+ export declare function percentile(sorted: number[], p: number): number;
51
+ /**
52
+ * Measure the execution time of a function over N iterations and return stats.
53
+ */
54
+ export declare function measureIterations(fn: BenchmarkFn, iterations: number): Promise<{
55
+ avg: number;
56
+ min: number;
57
+ max: number;
58
+ p95: number;
59
+ p99: number;
60
+ timings: number[];
61
+ }>;
62
+ /**
63
+ * Runs performance benchmarks on Squad operations.
64
+ *
65
+ * Usage:
66
+ * ```ts
67
+ * const suite = new BenchmarkSuite();
68
+ * const report = await suite.runAll(100);
69
+ * console.log(formatBenchmarkReport(report.results));
70
+ * ```
71
+ */
72
+ export declare class BenchmarkSuite {
73
+ private benchmarks;
74
+ constructor();
75
+ /**
76
+ * Register a custom benchmark.
77
+ */
78
+ register(name: string, fn: BenchmarkFn): void;
79
+ /**
80
+ * Unregister a benchmark by name.
81
+ */
82
+ unregister(name: string): boolean;
83
+ /**
84
+ * List all registered benchmark names.
85
+ */
86
+ list(): string[];
87
+ /**
88
+ * Benchmark config loading.
89
+ */
90
+ benchmarkConfigLoad(iterations: number): Promise<TimingResult>;
91
+ /**
92
+ * Benchmark charter compilation.
93
+ */
94
+ benchmarkCharterCompile(iterations: number): Promise<TimingResult>;
95
+ /**
96
+ * Benchmark routing operations.
97
+ */
98
+ benchmarkRouting(iterations: number): Promise<TimingResult>;
99
+ /**
100
+ * Benchmark model selection.
101
+ */
102
+ benchmarkModelSelection(iterations: number): Promise<TimingResult>;
103
+ /**
104
+ * Benchmark export/import round-trip.
105
+ */
106
+ benchmarkExportImport(iterations: number): Promise<TimingResult>;
107
+ /**
108
+ * Run all registered benchmarks and produce a full report.
109
+ */
110
+ runAll(iterations?: number): Promise<BenchmarkReport>;
111
+ private configLoadOp;
112
+ private charterCompileOp;
113
+ private routingOp;
114
+ private modelSelectionOp;
115
+ private exportImportOp;
116
+ }
117
+ /**
118
+ * Format benchmark results as a terminal-formatted table.
119
+ */
120
+ export declare function formatBenchmarkReport(results: BenchmarkResult[]): string;
121
+ //# sourceMappingURL=benchmarks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmarks.d.ts","sourceRoot":"","sources":["../../src/runtime/benchmarks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAMrD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,WAAW,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyBjG;AAMD;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAuC;;IAWzD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI;IAI7C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC;;OAEG;IACH,IAAI,IAAI,MAAM,EAAE;IAIhB;;OAEG;IACG,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKpE;;OAEG;IACG,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKxE;;OAEG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKjE;;OAEG;IACG,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKxE;;OAEG;IACG,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKtE;;OAEG;IACG,MAAM,CAAC,UAAU,GAAE,MAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IA4BhE,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,SAAS;IAgBjB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,cAAc;CAYvB;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAiCxE"}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * M6-11: Performance profiling & benchmarks
3
+ * Provides benchmark utilities to measure Squad operation timings.
4
+ *
5
+ * @module runtime/benchmarks
6
+ */
7
+ // ============================================================================
8
+ // Helpers
9
+ // ============================================================================
10
+ /**
11
+ * Calculate percentile from a sorted array of numbers.
12
+ */
13
+ export function percentile(sorted, p) {
14
+ if (sorted.length === 0)
15
+ return 0;
16
+ const idx = Math.ceil((p / 100) * sorted.length) - 1;
17
+ return sorted[Math.max(0, idx)];
18
+ }
19
+ /**
20
+ * Measure the execution time of a function over N iterations and return stats.
21
+ */
22
+ export async function measureIterations(fn, iterations) {
23
+ if (iterations < 1) {
24
+ throw new Error('Iterations must be at least 1');
25
+ }
26
+ const timings = [];
27
+ for (let i = 0; i < iterations; i++) {
28
+ const start = performance.now();
29
+ await fn();
30
+ const end = performance.now();
31
+ timings.push(end - start);
32
+ }
33
+ timings.sort((a, b) => a - b);
34
+ const sum = timings.reduce((a, b) => a + b, 0);
35
+ return {
36
+ avg: sum / timings.length,
37
+ min: timings[0],
38
+ max: timings[timings.length - 1],
39
+ p95: percentile(timings, 95),
40
+ p99: percentile(timings, 99),
41
+ timings,
42
+ };
43
+ }
44
+ // ============================================================================
45
+ // BenchmarkSuite
46
+ // ============================================================================
47
+ /**
48
+ * Runs performance benchmarks on Squad operations.
49
+ *
50
+ * Usage:
51
+ * ```ts
52
+ * const suite = new BenchmarkSuite();
53
+ * const report = await suite.runAll(100);
54
+ * console.log(formatBenchmarkReport(report.results));
55
+ * ```
56
+ */
57
+ export class BenchmarkSuite {
58
+ benchmarks = new Map();
59
+ constructor() {
60
+ // Register built-in benchmarks
61
+ this.benchmarks.set('configLoad', () => this.configLoadOp());
62
+ this.benchmarks.set('charterCompile', () => this.charterCompileOp());
63
+ this.benchmarks.set('routing', () => this.routingOp());
64
+ this.benchmarks.set('modelSelection', () => this.modelSelectionOp());
65
+ this.benchmarks.set('exportImport', () => this.exportImportOp());
66
+ }
67
+ /**
68
+ * Register a custom benchmark.
69
+ */
70
+ register(name, fn) {
71
+ this.benchmarks.set(name, fn);
72
+ }
73
+ /**
74
+ * Unregister a benchmark by name.
75
+ */
76
+ unregister(name) {
77
+ return this.benchmarks.delete(name);
78
+ }
79
+ /**
80
+ * List all registered benchmark names.
81
+ */
82
+ list() {
83
+ return [...this.benchmarks.keys()];
84
+ }
85
+ /**
86
+ * Benchmark config loading.
87
+ */
88
+ async benchmarkConfigLoad(iterations) {
89
+ const stats = await measureIterations(() => this.configLoadOp(), iterations);
90
+ return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
91
+ }
92
+ /**
93
+ * Benchmark charter compilation.
94
+ */
95
+ async benchmarkCharterCompile(iterations) {
96
+ const stats = await measureIterations(() => this.charterCompileOp(), iterations);
97
+ return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
98
+ }
99
+ /**
100
+ * Benchmark routing operations.
101
+ */
102
+ async benchmarkRouting(iterations) {
103
+ const stats = await measureIterations(() => this.routingOp(), iterations);
104
+ return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
105
+ }
106
+ /**
107
+ * Benchmark model selection.
108
+ */
109
+ async benchmarkModelSelection(iterations) {
110
+ const stats = await measureIterations(() => this.modelSelectionOp(), iterations);
111
+ return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
112
+ }
113
+ /**
114
+ * Benchmark export/import round-trip.
115
+ */
116
+ async benchmarkExportImport(iterations) {
117
+ const stats = await measureIterations(() => this.exportImportOp(), iterations);
118
+ return { avg: stats.avg, min: stats.min, max: stats.max, p95: stats.p95 };
119
+ }
120
+ /**
121
+ * Run all registered benchmarks and produce a full report.
122
+ */
123
+ async runAll(iterations = 100) {
124
+ const totalStart = performance.now();
125
+ const results = [];
126
+ for (const [name, fn] of this.benchmarks) {
127
+ const stats = await measureIterations(fn, iterations);
128
+ results.push({
129
+ name,
130
+ iterations,
131
+ avg: stats.avg,
132
+ min: stats.min,
133
+ max: stats.max,
134
+ p95: stats.p95,
135
+ p99: stats.p99,
136
+ });
137
+ }
138
+ const totalTime = performance.now() - totalStart;
139
+ return {
140
+ results,
141
+ totalTime,
142
+ timestamp: new Date().toISOString(),
143
+ };
144
+ }
145
+ // -- Internal operations simulating real Squad work --
146
+ configLoadOp() {
147
+ // Simulate config parsing: build and validate a config-like object
148
+ const config = {
149
+ version: '1.0.0',
150
+ models: { defaultModel: 'claude-sonnet-4.5', defaultTier: 'standard', fallbackChains: { premium: [], standard: [], fast: [] } },
151
+ routing: { rules: [{ workType: 'feature-dev', agents: ['@coordinator'] }] },
152
+ };
153
+ JSON.parse(JSON.stringify(config));
154
+ }
155
+ charterCompileOp() {
156
+ // Simulate agent charter compilation from markdown
157
+ const charter = `# Agent Charter\n\n## Role\nCore developer\n\n## Skills\n- TypeScript\n- Testing\n\n## Rules\n1. Follow conventions\n2. Write tests`;
158
+ const lines = charter.split('\n');
159
+ const sections = {};
160
+ let current = '';
161
+ for (const line of lines) {
162
+ if (line.startsWith('## ')) {
163
+ current = line.slice(3).trim().toLowerCase();
164
+ sections[current] = [];
165
+ }
166
+ else if (current) {
167
+ sections[current].push(line);
168
+ }
169
+ }
170
+ JSON.stringify(sections);
171
+ }
172
+ routingOp() {
173
+ // Simulate routing rule evaluation
174
+ const rules = [
175
+ { workType: 'feature-dev', agents: ['fenster'], patterns: [/feature/i, /feat/i] },
176
+ { workType: 'bug-fix', agents: ['kujan'], patterns: [/bug/i, /fix/i] },
177
+ { workType: 'testing', agents: ['verbal'], patterns: [/test/i, /spec/i] },
178
+ { workType: 'documentation', agents: ['mcmanus'], patterns: [/doc/i, /readme/i] },
179
+ ];
180
+ const input = 'Implement a new feature for the routing module';
181
+ for (const rule of rules) {
182
+ for (const pattern of rule.patterns) {
183
+ if (pattern.test(input))
184
+ break;
185
+ }
186
+ }
187
+ }
188
+ modelSelectionOp() {
189
+ // Simulate model selection logic
190
+ const tiers = {
191
+ premium: ['claude-opus-4.6', 'gpt-5.2'],
192
+ standard: ['claude-sonnet-4.5', 'gpt-5.1-codex'],
193
+ fast: ['claude-haiku-4.5', 'gpt-5-mini'],
194
+ };
195
+ const role = 'developer';
196
+ const complexity = 7;
197
+ const tier = complexity > 8 ? 'premium' : complexity > 4 ? 'standard' : 'fast';
198
+ const models = tiers[tier];
199
+ const _selected = models[0];
200
+ void _selected;
201
+ void role;
202
+ }
203
+ exportImportOp() {
204
+ // Simulate export → serialize → deserialize → import round-trip
205
+ const bundle = {
206
+ config: { version: '1.0.0', models: {}, routing: { rules: [] } },
207
+ agents: [{ name: 'fenster', role: 'developer', content: '# Fenster' }],
208
+ skills: ['typescript', 'testing'],
209
+ routingRules: [{ pattern: 'feature/*', agent: 'fenster' }],
210
+ metadata: { version: '1.0.0', timestamp: new Date().toISOString(), source: 'test' },
211
+ };
212
+ const serialized = JSON.stringify(bundle);
213
+ JSON.parse(serialized);
214
+ }
215
+ }
216
+ // ============================================================================
217
+ // Report Formatting
218
+ // ============================================================================
219
+ /**
220
+ * Format benchmark results as a terminal-formatted table.
221
+ */
222
+ export function formatBenchmarkReport(results) {
223
+ if (results.length === 0) {
224
+ return 'No benchmark results to display.';
225
+ }
226
+ const COL_NAME = 24;
227
+ const COL_NUM = 12;
228
+ const header = [
229
+ 'Name'.padEnd(COL_NAME),
230
+ 'Iter'.padStart(COL_NUM),
231
+ 'Avg (ms)'.padStart(COL_NUM),
232
+ 'Min (ms)'.padStart(COL_NUM),
233
+ 'Max (ms)'.padStart(COL_NUM),
234
+ 'P95 (ms)'.padStart(COL_NUM),
235
+ 'P99 (ms)'.padStart(COL_NUM),
236
+ ].join(' ');
237
+ const separator = '─'.repeat(header.length);
238
+ const rows = results.map((r) => {
239
+ return [
240
+ r.name.padEnd(COL_NAME),
241
+ String(r.iterations).padStart(COL_NUM),
242
+ r.avg.toFixed(3).padStart(COL_NUM),
243
+ r.min.toFixed(3).padStart(COL_NUM),
244
+ r.max.toFixed(3).padStart(COL_NUM),
245
+ r.p95.toFixed(3).padStart(COL_NUM),
246
+ r.p99.toFixed(3).padStart(COL_NUM),
247
+ ].join(' ');
248
+ });
249
+ return [separator, header, separator, ...rows, separator].join('\n');
250
+ }
251
+ //# sourceMappingURL=benchmarks.js.map