@ai-devkit/agent-manager 0.37.0 → 0.38.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 (295) hide show
  1. package/dist/AgentManager.d.ts +0 -4
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +2 -2
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/__tests__/capacity/anthropic.test.js +115 -0
  6. package/dist/__tests__/capacity/anthropic.test.js.map +1 -0
  7. package/dist/__tests__/capacity/boundaries.test.js +45 -0
  8. package/dist/__tests__/capacity/boundaries.test.js.map +1 -0
  9. package/dist/__tests__/capacity/claude.test.js +3 -3
  10. package/dist/__tests__/capacity/claude.test.js.map +1 -1
  11. package/dist/__tests__/capacity/codex.test.js +3 -1
  12. package/dist/__tests__/capacity/codex.test.js.map +1 -1
  13. package/dist/__tests__/capacity/openai.test.js +21 -12
  14. package/dist/__tests__/capacity/openai.test.js.map +1 -1
  15. package/dist/__tests__/capacity/wham.test.js +1 -1
  16. package/dist/__tests__/capacity/wham.test.js.map +1 -1
  17. package/dist/__tests__/capacity/zai.test.js +7 -8
  18. package/dist/__tests__/capacity/zai.test.js.map +1 -1
  19. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js +2 -1
  20. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -1
  21. package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -1
  22. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js +7 -15
  23. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -1
  24. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js +3 -1
  25. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -1
  26. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js +11 -26
  27. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -1
  28. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js +3 -7
  29. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -1
  30. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js +5 -11
  31. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js.map +1 -1
  32. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js +9 -19
  33. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js.map +1 -1
  34. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js +3 -7
  35. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js.map +1 -1
  36. package/dist/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.js +31 -10
  37. package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js.map +1 -0
  38. package/dist/__tests__/harnesses/runtimeProfiles.test.js +89 -0
  39. package/dist/__tests__/harnesses/runtimeProfiles.test.js.map +1 -0
  40. package/dist/__tests__/print/DurableAgent.test.js +4 -6
  41. package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
  42. package/dist/__tests__/print/DurableAgentRepository.test.js +1 -12
  43. package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
  44. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
  45. package/dist/__tests__/terminal/TmuxManager.test.js +1 -1
  46. package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
  47. package/dist/capacity/index.d.ts +9 -19
  48. package/dist/capacity/index.d.ts.map +1 -1
  49. package/dist/capacity/index.js +11 -4
  50. package/dist/capacity/index.js.map +1 -1
  51. package/dist/capacity/providers/anthropic.d.ts +9 -0
  52. package/dist/capacity/providers/anthropic.d.ts.map +1 -0
  53. package/dist/capacity/{claude.js → providers/anthropic.js} +10 -128
  54. package/dist/capacity/providers/anthropic.js.map +1 -0
  55. package/dist/capacity/providers/openai-platform.d.ts +14 -0
  56. package/dist/capacity/providers/openai-platform.d.ts.map +1 -0
  57. package/dist/capacity/providers/openai-platform.js +120 -0
  58. package/dist/capacity/providers/openai-platform.js.map +1 -0
  59. package/dist/capacity/providers/openai-subscription.d.ts +20 -0
  60. package/dist/capacity/providers/openai-subscription.d.ts.map +1 -0
  61. package/dist/capacity/providers/openai-subscription.js +129 -0
  62. package/dist/capacity/providers/openai-subscription.js.map +1 -0
  63. package/dist/capacity/providers/zai.d.ts +8 -0
  64. package/dist/capacity/providers/zai.d.ts.map +1 -0
  65. package/dist/capacity/{zai.js → providers/zai.js} +17 -62
  66. package/dist/capacity/providers/zai.js.map +1 -0
  67. package/dist/capacity/sources/claude.d.ts +9 -0
  68. package/dist/capacity/sources/claude.d.ts.map +1 -0
  69. package/dist/capacity/sources/claude.js +17 -0
  70. package/dist/capacity/sources/claude.js.map +1 -0
  71. package/dist/capacity/{codex.d.ts → sources/codex.d.ts} +5 -9
  72. package/dist/capacity/sources/codex.d.ts.map +1 -0
  73. package/dist/capacity/{codex.js → sources/codex.js} +31 -84
  74. package/dist/capacity/sources/codex.js.map +1 -0
  75. package/dist/capacity/sources/pi.d.ts +30 -0
  76. package/dist/capacity/sources/pi.d.ts.map +1 -0
  77. package/dist/capacity/sources/pi.js +81 -0
  78. package/dist/capacity/sources/pi.js.map +1 -0
  79. package/dist/capacity/types.d.ts +2 -0
  80. package/dist/capacity/types.d.ts.map +1 -1
  81. package/dist/capacity/types.js +1 -1
  82. package/dist/capacity/types.js.map +1 -1
  83. package/dist/harnesses/claude/credentials.d.ts +10 -0
  84. package/dist/harnesses/claude/credentials.d.ts.map +1 -0
  85. package/dist/harnesses/claude/credentials.js +112 -0
  86. package/dist/harnesses/claude/credentials.js.map +1 -0
  87. package/dist/harnesses/claude/readiness.d.ts +3 -0
  88. package/dist/harnesses/claude/readiness.d.ts.map +1 -0
  89. package/dist/harnesses/claude/readiness.js +63 -0
  90. package/dist/harnesses/claude/readiness.js.map +1 -0
  91. package/dist/harnesses/codex/credentials.d.ts +15 -0
  92. package/dist/harnesses/codex/credentials.d.ts.map +1 -0
  93. package/dist/harnesses/codex/credentials.js +58 -0
  94. package/dist/harnesses/codex/credentials.js.map +1 -0
  95. package/dist/harnesses/codex/readiness.d.ts +3 -0
  96. package/dist/harnesses/codex/readiness.d.ts.map +1 -0
  97. package/dist/harnesses/codex/readiness.js +60 -0
  98. package/dist/harnesses/codex/readiness.js.map +1 -0
  99. package/dist/harnesses/copilot/readiness.d.ts +3 -0
  100. package/dist/harnesses/copilot/readiness.d.ts.map +1 -0
  101. package/dist/harnesses/copilot/readiness.js +39 -0
  102. package/dist/harnesses/copilot/readiness.js.map +1 -0
  103. package/dist/harnesses/opencode/readiness.d.ts +3 -0
  104. package/dist/harnesses/opencode/readiness.d.ts.map +1 -0
  105. package/dist/harnesses/opencode/readiness.js +50 -0
  106. package/dist/harnesses/opencode/readiness.js.map +1 -0
  107. package/dist/harnesses/pi/credentials.d.ts +22 -0
  108. package/dist/harnesses/pi/credentials.d.ts.map +1 -0
  109. package/dist/harnesses/pi/credentials.js +98 -0
  110. package/dist/harnesses/pi/credentials.js.map +1 -0
  111. package/dist/harnesses/pi/readiness.d.ts +3 -0
  112. package/dist/harnesses/pi/readiness.d.ts.map +1 -0
  113. package/dist/harnesses/pi/readiness.js +96 -0
  114. package/dist/harnesses/pi/readiness.js.map +1 -0
  115. package/dist/harnesses/readiness/AgentReadiness.d.ts +6 -0
  116. package/dist/harnesses/readiness/AgentReadiness.d.ts.map +1 -0
  117. package/dist/harnesses/readiness/AgentReadiness.js +68 -0
  118. package/dist/harnesses/readiness/AgentReadiness.js.map +1 -0
  119. package/dist/harnesses/readiness/checks.d.ts +31 -0
  120. package/dist/harnesses/readiness/checks.d.ts.map +1 -0
  121. package/dist/harnesses/readiness/checks.js +270 -0
  122. package/dist/harnesses/readiness/checks.js.map +1 -0
  123. package/dist/{readiness/AgentReadiness.d.ts → harnesses/readiness/types.d.ts} +19 -10
  124. package/dist/harnesses/readiness/types.d.ts.map +1 -0
  125. package/dist/harnesses/readiness/types.js +4 -0
  126. package/dist/harnesses/readiness/types.js.map +1 -0
  127. package/dist/harnesses/runtimeProfiles.d.ts +11 -0
  128. package/dist/harnesses/runtimeProfiles.d.ts.map +1 -0
  129. package/dist/harnesses/runtimeProfiles.js +99 -0
  130. package/dist/harnesses/runtimeProfiles.js.map +1 -0
  131. package/dist/index.d.ts +16 -42
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +9 -23
  134. package/dist/index.js.map +1 -1
  135. package/dist/runtime/ManagedAgentRuntime.d.ts +3 -3
  136. package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -1
  137. package/dist/runtime/ManagedAgentRuntime.js +6 -20
  138. package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
  139. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -1
  140. package/dist/runtime/herdr/HerdrAgentDiscovery.js +2 -43
  141. package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
  142. package/dist/runtime/tmux/PidPolling.d.ts +1 -1
  143. package/dist/runtime/tmux/PidPolling.d.ts.map +1 -1
  144. package/dist/runtime/tmux/PidPolling.js.map +1 -1
  145. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +1 -1
  146. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -1
  147. package/dist/runtime/tmux/TmuxAgentRuntime.js +1 -1
  148. package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -1
  149. package/dist/runtime/tmux/TmuxManager.d.ts +12 -0
  150. package/dist/runtime/tmux/TmuxManager.d.ts.map +1 -0
  151. package/dist/{terminal → runtime/tmux}/TmuxManager.js +9 -28
  152. package/dist/runtime/tmux/TmuxManager.js.map +1 -0
  153. package/dist/runtime/types.d.ts +1 -1
  154. package/dist/runtime/types.d.ts.map +1 -1
  155. package/dist/runtime/types.js.map +1 -1
  156. package/dist/terminal/TerminalFocusManager.d.ts +4 -32
  157. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  158. package/dist/terminal/TerminalFocusManager.js +17 -267
  159. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  160. package/dist/terminal/TtyWriter.d.ts +1 -44
  161. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  162. package/dist/terminal/TtyWriter.js +11 -347
  163. package/dist/terminal/TtyWriter.js.map +1 -1
  164. package/dist/terminal/backends/index.d.ts +5 -0
  165. package/dist/terminal/backends/index.d.ts.map +1 -0
  166. package/dist/terminal/backends/index.js +19 -0
  167. package/dist/terminal/backends/index.js.map +1 -0
  168. package/dist/terminal/backends/iterm2.d.ts +3 -0
  169. package/dist/terminal/backends/iterm2.d.ts.map +1 -0
  170. package/dist/terminal/backends/iterm2.js +135 -0
  171. package/dist/terminal/backends/iterm2.js.map +1 -0
  172. package/dist/terminal/backends/shared.d.ts +7 -0
  173. package/dist/terminal/backends/shared.d.ts.map +1 -0
  174. package/dist/terminal/backends/shared.js +35 -0
  175. package/dist/terminal/backends/shared.js.map +1 -0
  176. package/dist/terminal/backends/terminal-app.d.ts +3 -0
  177. package/dist/terminal/backends/terminal-app.d.ts.map +1 -0
  178. package/dist/terminal/backends/terminal-app.js +129 -0
  179. package/dist/terminal/backends/terminal-app.js.map +1 -0
  180. package/dist/terminal/backends/tmux.d.ts +3 -0
  181. package/dist/terminal/backends/tmux.d.ts.map +1 -0
  182. package/dist/terminal/backends/tmux.js +76 -0
  183. package/dist/terminal/backends/tmux.js.map +1 -0
  184. package/dist/terminal/backends/wezterm.d.ts +3 -0
  185. package/dist/terminal/backends/wezterm.d.ts.map +1 -0
  186. package/dist/terminal/backends/wezterm.js +71 -0
  187. package/dist/terminal/backends/wezterm.js.map +1 -0
  188. package/dist/terminal/types.d.ts +21 -0
  189. package/dist/terminal/types.d.ts.map +1 -0
  190. package/dist/terminal/types.js +10 -0
  191. package/dist/terminal/types.js.map +1 -0
  192. package/package.json +1 -1
  193. package/src/AgentManager.ts +1 -1
  194. package/src/__tests__/capacity/anthropic.test.ts +105 -0
  195. package/src/__tests__/capacity/boundaries.test.ts +36 -0
  196. package/src/__tests__/capacity/claude.test.ts +3 -8
  197. package/src/__tests__/capacity/codex.test.ts +12 -35
  198. package/src/__tests__/capacity/fixtures/openai-codex-auth.json +1 -1
  199. package/src/__tests__/capacity/openai.test.ts +15 -15
  200. package/src/__tests__/capacity/wham.test.ts +1 -1
  201. package/src/__tests__/capacity/zai.test.ts +27 -62
  202. package/src/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.ts +2 -2
  203. package/src/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.ts +1 -1
  204. package/src/__tests__/harnesses/codex/durable/CodexCliProbe.test.ts +14 -19
  205. package/src/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.ts +3 -3
  206. package/src/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.ts +24 -30
  207. package/src/__tests__/harnesses/codex/durable/CodexPrintRunner.test.ts +4 -8
  208. package/src/__tests__/harnesses/pi/durable/PiCliProbe.test.ts +7 -11
  209. package/src/__tests__/harnesses/pi/durable/PiPrintAgentService.test.ts +19 -22
  210. package/src/__tests__/harnesses/pi/durable/PiPrintRunner.test.ts +7 -8
  211. package/src/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.ts +36 -9
  212. package/src/__tests__/harnesses/runtimeProfiles.test.ts +110 -0
  213. package/src/__tests__/print/DurableAgent.test.ts +4 -13
  214. package/src/__tests__/print/DurableAgentRepository.test.ts +1 -13
  215. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +1 -1
  216. package/src/__tests__/terminal/TmuxManager.test.ts +1 -1
  217. package/src/capacity/index.ts +29 -23
  218. package/src/capacity/{claude.ts → providers/anthropic.ts} +16 -131
  219. package/src/capacity/providers/openai-platform.ts +150 -0
  220. package/src/capacity/{wham.ts → providers/openai-subscription.ts} +86 -8
  221. package/src/capacity/{zai.ts → providers/zai.ts} +29 -111
  222. package/src/capacity/sources/claude.ts +30 -0
  223. package/src/capacity/{codex.ts → sources/codex.ts} +54 -124
  224. package/src/capacity/sources/pi.ts +131 -0
  225. package/src/capacity/types.ts +3 -0
  226. package/src/harnesses/claude/credentials.ts +122 -0
  227. package/src/harnesses/claude/readiness.ts +69 -0
  228. package/src/harnesses/codex/credentials.ts +81 -0
  229. package/src/harnesses/codex/readiness.ts +72 -0
  230. package/src/harnesses/copilot/readiness.ts +33 -0
  231. package/src/harnesses/opencode/readiness.ts +48 -0
  232. package/src/harnesses/pi/credentials.ts +129 -0
  233. package/src/harnesses/pi/readiness.ts +104 -0
  234. package/src/harnesses/readiness/AgentReadiness.ts +87 -0
  235. package/src/harnesses/readiness/checks.ts +336 -0
  236. package/src/harnesses/readiness/types.ts +90 -0
  237. package/src/{utils/agents.ts → harnesses/runtimeProfiles.ts} +34 -38
  238. package/src/index.ts +15 -128
  239. package/src/runtime/ManagedAgentRuntime.ts +7 -22
  240. package/src/runtime/herdr/HerdrAgentDiscovery.ts +3 -19
  241. package/src/runtime/tmux/PidPolling.ts +1 -1
  242. package/src/runtime/tmux/TmuxAgentRuntime.ts +1 -1
  243. package/src/{terminal → runtime/tmux}/TmuxManager.ts +9 -30
  244. package/src/runtime/types.ts +1 -1
  245. package/src/terminal/TerminalFocusManager.ts +19 -292
  246. package/src/terminal/TtyWriter.ts +16 -336
  247. package/src/terminal/backends/index.ts +21 -0
  248. package/src/terminal/backends/iterm2.ts +126 -0
  249. package/src/terminal/backends/shared.ts +42 -0
  250. package/src/terminal/backends/terminal-app.ts +122 -0
  251. package/src/terminal/backends/tmux.ts +62 -0
  252. package/src/terminal/backends/wezterm.ts +65 -0
  253. package/src/terminal/types.ts +22 -0
  254. package/dist/__tests__/readiness/AgentReadiness.test.js.map +0 -1
  255. package/dist/__tests__/utils/agents.test.js +0 -93
  256. package/dist/__tests__/utils/agents.test.js.map +0 -1
  257. package/dist/capacity/claude.d.ts +0 -17
  258. package/dist/capacity/claude.d.ts.map +0 -1
  259. package/dist/capacity/claude.js.map +0 -1
  260. package/dist/capacity/codex.d.ts.map +0 -1
  261. package/dist/capacity/codex.js.map +0 -1
  262. package/dist/capacity/openai.d.ts +0 -47
  263. package/dist/capacity/openai.d.ts.map +0 -1
  264. package/dist/capacity/openai.js +0 -307
  265. package/dist/capacity/openai.js.map +0 -1
  266. package/dist/capacity/wham.d.ts +0 -16
  267. package/dist/capacity/wham.d.ts.map +0 -1
  268. package/dist/capacity/wham.js +0 -66
  269. package/dist/capacity/wham.js.map +0 -1
  270. package/dist/capacity/zai.d.ts +0 -14
  271. package/dist/capacity/zai.d.ts.map +0 -1
  272. package/dist/capacity/zai.js.map +0 -1
  273. package/dist/readiness/AgentReadiness.d.ts.map +0 -1
  274. package/dist/readiness/AgentReadiness.js +0 -614
  275. package/dist/readiness/AgentReadiness.js.map +0 -1
  276. package/dist/terminal/TmuxManager.d.ts +0 -28
  277. package/dist/terminal/TmuxManager.d.ts.map +0 -1
  278. package/dist/terminal/TmuxManager.js.map +0 -1
  279. package/dist/terminal/index.d.ts +0 -5
  280. package/dist/terminal/index.d.ts.map +0 -1
  281. package/dist/terminal/index.js +0 -5
  282. package/dist/terminal/index.js.map +0 -1
  283. package/dist/utils/agents.d.ts +0 -16
  284. package/dist/utils/agents.d.ts.map +0 -1
  285. package/dist/utils/agents.js +0 -117
  286. package/dist/utils/agents.js.map +0 -1
  287. package/dist/utils/index.d.ts +0 -8
  288. package/dist/utils/index.d.ts.map +0 -1
  289. package/dist/utils/index.js +0 -6
  290. package/dist/utils/index.js.map +0 -1
  291. package/src/__tests__/utils/agents.test.ts +0 -105
  292. package/src/capacity/openai.ts +0 -355
  293. package/src/readiness/AgentReadiness.ts +0 -730
  294. package/src/terminal/index.ts +0 -4
  295. package/src/utils/index.ts +0 -14
