@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,157 @@
1
+ /**
2
+ * Cost Tracker
3
+ *
4
+ * Accumulates cost and token data across a squad run with per-agent and
5
+ * per-session breakdowns. Wires into EventBus for real-time updates.
6
+ *
7
+ * @module runtime/cost-tracker
8
+ */
9
+ // ============================================================================
10
+ // CostTracker
11
+ // ============================================================================
12
+ /**
13
+ * Accumulates cost/token data across the squad run.
14
+ *
15
+ * Can be wired to an EventBus to receive live usage events or fed
16
+ * data manually via `recordUsage()`.
17
+ */
18
+ export class CostTracker {
19
+ agents = new Map();
20
+ sessions = new Map();
21
+ unsubscribe = null;
22
+ /**
23
+ * Record a single usage event.
24
+ */
25
+ recordUsage(opts) {
26
+ const agentKey = opts.agentName ?? 'unknown';
27
+ // Per-agent
28
+ const agent = this.agents.get(agentKey);
29
+ if (agent) {
30
+ agent.inputTokens += opts.inputTokens;
31
+ agent.outputTokens += opts.outputTokens;
32
+ agent.estimatedCost += opts.estimatedCost;
33
+ agent.turnCount += 1;
34
+ agent.model = opts.model;
35
+ if (opts.isFallback)
36
+ agent.fallbackCount += 1;
37
+ }
38
+ else {
39
+ this.agents.set(agentKey, {
40
+ agentName: agentKey,
41
+ model: opts.model,
42
+ inputTokens: opts.inputTokens,
43
+ outputTokens: opts.outputTokens,
44
+ estimatedCost: opts.estimatedCost,
45
+ turnCount: 1,
46
+ fallbackCount: opts.isFallback ? 1 : 0,
47
+ });
48
+ }
49
+ // Per-session
50
+ const session = this.sessions.get(opts.sessionId);
51
+ if (session) {
52
+ session.inputTokens += opts.inputTokens;
53
+ session.outputTokens += opts.outputTokens;
54
+ session.estimatedCost += opts.estimatedCost;
55
+ session.turnCount += 1;
56
+ }
57
+ else {
58
+ this.sessions.set(opts.sessionId, {
59
+ sessionId: opts.sessionId,
60
+ agentName: opts.agentName,
61
+ inputTokens: opts.inputTokens,
62
+ outputTokens: opts.outputTokens,
63
+ estimatedCost: opts.estimatedCost,
64
+ turnCount: 1,
65
+ });
66
+ }
67
+ }
68
+ /** Record a model fallback for an agent (increments fallback counter). */
69
+ recordFallback(agentName) {
70
+ const agent = this.agents.get(agentName);
71
+ if (agent) {
72
+ agent.fallbackCount += 1;
73
+ }
74
+ }
75
+ /** Get the full cost summary. */
76
+ getSummary() {
77
+ let totalInputTokens = 0;
78
+ let totalOutputTokens = 0;
79
+ let totalEstimatedCost = 0;
80
+ for (const entry of this.agents.values()) {
81
+ totalInputTokens += entry.inputTokens;
82
+ totalOutputTokens += entry.outputTokens;
83
+ totalEstimatedCost += entry.estimatedCost;
84
+ }
85
+ return {
86
+ totalInputTokens,
87
+ totalOutputTokens,
88
+ totalEstimatedCost,
89
+ agents: new Map(this.agents),
90
+ sessions: new Map(this.sessions),
91
+ };
92
+ }
93
+ /** Get formatted summary string suitable for terminal output. */
94
+ formatSummary() {
95
+ const summary = this.getSummary();
96
+ const lines = [];
97
+ lines.push('=== Squad Cost Summary ===');
98
+ lines.push(`Total input tokens: ${summary.totalInputTokens.toLocaleString()}`);
99
+ lines.push(`Total output tokens: ${summary.totalOutputTokens.toLocaleString()}`);
100
+ lines.push(`Estimated cost: $${summary.totalEstimatedCost.toFixed(4)}`);
101
+ if (summary.agents.size > 0) {
102
+ lines.push('');
103
+ lines.push('--- By Agent ---');
104
+ for (const [name, entry] of summary.agents) {
105
+ lines.push(` ${name}: ${entry.inputTokens.toLocaleString()}in / ${entry.outputTokens.toLocaleString()}out` +
106
+ ` ($${entry.estimatedCost.toFixed(4)}) [${entry.turnCount} turns, model: ${entry.model}` +
107
+ `${entry.fallbackCount > 0 ? `, ${entry.fallbackCount} fallbacks` : ''}]`);
108
+ }
109
+ }
110
+ if (summary.sessions.size > 0) {
111
+ lines.push('');
112
+ lines.push('--- By Session ---');
113
+ for (const [id, entry] of summary.sessions) {
114
+ lines.push(` ${id}: ${entry.inputTokens.toLocaleString()}in / ${entry.outputTokens.toLocaleString()}out` +
115
+ ` ($${entry.estimatedCost.toFixed(4)}) [${entry.turnCount} turns]`);
116
+ }
117
+ }
118
+ return lines.join('\n');
119
+ }
120
+ /** Clear all accumulated data. */
121
+ reset() {
122
+ this.agents.clear();
123
+ this.sessions.clear();
124
+ }
125
+ /**
126
+ * Wire into an EventBus to receive real-time `session:message` events
127
+ * that carry usage payloads. Returns an unsubscribe function.
128
+ */
129
+ wireToEventBus(bus) {
130
+ const handler = (event) => {
131
+ const payload = event.payload;
132
+ if (!payload)
133
+ return;
134
+ // Accept events with usage data in the payload
135
+ if (typeof payload.inputTokens === 'number' &&
136
+ typeof payload.outputTokens === 'number') {
137
+ this.recordUsage({
138
+ sessionId: event.sessionId ?? 'unknown',
139
+ agentName: event.agentName,
140
+ model: payload.model ?? 'unknown',
141
+ inputTokens: payload.inputTokens,
142
+ outputTokens: payload.outputTokens,
143
+ estimatedCost: payload.estimatedCost ?? 0,
144
+ isFallback: payload.isFallback ?? false,
145
+ });
146
+ }
147
+ };
148
+ this.unsubscribe = bus.subscribe('session:message', handler);
149
+ return () => {
150
+ if (this.unsubscribe) {
151
+ this.unsubscribe();
152
+ this.unsubscribe = null;
153
+ }
154
+ };
155
+ }
156
+ }
157
+ //# sourceMappingURL=cost-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-tracker.js","sourceRoot":"","sources":["../../src/runtime/cost-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Cross-Session Event Bus (M0-5, Issue #77)
3
+ *
4
+ * Pub/sub event bus for session lifecycle events with cross-session aggregation.
5
+ * Enables the coordinator to observe all agent sessions from a single subscription point.
6
+ * Decouples event producers (sessions) from consumers (coordinator, Ralph, UI).
7
+ *
8
+ * @module runtime/event-bus
9
+ */
10
+ /**
11
+ * Core lifecycle events emitted by Squad sessions.
12
+ * All lifecycle events are persistent and logged for debugging.
13
+ */
14
+ export type SquadLifecycleEvent = 'session:created' | 'session:idle' | 'session:error' | 'session:destroyed';
15
+ /**
16
+ * Additional operational events for coordination and monitoring.
17
+ */
18
+ export type SquadOperationalEvent = 'session:message' | 'session:tool_call' | 'agent:milestone' | 'coordinator:routing' | 'pool:health';
19
+ /**
20
+ * All event types supported by the event bus.
21
+ */
22
+ export type SquadEventType = SquadLifecycleEvent | SquadOperationalEvent;
23
+ /**
24
+ * Base event structure with required metadata.
25
+ * All events include a timestamp for chronological ordering and debugging.
26
+ */
27
+ export interface SquadEvent {
28
+ /** Event type identifier */
29
+ type: SquadEventType;
30
+ /** Session ID that originated this event (optional for pool-level events) */
31
+ sessionId?: string;
32
+ /** Agent name associated with this event (optional) */
33
+ agentName?: string;
34
+ /** Event-specific payload data */
35
+ payload: unknown;
36
+ /** Timestamp when event was created */
37
+ timestamp: Date;
38
+ }
39
+ /**
40
+ * Handler function for processing events.
41
+ * Handlers may be synchronous or asynchronous.
42
+ * Errors in handlers are isolated and do not affect other handlers.
43
+ */
44
+ export type EventHandler = (event: SquadEvent) => void | Promise<void>;
45
+ /**
46
+ * Unsubscribe function returned from subscription methods.
47
+ * Call this function to remove the handler from the event bus.
48
+ */
49
+ export type UnsubscribeFn = () => void;
50
+ /**
51
+ * Cross-session event aggregation bus.
52
+ *
53
+ * Key features:
54
+ * - Subscribe to specific event types or all events
55
+ * - Async/sync handler support with error isolation
56
+ * - No race conditions — handlers run in subscription order
57
+ * - Lifecycle events: session:created, session:idle, session:error, session:destroyed
58
+ * - Cross-session aggregation — single subscription point for all sessions
59
+ *
60
+ * Usage:
61
+ * ```typescript
62
+ * const bus = new EventBus();
63
+ *
64
+ * // Subscribe to specific event
65
+ * const unsubscribe = bus.subscribe('session:created', (event) => {
66
+ * console.log('New session:', event.sessionId);
67
+ * });
68
+ *
69
+ * // Subscribe to all events
70
+ * const unsubscribeAll = bus.subscribeAll((event) => {
71
+ * console.log('Event:', event.type);
72
+ * });
73
+ *
74
+ * // Emit event
75
+ * await bus.emit({
76
+ * type: 'session:created',
77
+ * sessionId: 'abc-123',
78
+ * agentName: 'Ralph',
79
+ * payload: { model: 'claude-sonnet-4.5' },
80
+ * timestamp: new Date()
81
+ * });
82
+ *
83
+ * // Clean up
84
+ * unsubscribe();
85
+ * unsubscribeAll();
86
+ * ```
87
+ */
88
+ export declare class EventBus {
89
+ private handlers;
90
+ private allHandlers;
91
+ private errorHandlers;
92
+ /**
93
+ * Subscribe to a specific event type.
94
+ *
95
+ * @param type - Event type to listen for
96
+ * @param handler - Handler function to call when event occurs
97
+ * @returns Unsubscribe function to remove this handler
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const bus = new EventBus();
102
+ * const unsubscribe = bus.subscribe('session:created', (event) => {
103
+ * console.log('Session created:', event.sessionId);
104
+ * });
105
+ *
106
+ * // Later, remove subscription
107
+ * unsubscribe();
108
+ * ```
109
+ */
110
+ subscribe(type: SquadEventType, handler: EventHandler): UnsubscribeFn;
111
+ /**
112
+ * Subscribe to all events regardless of type.
113
+ * Useful for logging, monitoring, or debugging.
114
+ *
115
+ * @param handler - Handler function to call for every event
116
+ * @returns Unsubscribe function to remove this handler
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * const bus = new EventBus();
121
+ * const unsubscribe = bus.subscribeAll((event) => {
122
+ * console.log(`[${event.type}] ${event.sessionId || 'global'}`);
123
+ * });
124
+ * ```
125
+ */
126
+ subscribeAll(handler: EventHandler): UnsubscribeFn;
127
+ /**
128
+ * Unsubscribe a handler from a specific event type.
129
+ *
130
+ * @param type - Event type to unsubscribe from
131
+ * @param handler - Handler function to remove
132
+ */
133
+ unsubscribe(type: SquadEventType, handler: EventHandler): void;
134
+ /**
135
+ * Register an error handler for handler execution failures.
136
+ * Error handlers are called when a subscribed handler throws an error.
137
+ *
138
+ * @param handler - Error handler function
139
+ * @returns Unsubscribe function to remove this error handler
140
+ */
141
+ onError(handler: (error: Error, event: SquadEvent) => void): UnsubscribeFn;
142
+ /**
143
+ * Emit an event to all matching subscribers.
144
+ * Handlers are called in subscription order with error isolation.
145
+ * One handler failure does not prevent other handlers from executing.
146
+ *
147
+ * @param event - Event to emit
148
+ * @returns Promise that resolves when all handlers complete
149
+ *
150
+ * @example
151
+ * ```typescript
152
+ * await bus.emit({
153
+ * type: 'session:created',
154
+ * sessionId: 'abc-123',
155
+ * agentName: 'Ralph',
156
+ * payload: { model: 'claude-sonnet-4.5' },
157
+ * timestamp: new Date()
158
+ * });
159
+ * ```
160
+ */
161
+ emit(event: SquadEvent): Promise<void>;
162
+ /**
163
+ * Execute a single handler with error isolation.
164
+ * Catches and reports handler errors without propagating them.
165
+ *
166
+ * @param handler - Handler function to execute
167
+ * @param event - Event to pass to handler
168
+ */
169
+ private executeHandler;
170
+ /**
171
+ * Remove all handlers and reset the event bus.
172
+ * Useful for cleanup in tests or when shutting down.
173
+ */
174
+ clear(): void;
175
+ /**
176
+ * Get count of handlers for a specific event type.
177
+ * Useful for debugging and testing.
178
+ *
179
+ * @param type - Event type to count handlers for
180
+ * @returns Number of handlers subscribed to this event type
181
+ */
182
+ getHandlerCount(type: SquadEventType): number;
183
+ /**
184
+ * Get count of wildcard handlers.
185
+ *
186
+ * @returns Number of handlers subscribed to all events
187
+ */
188
+ getAllHandlerCount(): number;
189
+ }
190
+ //# sourceMappingURL=event-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/runtime/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAC3B,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,mBAAmB,CAAC;AAExB;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B,iBAAiB,GACjB,mBAAmB,GACnB,iBAAiB,GACjB,qBAAqB,GACrB,aAAa,CAAC;AAElB;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAEzE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC;AAMvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAqD;IACrE,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,aAAa,CAA6D;IAElF;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,GAAG,aAAa;IASrE;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa;IAKlD;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAS9D;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,aAAa;IAK1E;;;;;;;;;;;;;;;;;;OAkBG;IACG,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB5C;;;;;;OAMG;YACW,cAAc;IA2B5B;;;OAGG;IACH,KAAK,IAAI,IAAI;IAMb;;;;;;OAMG;IACH,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAI7C;;;;OAIG;IACH,kBAAkB,IAAI,MAAM;CAG7B"}
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Cross-Session Event Bus (M0-5, Issue #77)
3
+ *
4
+ * Pub/sub event bus for session lifecycle events with cross-session aggregation.
5
+ * Enables the coordinator to observe all agent sessions from a single subscription point.
6
+ * Decouples event producers (sessions) from consumers (coordinator, Ralph, UI).
7
+ *
8
+ * @module runtime/event-bus
9
+ */
10
+ // ============================================================================
11
+ // Event Bus Implementation
12
+ // ============================================================================
13
+ /**
14
+ * Cross-session event aggregation bus.
15
+ *
16
+ * Key features:
17
+ * - Subscribe to specific event types or all events
18
+ * - Async/sync handler support with error isolation
19
+ * - No race conditions — handlers run in subscription order
20
+ * - Lifecycle events: session:created, session:idle, session:error, session:destroyed
21
+ * - Cross-session aggregation — single subscription point for all sessions
22
+ *
23
+ * Usage:
24
+ * ```typescript
25
+ * const bus = new EventBus();
26
+ *
27
+ * // Subscribe to specific event
28
+ * const unsubscribe = bus.subscribe('session:created', (event) => {
29
+ * console.log('New session:', event.sessionId);
30
+ * });
31
+ *
32
+ * // Subscribe to all events
33
+ * const unsubscribeAll = bus.subscribeAll((event) => {
34
+ * console.log('Event:', event.type);
35
+ * });
36
+ *
37
+ * // Emit event
38
+ * await bus.emit({
39
+ * type: 'session:created',
40
+ * sessionId: 'abc-123',
41
+ * agentName: 'Ralph',
42
+ * payload: { model: 'claude-sonnet-4.5' },
43
+ * timestamp: new Date()
44
+ * });
45
+ *
46
+ * // Clean up
47
+ * unsubscribe();
48
+ * unsubscribeAll();
49
+ * ```
50
+ */
51
+ export class EventBus {
52
+ handlers = new Map();
53
+ allHandlers = new Set();
54
+ errorHandlers = new Set();
55
+ /**
56
+ * Subscribe to a specific event type.
57
+ *
58
+ * @param type - Event type to listen for
59
+ * @param handler - Handler function to call when event occurs
60
+ * @returns Unsubscribe function to remove this handler
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const bus = new EventBus();
65
+ * const unsubscribe = bus.subscribe('session:created', (event) => {
66
+ * console.log('Session created:', event.sessionId);
67
+ * });
68
+ *
69
+ * // Later, remove subscription
70
+ * unsubscribe();
71
+ * ```
72
+ */
73
+ subscribe(type, handler) {
74
+ if (!this.handlers.has(type)) {
75
+ this.handlers.set(type, new Set());
76
+ }
77
+ this.handlers.get(type).add(handler);
78
+ return () => this.unsubscribe(type, handler);
79
+ }
80
+ /**
81
+ * Subscribe to all events regardless of type.
82
+ * Useful for logging, monitoring, or debugging.
83
+ *
84
+ * @param handler - Handler function to call for every event
85
+ * @returns Unsubscribe function to remove this handler
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * const bus = new EventBus();
90
+ * const unsubscribe = bus.subscribeAll((event) => {
91
+ * console.log(`[${event.type}] ${event.sessionId || 'global'}`);
92
+ * });
93
+ * ```
94
+ */
95
+ subscribeAll(handler) {
96
+ this.allHandlers.add(handler);
97
+ return () => this.allHandlers.delete(handler);
98
+ }
99
+ /**
100
+ * Unsubscribe a handler from a specific event type.
101
+ *
102
+ * @param type - Event type to unsubscribe from
103
+ * @param handler - Handler function to remove
104
+ */
105
+ unsubscribe(type, handler) {
106
+ this.handlers.get(type)?.delete(handler);
107
+ // Clean up empty handler sets
108
+ if (this.handlers.get(type)?.size === 0) {
109
+ this.handlers.delete(type);
110
+ }
111
+ }
112
+ /**
113
+ * Register an error handler for handler execution failures.
114
+ * Error handlers are called when a subscribed handler throws an error.
115
+ *
116
+ * @param handler - Error handler function
117
+ * @returns Unsubscribe function to remove this error handler
118
+ */
119
+ onError(handler) {
120
+ this.errorHandlers.add(handler);
121
+ return () => this.errorHandlers.delete(handler);
122
+ }
123
+ /**
124
+ * Emit an event to all matching subscribers.
125
+ * Handlers are called in subscription order with error isolation.
126
+ * One handler failure does not prevent other handlers from executing.
127
+ *
128
+ * @param event - Event to emit
129
+ * @returns Promise that resolves when all handlers complete
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * await bus.emit({
134
+ * type: 'session:created',
135
+ * sessionId: 'abc-123',
136
+ * agentName: 'Ralph',
137
+ * payload: { model: 'claude-sonnet-4.5' },
138
+ * timestamp: new Date()
139
+ * });
140
+ * ```
141
+ */
142
+ async emit(event) {
143
+ const typeHandlers = this.handlers.get(event.type) ?? new Set();
144
+ const allPromises = [];
145
+ // Execute type-specific handlers
146
+ for (const handler of typeHandlers) {
147
+ allPromises.push(this.executeHandler(handler, event));
148
+ }
149
+ // Execute wildcard handlers
150
+ for (const handler of this.allHandlers) {
151
+ allPromises.push(this.executeHandler(handler, event));
152
+ }
153
+ // Wait for all handlers to complete
154
+ // Errors are isolated and won't throw from here
155
+ await Promise.all(allPromises);
156
+ }
157
+ /**
158
+ * Execute a single handler with error isolation.
159
+ * Catches and reports handler errors without propagating them.
160
+ *
161
+ * @param handler - Handler function to execute
162
+ * @param event - Event to pass to handler
163
+ */
164
+ async executeHandler(handler, event) {
165
+ try {
166
+ const result = handler(event);
167
+ if (result instanceof Promise) {
168
+ await result;
169
+ }
170
+ }
171
+ catch (error) {
172
+ // Isolate handler errors — one failure shouldn't crash others
173
+ const wrappedError = error instanceof Error ? error : new Error(String(error));
174
+ // Notify error handlers
175
+ for (const errorHandler of this.errorHandlers) {
176
+ try {
177
+ errorHandler(wrappedError, event);
178
+ }
179
+ catch (errorHandlerError) {
180
+ // Error handler itself failed — log to console as last resort
181
+ console.error('EventBus error handler failed:', errorHandlerError);
182
+ }
183
+ }
184
+ // If no error handlers registered, log to console
185
+ if (this.errorHandlers.size === 0) {
186
+ console.error(`EventBus handler error for ${event.type}:`, wrappedError);
187
+ }
188
+ }
189
+ }
190
+ /**
191
+ * Remove all handlers and reset the event bus.
192
+ * Useful for cleanup in tests or when shutting down.
193
+ */
194
+ clear() {
195
+ this.handlers.clear();
196
+ this.allHandlers.clear();
197
+ this.errorHandlers.clear();
198
+ }
199
+ /**
200
+ * Get count of handlers for a specific event type.
201
+ * Useful for debugging and testing.
202
+ *
203
+ * @param type - Event type to count handlers for
204
+ * @returns Number of handlers subscribed to this event type
205
+ */
206
+ getHandlerCount(type) {
207
+ return this.handlers.get(type)?.size ?? 0;
208
+ }
209
+ /**
210
+ * Get count of wildcard handlers.
211
+ *
212
+ * @returns Number of handlers subscribed to all events
213
+ */
214
+ getAllHandlerCount() {
215
+ return this.allHandlers.size;
216
+ }
217
+ }
218
+ //# sourceMappingURL=event-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../src/runtime/event-bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Health Monitor (M0-8 #83)
3
+ *
4
+ * Monitors the health of SquadClient connections and provides diagnostics.
5
+ * Exposes health status for external monitoring and startup validation.
6
+ */
7
+ import type { SquadClient } from '../adapter/client.js';
8
+ export interface HealthCheckResult {
9
+ /** Overall health status */
10
+ status: 'healthy' | 'degraded' | 'unhealthy';
11
+ /** Connection state */
12
+ connectionState: string;
13
+ /** Whether the client is connected */
14
+ connected: boolean;
15
+ /** Error message if unhealthy */
16
+ error?: string;
17
+ /** Protocol version if available */
18
+ protocolVersion?: number;
19
+ /** Timestamp of the check */
20
+ timestamp: Date;
21
+ /** Response time in milliseconds */
22
+ responseTimeMs?: number;
23
+ }
24
+ export interface HealthMonitorConfig {
25
+ /** Client to monitor */
26
+ client: SquadClient;
27
+ /** Timeout for health checks in milliseconds (default: 5000) */
28
+ timeout?: number;
29
+ /** Log diagnostic information on failures */
30
+ logDiagnostics?: boolean;
31
+ }
32
+ /**
33
+ * Health Monitor for SquadClient connections.
34
+ *
35
+ * Provides health checks, diagnostics logging, and external health status.
36
+ * Use check() for startup validation before creating sessions.
37
+ */
38
+ export declare class HealthMonitor {
39
+ private client;
40
+ private timeout;
41
+ private logDiagnostics;
42
+ constructor(config: HealthMonitorConfig);
43
+ /**
44
+ * Perform a health check on the client connection.
45
+ *
46
+ * This method:
47
+ * 1. Checks connection state
48
+ * 2. Attempts a ping if connected
49
+ * 3. Validates protocol version
50
+ * 4. Logs diagnostics on failure
51
+ *
52
+ * @returns Health check result with status and diagnostics
53
+ */
54
+ check(): Promise<HealthCheckResult>;
55
+ /**
56
+ * Get current status without performing a health check.
57
+ *
58
+ * @returns Basic health status based on connection state
59
+ */
60
+ getStatus(): Pick<HealthCheckResult, 'status' | 'connectionState' | 'connected' | 'timestamp'>;
61
+ /**
62
+ * Log diagnostic information on connection failures.
63
+ */
64
+ private logDiagnostic;
65
+ }
66
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/runtime/health.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAE7C,uBAAuB;IACvB,eAAe,EAAE,MAAM,CAAC;IAExB,sCAAsC;IACtC,SAAS,EAAE,OAAO,CAAC;IAEnB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,oCAAoC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6BAA6B;IAC7B,SAAS,EAAE,IAAI,CAAC;IAEhB,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,wBAAwB;IACxB,MAAM,EAAE,WAAW,CAAC;IAEpB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAU;gBAEpB,MAAM,EAAE,mBAAmB;IAMvC;;;;;;;;;;OAUG;IACG,KAAK,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAgDzC;;;;OAIG;IACH,SAAS,IAAI,IAAI,CAAC,iBAAiB,EAAE,QAAQ,GAAG,iBAAiB,GAAG,WAAW,GAAG,WAAW,CAAC;IAqB9F;;OAEG;IACH,OAAO,CAAC,aAAa;CAQtB"}