@@ -1,7 +1,8 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import { PassThrough, Writable } from "node:stream";
3
3
  import { describe, expect, it, vi } from "vitest";
4
- import type { CodexDurableAgent } from "../../../../index.js";
4
+ import type { CodexDurableAgent } from "../../../../durable/DurableAgent.js";
5
+ import { CodexPrintRunner } from "../../../../harnesses/codex/durable/CodexPrintRunner.js";
5
6
 
6
7
  const SESSION = "22222222-2222-4222-8222-222222222222";
7
8
 
@@ -64,10 +65,7 @@ function events(session = SESSION): string[] {
64
65
  }
65
66
 
66
67
  async function runner(fixture: ReturnType<typeof fakeSpawn>, maxLineBytes?: number) {
67
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
68
- expect(api).toHaveProperty("CodexPrintRunner");
69
- const Runner = api.CodexPrintRunner as new (options: unknown) => any;
70
- return new Runner({
68
+ return new CodexPrintRunner({
71
69
  spawn: fixture.spawn,
72
70
  maxLineBytes,
73
71
  processInspector: {
@@ -262,10 +260,8 @@ describe("CodexPrintRunner", () => {
262
260
  });
263
261
 
264
262
  it("rejects an unverifiable positive PID", async () => {
265
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
266
263
  const fixture = fakeSpawn([]);
267
- const Runner = api.CodexPrintRunner as new (options: unknown) => any;
268
- const instance = new Runner({
264
+ const instance = new CodexPrintRunner({
269
265
  spawn: fixture.spawn,
270
266
  processInspector: { getIdentity: () => null },
271
267
  });
@@ -1,9 +1,8 @@
1
1
  import { describe, expect, it, vi } from "vitest";
2
+ import { PiCliProbe } from "../../../../harnesses/pi/durable/PiCliProbe.js";
2
3
 
3
4
  describe("PiCliProbe", () => {
4
5
  it("validates documented JSON mode and session capabilities", async () => {
5
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
6
- expect(api).toHaveProperty("PiCliProbe");
7
6
  const exec = vi
8
7
  .fn()
9
8
  .mockResolvedValueOnce({ stdout: "pi 0.52.8", stderr: "" })
@@ -11,8 +10,7 @@ describe("PiCliProbe", () => {
11
10
  stdout: "--mode json\n--session-id <uuid>\n--session <path|id>",
12
11
  stderr: "",
13
12
  });
14
- const Probe = api.PiCliProbe as new (options: unknown) => any;
15
- await expect(new Probe({ executable: "fake-pi", exec }).validate()).resolves.toEqual({
13
+ await expect(new PiCliProbe({ executable: "fake-pi", exec }).validate()).resolves.toEqual({
16
14
  executable: "fake-pi",
17
15
  version: "pi 0.52.8",
18
16
  });
@@ -23,17 +21,15 @@ describe("PiCliProbe", () => {
23
21
  });
24
22
 
25
23
  it("rejects unsupported and unavailable CLIs with sanitized errors", async () => {
26
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
27
- const Probe = api.PiCliProbe as new (options: unknown) => any;
28
24
  await expect(
29
- new Probe({
25
+ new PiCliProbe({
30
26
  exec: vi
31
27
  .fn()
32
28
  .mockResolvedValueOnce({ stdout: "", stderr: "" })
33
29
  .mockResolvedValueOnce({ stdout: "--print only", stderr: "" }),
34
30
  }).validate(),
35
31
  ).rejects.toMatchObject({ code: "PI_CLI_UNSUPPORTED" });
36
- const unavailable = new Probe({
32
+ const unavailable = new PiCliProbe({
37
33
  exec: vi.fn().mockRejectedValue(new Error(`bad\0${"x".repeat(1000)}`)),
38
34
  });
39
35
  const error = await unavailable.validate().catch((value: Error & { code: string }) => value);
@@ -43,12 +39,12 @@ describe("PiCliProbe", () => {
43
39
  });
44
40
 
45
41
  it("reports an empty version as unknown", async () => {
46
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
47
- const Probe = api.PiCliProbe as new (options: unknown) => any;
48
42
  const exec = vi
49
43
  .fn()
50
44
  .mockResolvedValueOnce({ stdout: " \n", stderr: "" })
51
45
  .mockResolvedValueOnce({ stdout: "--mode json --session-id --session", stderr: "" });
52
- await expect(new Probe({ exec }).validate()).resolves.toMatchObject({ version: "unknown" });
46
+ await expect(new PiCliProbe({ exec }).validate()).resolves.toMatchObject({
47
+ version: "unknown",
48
+ });
53
49
  });
54
50
  });
@@ -1,4 +1,6 @@
1
1
  import { describe, expect, it, vi } from "vitest";
2
+ import { PiPrintError } from "../../../../durable/DurableAgent.js";
3
+ import { PiPrintAgentService } from "../../../../harnesses/pi/durable/PiPrintAgentService.js";
2
4
  const SESSION = "22222222-2222-4222-8222-222222222222";
3
5
  const base = {
4
6
  id: "id",
@@ -10,13 +12,13 @@ const base = {
10
12
 
11
13
  describe("PiPrintAgentService", () => {
12
14
  it("probes before provider-aware create", async () => {
13
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
14
- expect(api).toHaveProperty("PiPrintAgentService");
15
15
  const probe = { validate: vi.fn() };
16
16
  const repository = { create: vi.fn().mockResolvedValue(base), list: vi.fn() };
17
17
  const runner = { run: vi.fn() };
18
- const Service = api.PiPrintAgentService as new (options: unknown) => any;
19
- await new Service({ repository, probe, runner }).create({ name: "reviewer", cwd: "/project" });
18
+ await new PiPrintAgentService({ repository, probe, runner }).create({
19
+ name: "reviewer",
20
+ cwd: "/project",
21
+ });
20
22
  expect(probe.validate).toHaveBeenCalledOnce();
21
23
  expect(repository.create).toHaveBeenCalledWith({
22
24
  name: "reviewer",
@@ -26,7 +28,6 @@ describe("PiPrintAgentService", () => {
26
28
  });
27
29
 
28
30
  it("records successful first and resumed sends", async () => {
29
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
30
31
  const repository = {
31
32
  list: vi.fn(),
32
33
  resolve: vi.fn().mockResolvedValue(base),
@@ -43,8 +44,7 @@ describe("PiPrintAgentService", () => {
43
44
  return { sessionId: SESSION, result: "answer", messages: ["answer"], exitCode: 0 };
44
45
  }),
45
46
  };
46
- const Service = api.PiPrintAgentService as new (options: unknown) => any;
47
- const service = new Service({ repository, probe: { validate: vi.fn() }, runner });
47
+ const service = new PiPrintAgentService({ repository, probe: { validate: vi.fn() }, runner });
48
48
  await service.send("reviewer", "first");
49
49
  await service.send("reviewer", "later");
50
50
  expect(repository.completeRun).toHaveBeenCalledWith(
@@ -55,8 +55,6 @@ describe("PiPrintAgentService", () => {
55
55
  });
56
56
 
57
57
  it("records mismatches and rejects missing and ambiguous records", async () => {
58
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
59
- const ErrorType = api.PiPrintError as new (message: string, code: string) => Error;
60
58
  const completeRun = vi.fn();
61
59
  const repository = {
62
60
  list: vi.fn(),
@@ -65,12 +63,11 @@ describe("PiPrintAgentService", () => {
65
63
  recordProviderProcess: vi.fn(),
66
64
  completeRun,
67
65
  };
68
- const Service = api.PiPrintAgentService as new (options: unknown) => any;
69
66
  await expect(
70
- new Service({
67
+ new PiPrintAgentService({
71
68
  repository,
72
69
  probe: { validate: vi.fn() },
73
- runner: { run: vi.fn().mockRejectedValue(new ErrorType("bad", "PI_SESSION_MISMATCH")) },
70
+ runner: { run: vi.fn().mockRejectedValue(new PiPrintError("bad", "PI_SESSION_MISMATCH")) },
74
71
  }).send("reviewer", "x"),
75
72
  ).rejects.toMatchObject({ code: "PI_SESSION_MISMATCH" });
76
73
  expect(completeRun).toHaveBeenCalledWith(
@@ -83,7 +80,7 @@ describe("PiPrintAgentService", () => {
83
80
  resolve: vi.fn().mockResolvedValueOnce(null).mockResolvedValueOnce([base, base]),
84
81
  acquireRun: vi.fn(),
85
82
  };
86
- const early = new Service({
83
+ const early = new PiPrintAgentService({
87
84
  repository: earlyRepository,
88
85
  probe: { validate: vi.fn() },
89
86
  runner: { run: vi.fn() },
@@ -95,8 +92,6 @@ describe("PiPrintAgentService", () => {
95
92
  });
96
93
 
97
94
  it("rejects a non-Pi target without acquiring or mutating it", async () => {
98
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
99
- const Service = api.PiPrintAgentService as new (options: unknown) => any;
100
95
  const repository = {
101
96
  resolve: vi.fn().mockResolvedValue({ ...base, provider: "claude" }),
102
97
  acquireRun: vi.fn(),
@@ -105,18 +100,17 @@ describe("PiPrintAgentService", () => {
105
100
  };
106
101
 
107
102
  await expect(
108
- new Service({ repository, probe: { validate: vi.fn() }, runner: { run: vi.fn() } }).send(
109
- "reviewer",
110
- "x",
111
- ),
103
+ new PiPrintAgentService({
104
+ repository,
105
+ probe: { validate: vi.fn() },
106
+ runner: { run: vi.fn() },
107
+ }).send("reviewer", "x"),
112
108
  ).rejects.toMatchObject({ code: "PI_UNSUPPORTED" });
113
109
  expect(repository.acquireRun).not.toHaveBeenCalled();
114
110
  expect(repository.completeRun).not.toHaveBeenCalled();
115
111
  });
116
112
 
117
113
  it("does not turn a successful completion write failure into a second completion", async () => {
118
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
119
- const Service = api.PiPrintAgentService as new (options: unknown) => any;
120
114
  const completionFailure = new Error("completion failed");
121
115
  const repository = {
122
116
  resolve: vi.fn().mockResolvedValue(base),
@@ -134,7 +128,10 @@ describe("PiPrintAgentService", () => {
134
128
  };
135
129
 
136
130
  await expect(
137
- new Service({ repository, probe: { validate: vi.fn() }, runner }).send("reviewer", "x"),
131
+ new PiPrintAgentService({ repository, probe: { validate: vi.fn() }, runner }).send(
132
+ "reviewer",
133
+ "x",
134
+ ),
138
135
  ).rejects.toBe(completionFailure);
139
136
  expect(repository.completeRun).toHaveBeenCalledOnce();
140
137
  });
@@ -1,7 +1,8 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import { PassThrough, Writable } from "node:stream";
3
3
  import { describe, expect, it, vi } from "vitest";
4
- import type { PiDurableAgent } from "../../../../index.js";
4
+ import type { PiDurableAgent } from "../../../../durable/DurableAgent.js";
5
+ import { PiPrintRunner } from "../../../../harnesses/pi/durable/PiPrintRunner.js";
5
6
 
6
7
  const SESSION = "22222222-2222-4222-8222-222222222222";
7
8
  function agent(sessionHealth: PiDurableAgent["sessionHealth"] = "uninitialized"): PiDurableAgent {
@@ -63,10 +64,7 @@ function events(session = SESSION): string[] {
63
64
  ];
64
65
  }
65
66
  async function runner(fixture: ReturnType<typeof fakeSpawn>, maxLineBytes?: number) {
66
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
67
- expect(api).toHaveProperty("PiPrintRunner");
68
- const Runner = api.PiPrintRunner as new (options: unknown) => any;
69
- return new Runner({
67
+ return new PiPrintRunner({
70
68
  spawn: fixture.spawn,
71
69
  maxLineBytes,
72
70
  processInspector: { getIdentity: () => ({ pid: 4242, startedAt: "start" }) },
@@ -154,10 +152,11 @@ describe("PiPrintRunner", () => {
154
152
  (await runner(fakeSpawn(events(), 1))).run({ agent: agent(), prompt: "x", onSpawn: vi.fn() }),
155
153
  ).rejects.toMatchObject({ code: "PI_PROCESS" });
156
154
  const fixture = fakeSpawn([]);
157
- const api = (await import("../../../../index.js")) as Record<string, unknown>;
158
- const Runner = api.PiPrintRunner as new (options: unknown) => any;
159
155
  await expect(
160
- new Runner({ spawn: fixture.spawn, processInspector: { getIdentity: () => null } }).run({
156
+ new PiPrintRunner({
157
+ spawn: fixture.spawn,
158
+ processInspector: { getIdentity: () => null },
159
+ }).run({
161
160
  agent: agent(),
162
161
  prompt: "x",
163
162
  onSpawn: vi.fn(),
@@ -1,21 +1,23 @@
1
1
  import path from "node:path";
2
2
  import { describe, expect, it, vi } from "vitest";
3
3
  import {
4
- AGENTS,
5
4
  getAgentReadinessReport,
6
5
  getAgentReadinessReports,
7
6
  type AgentReadinessOptions,
8
7
  type ReadinessAgentType,
9
- } from "../../index.js";
8
+ } from "../../../harnesses/readiness/AgentReadiness.js";
9
+ import { HARNESS_RUNTIME_PROFILES } from "../../../harnesses/runtimeProfiles.js";
10
10
 
11
11
  type Files = Record<string, string>;
12
12
 
13
13
  const builtInSkillNames = ["agent-management", "memory", "verify"];
14
- const skillRoots: Record<ReadinessAgentType, string> = {
14
+ const skillRoots: Record<string, string> = {
15
15
  claude: ".claude/skills",
16
16
  codex: ".codex/skills",
17
17
  copilot: ".copilot/skills",
18
+ gemini_cli: ".gemini/skills",
18
19
  grok_cli: ".grok/skills",
20
+ antigravity_cli: ".gemini/config/skills",
19
21
  opencode: ".config/opencode/skill",
20
22
  pi: ".pi/agent/skills",
21
23
  };
@@ -56,7 +58,17 @@ function fixture(overrides: Partial<AgentReadinessOptions> = {}) {
56
58
  litellm: { key: "litellm-secret", env: { LITELLM_BASE_URL: "https://litellm.example.test" } },
57
59
  }),
58
60
  };
59
- for (const directory of [".claude", ".codex", ".copilot", ".grok", ".config/opencode", ".pi"]) {
61
+ for (const directory of [
62
+ ".claude",
63
+ ".codex",
64
+ ".copilot",
65
+ ".gemini",
66
+ ".grok",
67
+ ".kiro",
68
+ ".gemini/antigravity-cli",
69
+ ".config/opencode",
70
+ ".pi",
71
+ ]) {
60
72
  files[path.join(homeDir, directory)] = "<dir>";
61
73
  }
62
74
  for (const root of Object.values(skillRoots)) {
@@ -64,7 +76,9 @@ function fixture(overrides: Partial<AgentReadinessOptions> = {}) {
64
76
  files[path.join(homeDir, root, skill, "SKILL.md")] = "# skill";
65
77
  }
66
78
  }
67
- const executablePaths = Object.values(AGENTS).map((agent) => path.join("/bin", agent.command));
79
+ const executablePaths = Object.values(HARNESS_RUNTIME_PROFILES).map((agent) =>
80
+ path.join("/bin", agent.command),
81
+ );
68
82
  const options: AgentReadinessOptions = {
69
83
  homeDir,
70
84
  path: "/bin",
@@ -103,20 +117,30 @@ describe("agent readiness", () => {
103
117
  expect(Object.keys(reports)).toEqual([
104
118
  "claude",
105
119
  "codex",
106
- "copilot",
120
+ "gemini_cli",
107
121
  "grok_cli",
122
+ "kiro",
123
+ "antigravity_cli",
108
124
  "opencode",
125
+ "copilot",
109
126
  "pi",
110
127
  ]);
111
- expect(reports).not.toHaveProperty("gemini_cli");
112
128
  for (const [agent, report] of Object.entries(reports) as Array<
113
129
  [ReadinessAgentType, (typeof reports)[ReadinessAgentType]]
114
130
  >) {
115
131
  expect(report.type).toBe(agent);
116
132
  expect(report.executable.status).toBe("pass");
117
133
  expect(report.globalConfig.status).toBe("pass");
118
- expect(report.builtInSkills).toMatchObject({ status: "info", present: 3, required: 3 });
134
+ expect(report.builtInSkills.status).toBe("info");
119
135
  }
136
+ expect(reports.gemini_cli.builtInSkills).toMatchObject({ present: 3, required: 3 });
137
+ expect(reports.antigravity_cli.builtInSkills).toMatchObject({ present: 3, required: 3 });
138
+ expect(reports.kiro.builtInSkills).toMatchObject({
139
+ path: null,
140
+ present: 0,
141
+ required: 3,
142
+ missing: builtInSkillNames,
143
+ });
120
144
  expect(reports.codex.integration).toMatchObject({
121
145
  label: "ai-devkit hook",
122
146
  installed: true,
@@ -133,13 +157,16 @@ describe("agent readiness", () => {
133
157
  status: "pass",
134
158
  });
135
159
  expect(reports.copilot.integration).toBeUndefined();
160
+ expect(reports.gemini_cli.integration).toBeUndefined();
136
161
  expect(reports.grok_cli.integration).toBeUndefined();
162
+ expect(reports.kiro.integration).toBeUndefined();
163
+ expect(reports.antigravity_cli.integration).toBeUndefined();
137
164
  expect(reports.opencode.integration).toBeUndefined();
138
165
  });
139
166
 
140
167
  it("resolves agent executables from PATH directories containing spaces", async () => {
141
168
  const spacedBin = "/Applications/Some App.app/Contents/Resources";
142
- const codexPath = path.join(spacedBin, AGENTS.codex.command);
169
+ const codexPath = path.join(spacedBin, HARNESS_RUNTIME_PROFILES.codex.command);
143
170
  const { options } = fixture({
144
171
  path: [spacedBin, "/usr/local/bin"].join(path.delimiter),
145
172
  access: async (target) => {
@@ -0,0 +1,110 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import {
6
+ HARNESS_RUNTIME_PROFILES,
7
+ runtimeAgentMatchesHarness,
8
+ } from "../../harnesses/runtimeProfiles.js";
9
+
10
+ describe("harness runtime profiles", () => {
11
+ it("keeps launch and runtime identity metadata together", () => {
12
+ expect(HARNESS_RUNTIME_PROFILES.antigravity_cli).toMatchObject({
13
+ command: "agy",
14
+ runtimeKind: "agy",
15
+ discoveryAliases: ["agy", "antigravity", "antigravity_cli"],
16
+ });
17
+ expect(HARNESS_RUNTIME_PROFILES.antigravity_cli.matches("/usr/local/bin/agy")).toBe(true);
18
+ });
19
+
20
+ it("recognizes agent commands without matching similar argument text", () => {
21
+ expect(HARNESS_RUNTIME_PROFILES.copilot.matches("/opt/copilot-cli/1.0/copilot")).toBe(true);
22
+ expect(HARNESS_RUNTIME_PROFILES.copilot.matches("node /repo/copilot-cli/script.js")).toBe(
23
+ false,
24
+ );
25
+ expect(HARNESS_RUNTIME_PROFILES.grok_cli.matches("/Users/dev/.grok/bin/grok --approve")).toBe(
26
+ true,
27
+ );
28
+ expect(HARNESS_RUNTIME_PROFILES.grok_cli.matches("node /repo/grok-cli/script.js")).toBe(false);
29
+ expect(
30
+ HARNESS_RUNTIME_PROFILES.gemini_cli.matches("node --no-warnings /usr/local/bin/gemini"),
31
+ ).toBe(true);
32
+ });
33
+
34
+ it("matches runtime discovery names through the owning harness profile", () => {
35
+ expect(runtimeAgentMatchesHarness("kiro-cli", "kiro")).toBe(true);
36
+ expect(runtimeAgentMatchesHarness("gemini", "gemini_cli")).toBe(true);
37
+ expect(runtimeAgentMatchesHarness("codex", "claude")).toBe(false);
38
+ });
39
+ });
40
+
41
+ describe("harness matchers with executables under paths containing spaces", () => {
42
+ let root: string;
43
+
44
+ function install(relativePath: string): string {
45
+ const fullPath = path.join(root, relativePath);
46
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
47
+ fs.writeFileSync(fullPath, "");
48
+ return fullPath;
49
+ }
50
+
51
+ beforeEach(() => {
52
+ root = fs.mkdtempSync(path.join(os.tmpdir(), "runtime-profiles-spaces-"));
53
+ });
54
+
55
+ afterEach(() => {
56
+ fs.rmSync(root, { recursive: true, force: true });
57
+ });
58
+
59
+ it("recognizes argv[0] under a spaced directory", () => {
60
+ const codex = install("Applications/Some App.app/Contents/Resources/codex");
61
+ const claude = install("Users/dev/My Tools/bin/claude");
62
+
63
+ expect(HARNESS_RUNTIME_PROFILES.codex.matches(`${codex} --sandbox workspace-write`)).toBe(true);
64
+ expect(HARNESS_RUNTIME_PROFILES.codex.matches(codex)).toBe(true);
65
+ expect(HARNESS_RUNTIME_PROFILES.claude.matches(`${claude} --continue`)).toBe(true);
66
+ expect(HARNESS_RUNTIME_PROFILES.claude.matches(`${codex} exec --cd /repo`)).toBe(false);
67
+ });
68
+
69
+ it("recognizes argv[0] by distribution name under a spaced directory", () => {
70
+ const copilot = install("opt/Home Brew/Caskroom/copilot-cli/1.0.60/copilot");
71
+
72
+ expect(HARNESS_RUNTIME_PROFILES.copilot.matches(`${copilot} --allow-all-tools`)).toBe(true);
73
+ });
74
+
75
+ it("does not treat arguments containing spaces as the executable", () => {
76
+ const vim = install("usr/bin/vim");
77
+ const codex = install("Applications/Some App.app/Contents/Resources/codex");
78
+
79
+ expect(HARNESS_RUNTIME_PROFILES.claude.matches(`${vim} My Notes/claude`)).toBe(false);
80
+ expect(
81
+ HARNESS_RUNTIME_PROFILES.claude.matches(`${codex} exec review the Other Dir/claude`),
82
+ ).toBe(false);
83
+ expect(HARNESS_RUNTIME_PROFILES.copilot.matches(`${vim} Some Dir/copilot-cli/notes.md`)).toBe(
84
+ false,
85
+ );
86
+ expect(HARNESS_RUNTIME_PROFILES.claude.matches("/usr/bin/vim My Notes/claude")).toBe(false);
87
+ });
88
+
89
+ it("recognizes spaced argv[0] in script-aware matchers", () => {
90
+ const pi = install("Users/dev/Node Tools/bin/pi");
91
+ const kiro = install("Applications/Kiro CLI.app/Contents/MacOS/kiro-cli");
92
+ const node = install("Applications/Dev Tools/node/bin/node");
93
+
94
+ expect(HARNESS_RUNTIME_PROFILES.pi.matches(`${pi} --model x`)).toBe(true);
95
+ expect(HARNESS_RUNTIME_PROFILES.kiro.matches(`${kiro} chat`)).toBe(true);
96
+ expect(
97
+ HARNESS_RUNTIME_PROFILES.gemini_cli.matches(`${node} /Users/dev/.npm/bin/gemini --yolo`),
98
+ ).toBe(true);
99
+ expect(HARNESS_RUNTIME_PROFILES.pi.matches(`${node} /opt/pi-tools/script.js`)).toBe(false);
100
+ });
101
+
102
+ it("does not match agent words inside an executable directory", () => {
103
+ const node = install("opt/Dev pi gemini/bin/node");
104
+
105
+ expect(HARNESS_RUNTIME_PROFILES.pi.matches(`${node} /repo/script.js`)).toBe(false);
106
+ expect(HARNESS_RUNTIME_PROFILES.gemini_cli.matches(`${node} /repo/script.js`)).toBe(false);
107
+ expect(HARNESS_RUNTIME_PROFILES.gemini_cli.matches(`${node} /repo/bin/gemini`)).toBe(true);
108
+ expect(HARNESS_RUNTIME_PROFILES.pi.matches(`${node} --title pi`)).toBe(true);
109
+ });
110
+ });
@@ -1,18 +1,9 @@
1
1
  import { describe, expect, it } from "vitest";
2
+ import { DurableAgentBusyError } from "../../durable/DurableAgent.js";
2
3
 
3
- describe("durable-agent public domain", () => {
4
- it("exports a classified busy error without exposing prompt data", async () => {
5
- const api = (await import("../../index.js")) as Record<string, unknown>;
6
-
7
- expect(api).toHaveProperty("DurableAgentBusyError");
8
- const ErrorType = api.DurableAgentBusyError as new (
9
- agentId: string,
10
- name: string,
11
- ) => Error & {
12
- code: string;
13
- agentId: string;
14
- };
15
- const error = new ErrorType("agent-id", "reviewer");
4
+ describe("durable-agent errors", () => {
5
+ it("classifies a busy error without exposing prompt data", () => {
6
+ const error = new DurableAgentBusyError("agent-id", "reviewer");
16
7
 
17
8
  expect(error).toMatchObject({
18
9
  name: "DurableAgentBusyError",
@@ -2,6 +2,7 @@ import fs from "fs";
2
2
  import os from "os";
3
3
  import path from "path";
4
4
  import { afterEach, describe, expect, it } from "vitest";
5
+ import { DurableAgentRepository } from "../../durable/DurableAgentRepository.js";
5
6
 
6
7
  const tempDirs: string[] = [];
7
8
 
@@ -9,12 +10,6 @@ afterEach(() => {
9
10
  for (const dir of tempDirs.splice(0)) fs.rmSync(dir, { recursive: true, force: true });
10
11
  });
11
12
 
12
- async function loadStore(): Promise<any> {
13
- const api = (await import("../../index.js")) as Record<string, unknown>;
14
- expect(api).toHaveProperty("DurableAgentRepository");
15
- return api.DurableAgentRepository;
16
- }
17
-
18
13
  function fixture(): { root: string; cwd: string; dbPath: string } {
19
14
  const root = fs.mkdtempSync(path.join(os.tmpdir(), "durable-agent-store-"));
20
15
  tempDirs.push(root);
@@ -25,7 +20,6 @@ function fixture(): { root: string; cwd: string; dbPath: string } {
25
20
 
26
21
  describe("DurableAgentRepository create/list/resolve", () => {
27
22
  it("creates distinct durable identities with a canonical cwd and lists them", async () => {
28
- const DurableAgentRepository = await loadStore();
29
23
  const { cwd, dbPath } = fixture();
30
24
  const repository = new DurableAgentRepository({
31
25
  dbPath,
@@ -51,7 +45,6 @@ describe("DurableAgentRepository create/list/resolve", () => {
51
45
  });
52
46
 
53
47
  it("resolves exact ids and names and rejects duplicate names", async () => {
54
- const DurableAgentRepository = await loadStore();
55
48
  const { cwd, dbPath } = fixture();
56
49
  const repository = new DurableAgentRepository({ dbPath });
57
50
  const agent = await repository.create({ name: "Reviewer", cwd });
@@ -65,7 +58,6 @@ describe("DurableAgentRepository create/list/resolve", () => {
65
58
  });
66
59
 
67
60
  it("rejects a missing cwd", async () => {
68
- const DurableAgentRepository = await loadStore();
69
61
  const { root, dbPath } = fixture();
70
62
  const repository = new DurableAgentRepository({ dbPath });
71
63
 
@@ -77,7 +69,6 @@ describe("DurableAgentRepository create/list/resolve", () => {
77
69
 
78
70
  describe("DurableAgentRepository run ownership", () => {
79
71
  it("fails fast when another exact owner is live and completes only for its token", async () => {
80
- const DurableAgentRepository = await loadStore();
81
72
  const { cwd, dbPath } = fixture();
82
73
  const live = new Map<number, string>([[process.pid, "owner-start"]]);
83
74
  const processInspector = {
@@ -112,7 +103,6 @@ describe("DurableAgentRepository run ownership", () => {
112
103
  });
113
104
 
114
105
  it("retains busy for a live provider then recovers a dead run without signaling it", async () => {
115
- const DurableAgentRepository = await loadStore();
116
106
  const { cwd, dbPath } = fixture();
117
107
  const live = new Map<number, string>([
118
108
  [process.pid, "owner-start"],
@@ -151,7 +141,6 @@ describe("DurableAgentRepository run ownership", () => {
151
141
  });
152
142
 
153
143
  it("reconciles an interrupted run to degraded during list", async () => {
154
- const DurableAgentRepository = await loadStore();
155
144
  const { cwd, dbPath } = fixture();
156
145
  const live = new Map<number, string>([[process.pid, "owner-start"]]);
157
146
  const repository = new DurableAgentRepository({
@@ -179,7 +168,6 @@ describe("DurableAgentRepository run ownership", () => {
179
168
  });
180
169
 
181
170
  it("rejects send acquisition when the bound cwd is replaced by a symlink", async () => {
182
- const DurableAgentRepository = await loadStore();
183
171
  const { root, cwd, dbPath } = fixture();
184
172
  const repository = new DurableAgentRepository({ dbPath });
185
173
  const agent = await repository.create({ name: "bound", cwd });
@@ -15,7 +15,7 @@ import {
15
15
  } from "../../runtime/ManagedAgentRuntime.js";
16
16
  import type { AgentInfo } from "../../adapters/AgentAdapter.js";
17
17
  import type { AgentRegistry, RegistryEntry } from "../../utils/AgentRegistry.js";
18
- import type { TmuxManager } from "../../terminal/TmuxManager.js";
18
+ import type { TmuxManager } from "../../runtime/tmux/TmuxManager.js";
19
19
  import type { InteractiveAgentRuntime } from "../../runtime/types.js";
20
20
 
21
21
  function makeAgent(overrides: Partial<AgentInfo> = {}): AgentInfo {
@@ -1,6 +1,6 @@
1
1
  import { execFile } from "child_process";
2
2
  import type { MockedFunction } from "vitest";
3
- import { TmuxManager } from "../../terminal/TmuxManager.js";
3
+ import { TmuxManager } from "../../runtime/tmux/TmuxManager.js";
4
4
 
5
5
  vi.mock("child_process", () => ({
6
6
  execFile: vi.fn(),
@@ -1,14 +1,25 @@
1
1
  import { constants } from "node:fs";
2
2
  import { access as fsAccess } from "node:fs/promises";
3
3
  import path from "node:path";
4
- import { codexUnavailableReport, probeCodexCapacity } from "./codex.js";
5
- import { probeClaudeCapacity, type ClaudeCapacityOptions } from "./claude.js";
6
- import { probeOpenAiCapacity } from "./openai.js";
7
- import { probeZaiCapacity } from "./zai.js";
4
+ import { codexUnavailableReport, probeCodexCapacity } from "./sources/codex.js";
5
+ import { probeClaudeCapacity, type ClaudeCapacityOptions } from "./sources/claude.js";
6
+ import {
7
+ probeOpenAiCapacity,
8
+ probePiAnthropicCapacity,
9
+ probeZaiCapacity,
10
+ type PiAnthropicCapacityOptions,
11
+ type PiOpenAiCapacityOptions,
12
+ type PiZaiCapacityOptions,
13
+ } from "./sources/pi.js";
8
14
  import type { CapacityReport } from "./types.js";
9
15
 
10
16
  export type { CapacityReport, CapacityWindow } from "./types.js";
11
- export type { ClaudeCapacityOptions } from "./claude.js";
17
+ export type { ClaudeCapacityOptions } from "./sources/claude.js";
18
+ export type { PiAnthropicCapacityOptions as AnthropicCapacityOptions } from "./sources/pi.js";
19
+ export type {
20
+ PiOpenAiCapacityOptions as OpenAiCapacityOptions,
21
+ PiZaiCapacityOptions as ZaiCapacityOptions,
22
+ } from "./sources/pi.js";
12
23
 
13
24
  export type CapacityProbeOptions = {
14
25
  now?: () => Date;
@@ -17,22 +28,6 @@ export type CapacityProbeOptions = {
17
28
  probe?: typeof probeCodexCapacity;
18
29
  };
19
30
 
20
- export type ZaiCapacityOptions = {
21
- now?: () => Date;
22
- env?: NodeJS.ProcessEnv;
23
- readFile?: (path: string, encoding: BufferEncoding) => Promise<string>;
24
- fetch?: typeof globalThis.fetch;
25
- timeoutMs?: number;
26
- };
27
-
28
- export type OpenAiCapacityOptions = {
29
- now?: () => Date;
30
- env?: NodeJS.ProcessEnv;
31
- readFile?: (path: string, encoding: BufferEncoding) => Promise<string>;
32
- fetch?: typeof globalThis.fetch;
33
- timeoutMs?: number;
34
- };
35
-
36
31
  async function canAccess(target: string, mode: number): Promise<boolean> {
37
32
  try {
38
33
  await fsAccess(target, mode);
@@ -78,7 +73,7 @@ export async function getCodexCapacityReport(
78
73
  }
79
74
 
80
75
  export async function getZaiCapacityReport(
81
- options: ZaiCapacityOptions = {},
76
+ options: PiZaiCapacityOptions = {},
82
77
  ): Promise<CapacityReport> {
83
78
  const { now, ...probeOptions } = options;
84
79
  return probeZaiCapacity({
@@ -88,7 +83,7 @@ export async function getZaiCapacityReport(
88
83
  }
89
84
 
90
85
  export async function getOpenAiCapacityReport(
91
- options: OpenAiCapacityOptions = {},
86
+ options: PiOpenAiCapacityOptions = {},
92
87
  ): Promise<CapacityReport> {
93
88
  const { now, ...probeOptions } = options;
94
89
  return probeOpenAiCapacity({
@@ -107,3 +102,14 @@ export async function getClaudeCapacityReport(
107
102
  now,
108
103
  });
109
104
  }
105
+
106
+ export async function getAnthropicCapacityReport(
107
+ options: PiAnthropicCapacityOptions = {},
108
+ ): Promise<CapacityReport> {
109
+ const { now, ...probeOptions } = options;
110
+ return probePiAnthropicCapacity({
111
+ ...probeOptions,
112
+ checkedAt: (now?.() ?? new Date()).toISOString(),
113
+ now,
114
+ });
115
+ }