@ai-devkit/agent-manager 0.37.0 → 0.39.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 (357) 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/devin/DevinAdapter.test.js +597 -0
  31. package/dist/__tests__/harnesses/devin/DevinAdapter.test.js.map +1 -0
  32. package/dist/__tests__/harnesses/devin/DevinAgentMapper.test.js +91 -0
  33. package/dist/__tests__/harnesses/devin/DevinAgentMapper.test.js.map +1 -0
  34. package/dist/__tests__/harnesses/devin/DevinSessionLocator.test.js +192 -0
  35. package/dist/__tests__/harnesses/devin/DevinSessionLocator.test.js.map +1 -0
  36. package/dist/__tests__/harnesses/devin/DevinSessionParser.test.js +407 -0
  37. package/dist/__tests__/harnesses/devin/DevinSessionParser.test.js.map +1 -0
  38. package/dist/__tests__/harnesses/devin/fixtures.js +95 -0
  39. package/dist/__tests__/harnesses/devin/fixtures.js.map +1 -0
  40. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js +5 -11
  41. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js.map +1 -1
  42. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js +9 -19
  43. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js.map +1 -1
  44. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js +3 -7
  45. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js.map +1 -1
  46. package/dist/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.js +95 -11
  47. package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js.map +1 -0
  48. package/dist/__tests__/harnesses/runtimeProfiles.test.js +89 -0
  49. package/dist/__tests__/harnesses/runtimeProfiles.test.js.map +1 -0
  50. package/dist/__tests__/print/DurableAgent.test.js +4 -6
  51. package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
  52. package/dist/__tests__/print/DurableAgentRepository.test.js +1 -12
  53. package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
  54. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
  55. package/dist/__tests__/terminal/GhosttyBackend.test.js +334 -0
  56. package/dist/__tests__/terminal/GhosttyBackend.test.js.map +1 -0
  57. package/dist/__tests__/terminal/TmuxManager.test.js +1 -1
  58. package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
  59. package/dist/adapters/AgentAdapter.d.ts +1 -1
  60. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  61. package/dist/adapters/AgentAdapter.js +2 -1
  62. package/dist/adapters/AgentAdapter.js.map +1 -1
  63. package/dist/capacity/index.d.ts +9 -19
  64. package/dist/capacity/index.d.ts.map +1 -1
  65. package/dist/capacity/index.js +11 -4
  66. package/dist/capacity/index.js.map +1 -1
  67. package/dist/capacity/providers/anthropic.d.ts +9 -0
  68. package/dist/capacity/providers/anthropic.d.ts.map +1 -0
  69. package/dist/capacity/{claude.js → providers/anthropic.js} +10 -128
  70. package/dist/capacity/providers/anthropic.js.map +1 -0
  71. package/dist/capacity/providers/openai-platform.d.ts +14 -0
  72. package/dist/capacity/providers/openai-platform.d.ts.map +1 -0
  73. package/dist/capacity/providers/openai-platform.js +120 -0
  74. package/dist/capacity/providers/openai-platform.js.map +1 -0
  75. package/dist/capacity/providers/openai-subscription.d.ts +20 -0
  76. package/dist/capacity/providers/openai-subscription.d.ts.map +1 -0
  77. package/dist/capacity/providers/openai-subscription.js +129 -0
  78. package/dist/capacity/providers/openai-subscription.js.map +1 -0
  79. package/dist/capacity/providers/zai.d.ts +8 -0
  80. package/dist/capacity/providers/zai.d.ts.map +1 -0
  81. package/dist/capacity/{zai.js → providers/zai.js} +17 -62
  82. package/dist/capacity/providers/zai.js.map +1 -0
  83. package/dist/capacity/sources/claude.d.ts +9 -0
  84. package/dist/capacity/sources/claude.d.ts.map +1 -0
  85. package/dist/capacity/sources/claude.js +17 -0
  86. package/dist/capacity/sources/claude.js.map +1 -0
  87. package/dist/capacity/{codex.d.ts → sources/codex.d.ts} +5 -9
  88. package/dist/capacity/sources/codex.d.ts.map +1 -0
  89. package/dist/capacity/{codex.js → sources/codex.js} +31 -84
  90. package/dist/capacity/sources/codex.js.map +1 -0
  91. package/dist/capacity/sources/pi.d.ts +30 -0
  92. package/dist/capacity/sources/pi.d.ts.map +1 -0
  93. package/dist/capacity/sources/pi.js +81 -0
  94. package/dist/capacity/sources/pi.js.map +1 -0
  95. package/dist/capacity/types.d.ts +2 -0
  96. package/dist/capacity/types.d.ts.map +1 -1
  97. package/dist/capacity/types.js +1 -1
  98. package/dist/capacity/types.js.map +1 -1
  99. package/dist/harnesses/claude/credentials.d.ts +10 -0
  100. package/dist/harnesses/claude/credentials.d.ts.map +1 -0
  101. package/dist/harnesses/claude/credentials.js +112 -0
  102. package/dist/harnesses/claude/credentials.js.map +1 -0
  103. package/dist/harnesses/claude/readiness.d.ts +3 -0
  104. package/dist/harnesses/claude/readiness.d.ts.map +1 -0
  105. package/dist/harnesses/claude/readiness.js +63 -0
  106. package/dist/harnesses/claude/readiness.js.map +1 -0
  107. package/dist/harnesses/codex/credentials.d.ts +15 -0
  108. package/dist/harnesses/codex/credentials.d.ts.map +1 -0
  109. package/dist/harnesses/codex/credentials.js +58 -0
  110. package/dist/harnesses/codex/credentials.js.map +1 -0
  111. package/dist/harnesses/codex/readiness.d.ts +3 -0
  112. package/dist/harnesses/codex/readiness.d.ts.map +1 -0
  113. package/dist/harnesses/codex/readiness.js +60 -0
  114. package/dist/harnesses/codex/readiness.js.map +1 -0
  115. package/dist/harnesses/copilot/readiness.d.ts +3 -0
  116. package/dist/harnesses/copilot/readiness.d.ts.map +1 -0
  117. package/dist/harnesses/copilot/readiness.js +39 -0
  118. package/dist/harnesses/copilot/readiness.js.map +1 -0
  119. package/dist/harnesses/devin/DevinAdapter.d.ts +39 -0
  120. package/dist/harnesses/devin/DevinAdapter.d.ts.map +1 -0
  121. package/dist/harnesses/devin/DevinAdapter.js +177 -0
  122. package/dist/harnesses/devin/DevinAdapter.js.map +1 -0
  123. package/dist/harnesses/devin/DevinAgentMapper.d.ts +11 -0
  124. package/dist/harnesses/devin/DevinAgentMapper.d.ts.map +1 -0
  125. package/dist/harnesses/devin/DevinAgentMapper.js +35 -0
  126. package/dist/harnesses/devin/DevinAgentMapper.js.map +1 -0
  127. package/dist/harnesses/devin/DevinSessionLocator.d.ts +46 -0
  128. package/dist/harnesses/devin/DevinSessionLocator.d.ts.map +1 -0
  129. package/dist/harnesses/devin/DevinSessionLocator.js +176 -0
  130. package/dist/harnesses/devin/DevinSessionLocator.js.map +1 -0
  131. package/dist/harnesses/devin/DevinSessionParser.d.ts +29 -0
  132. package/dist/harnesses/devin/DevinSessionParser.d.ts.map +1 -0
  133. package/dist/harnesses/devin/DevinSessionParser.js +166 -0
  134. package/dist/harnesses/devin/DevinSessionParser.js.map +1 -0
  135. package/dist/harnesses/devin/readiness.d.ts +3 -0
  136. package/dist/harnesses/devin/readiness.d.ts.map +1 -0
  137. package/dist/harnesses/devin/readiness.js +39 -0
  138. package/dist/harnesses/devin/readiness.js.map +1 -0
  139. package/dist/harnesses/index.d.ts.map +1 -1
  140. package/dist/harnesses/index.js +3 -1
  141. package/dist/harnesses/index.js.map +1 -1
  142. package/dist/harnesses/opencode/readiness.d.ts +3 -0
  143. package/dist/harnesses/opencode/readiness.d.ts.map +1 -0
  144. package/dist/harnesses/opencode/readiness.js +50 -0
  145. package/dist/harnesses/opencode/readiness.js.map +1 -0
  146. package/dist/harnesses/pi/credentials.d.ts +22 -0
  147. package/dist/harnesses/pi/credentials.d.ts.map +1 -0
  148. package/dist/harnesses/pi/credentials.js +98 -0
  149. package/dist/harnesses/pi/credentials.js.map +1 -0
  150. package/dist/harnesses/pi/readiness.d.ts +3 -0
  151. package/dist/harnesses/pi/readiness.d.ts.map +1 -0
  152. package/dist/harnesses/pi/readiness.js +96 -0
  153. package/dist/harnesses/pi/readiness.js.map +1 -0
  154. package/dist/harnesses/readiness/AgentReadiness.d.ts +6 -0
  155. package/dist/harnesses/readiness/AgentReadiness.d.ts.map +1 -0
  156. package/dist/harnesses/readiness/AgentReadiness.js +70 -0
  157. package/dist/harnesses/readiness/AgentReadiness.js.map +1 -0
  158. package/dist/harnesses/readiness/checks.d.ts +31 -0
  159. package/dist/harnesses/readiness/checks.d.ts.map +1 -0
  160. package/dist/harnesses/readiness/checks.js +270 -0
  161. package/dist/harnesses/readiness/checks.js.map +1 -0
  162. package/dist/{readiness/AgentReadiness.d.ts → harnesses/readiness/types.d.ts} +19 -10
  163. package/dist/harnesses/readiness/types.d.ts.map +1 -0
  164. package/dist/harnesses/readiness/types.js +4 -0
  165. package/dist/harnesses/readiness/types.js.map +1 -0
  166. package/dist/harnesses/runtimeProfiles.d.ts +11 -0
  167. package/dist/harnesses/runtimeProfiles.d.ts.map +1 -0
  168. package/dist/harnesses/runtimeProfiles.js +100 -0
  169. package/dist/harnesses/runtimeProfiles.js.map +1 -0
  170. package/dist/index.d.ts +16 -42
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +9 -23
  173. package/dist/index.js.map +1 -1
  174. package/dist/runtime/ManagedAgentRuntime.d.ts +3 -3
  175. package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -1
  176. package/dist/runtime/ManagedAgentRuntime.js +6 -20
  177. package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
  178. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -1
  179. package/dist/runtime/herdr/HerdrAgentDiscovery.js +2 -43
  180. package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
  181. package/dist/runtime/tmux/PidPolling.d.ts +1 -1
  182. package/dist/runtime/tmux/PidPolling.d.ts.map +1 -1
  183. package/dist/runtime/tmux/PidPolling.js.map +1 -1
  184. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +1 -1
  185. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -1
  186. package/dist/runtime/tmux/TmuxAgentRuntime.js +1 -1
  187. package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -1
  188. package/dist/runtime/tmux/TmuxManager.d.ts +12 -0
  189. package/dist/runtime/tmux/TmuxManager.d.ts.map +1 -0
  190. package/dist/{terminal → runtime/tmux}/TmuxManager.js +9 -28
  191. package/dist/runtime/tmux/TmuxManager.js.map +1 -0
  192. package/dist/runtime/types.d.ts +1 -1
  193. package/dist/runtime/types.d.ts.map +1 -1
  194. package/dist/runtime/types.js.map +1 -1
  195. package/dist/terminal/TerminalFocusManager.d.ts +4 -32
  196. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  197. package/dist/terminal/TerminalFocusManager.js +17 -267
  198. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  199. package/dist/terminal/TtyWriter.d.ts +1 -44
  200. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  201. package/dist/terminal/TtyWriter.js +12 -347
  202. package/dist/terminal/TtyWriter.js.map +1 -1
  203. package/dist/terminal/backends/ghostty.d.ts +3 -0
  204. package/dist/terminal/backends/ghostty.d.ts.map +1 -0
  205. package/dist/terminal/backends/ghostty.js +161 -0
  206. package/dist/terminal/backends/ghostty.js.map +1 -0
  207. package/dist/terminal/backends/index.d.ts +5 -0
  208. package/dist/terminal/backends/index.d.ts.map +1 -0
  209. package/dist/terminal/backends/index.js +21 -0
  210. package/dist/terminal/backends/index.js.map +1 -0
  211. package/dist/terminal/backends/iterm2.d.ts +3 -0
  212. package/dist/terminal/backends/iterm2.d.ts.map +1 -0
  213. package/dist/terminal/backends/iterm2.js +135 -0
  214. package/dist/terminal/backends/iterm2.js.map +1 -0
  215. package/dist/terminal/backends/shared.d.ts +9 -0
  216. package/dist/terminal/backends/shared.d.ts.map +1 -0
  217. package/dist/terminal/backends/shared.js +38 -0
  218. package/dist/terminal/backends/shared.js.map +1 -0
  219. package/dist/terminal/backends/terminal-app.d.ts +3 -0
  220. package/dist/terminal/backends/terminal-app.d.ts.map +1 -0
  221. package/dist/terminal/backends/terminal-app.js +129 -0
  222. package/dist/terminal/backends/terminal-app.js.map +1 -0
  223. package/dist/terminal/backends/tmux.d.ts +3 -0
  224. package/dist/terminal/backends/tmux.d.ts.map +1 -0
  225. package/dist/terminal/backends/tmux.js +76 -0
  226. package/dist/terminal/backends/tmux.js.map +1 -0
  227. package/dist/terminal/backends/wezterm.d.ts +3 -0
  228. package/dist/terminal/backends/wezterm.d.ts.map +1 -0
  229. package/dist/terminal/backends/wezterm.js +71 -0
  230. package/dist/terminal/backends/wezterm.js.map +1 -0
  231. package/dist/terminal/types.d.ts +22 -0
  232. package/dist/terminal/types.d.ts.map +1 -0
  233. package/dist/terminal/types.js +11 -0
  234. package/dist/terminal/types.js.map +1 -0
  235. package/dist/utils/process.d.ts +2 -0
  236. package/dist/utils/process.d.ts.map +1 -1
  237. package/dist/utils/process.js +3 -0
  238. package/dist/utils/process.js.map +1 -1
  239. package/package.json +1 -1
  240. package/src/AgentManager.ts +1 -1
  241. package/src/__tests__/capacity/anthropic.test.ts +105 -0
  242. package/src/__tests__/capacity/boundaries.test.ts +36 -0
  243. package/src/__tests__/capacity/claude.test.ts +3 -8
  244. package/src/__tests__/capacity/codex.test.ts +12 -35
  245. package/src/__tests__/capacity/fixtures/openai-codex-auth.json +1 -1
  246. package/src/__tests__/capacity/openai.test.ts +15 -15
  247. package/src/__tests__/capacity/wham.test.ts +1 -1
  248. package/src/__tests__/capacity/zai.test.ts +27 -62
  249. package/src/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.ts +2 -2
  250. package/src/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.ts +1 -1
  251. package/src/__tests__/harnesses/codex/durable/CodexCliProbe.test.ts +14 -19
  252. package/src/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.ts +3 -3
  253. package/src/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.ts +24 -30
  254. package/src/__tests__/harnesses/codex/durable/CodexPrintRunner.test.ts +4 -8
  255. package/src/__tests__/harnesses/devin/DevinAdapter.test.ts +292 -0
  256. package/src/__tests__/harnesses/devin/DevinAgentMapper.test.ts +88 -0
  257. package/src/__tests__/harnesses/devin/DevinSessionLocator.test.ts +139 -0
  258. package/src/__tests__/harnesses/devin/DevinSessionParser.test.ts +218 -0
  259. package/src/__tests__/harnesses/devin/fixtures.ts +144 -0
  260. package/src/__tests__/harnesses/pi/durable/PiCliProbe.test.ts +7 -11
  261. package/src/__tests__/harnesses/pi/durable/PiPrintAgentService.test.ts +19 -22
  262. package/src/__tests__/harnesses/pi/durable/PiPrintRunner.test.ts +7 -8
  263. package/src/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.ts +77 -9
  264. package/src/__tests__/harnesses/runtimeProfiles.test.ts +110 -0
  265. package/src/__tests__/print/DurableAgent.test.ts +4 -13
  266. package/src/__tests__/print/DurableAgentRepository.test.ts +1 -13
  267. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +1 -1
  268. package/src/__tests__/terminal/GhosttyBackend.test.ts +271 -0
  269. package/src/__tests__/terminal/TmuxManager.test.ts +1 -1
  270. package/src/adapters/AgentAdapter.ts +1 -0
  271. package/src/capacity/index.ts +29 -23
  272. package/src/capacity/{claude.ts → providers/anthropic.ts} +16 -131
  273. package/src/capacity/providers/openai-platform.ts +150 -0
  274. package/src/capacity/{wham.ts → providers/openai-subscription.ts} +86 -8
  275. package/src/capacity/{zai.ts → providers/zai.ts} +29 -111
  276. package/src/capacity/sources/claude.ts +30 -0
  277. package/src/capacity/{codex.ts → sources/codex.ts} +54 -124
  278. package/src/capacity/sources/pi.ts +131 -0
  279. package/src/capacity/types.ts +3 -0
  280. package/src/harnesses/claude/credentials.ts +122 -0
  281. package/src/harnesses/claude/readiness.ts +69 -0
  282. package/src/harnesses/codex/credentials.ts +81 -0
  283. package/src/harnesses/codex/readiness.ts +72 -0
  284. package/src/harnesses/copilot/readiness.ts +33 -0
  285. package/src/harnesses/devin/DevinAdapter.ts +224 -0
  286. package/src/harnesses/devin/DevinAgentMapper.ts +43 -0
  287. package/src/harnesses/devin/DevinSessionLocator.ts +230 -0
  288. package/src/harnesses/devin/DevinSessionParser.ts +236 -0
  289. package/src/harnesses/devin/readiness.ts +36 -0
  290. package/src/harnesses/index.ts +2 -0
  291. package/src/harnesses/opencode/readiness.ts +48 -0
  292. package/src/harnesses/pi/credentials.ts +129 -0
  293. package/src/harnesses/pi/readiness.ts +104 -0
  294. package/src/harnesses/readiness/AgentReadiness.ts +89 -0
  295. package/src/harnesses/readiness/checks.ts +336 -0
  296. package/src/harnesses/readiness/types.ts +90 -0
  297. package/src/{utils/agents.ts → harnesses/runtimeProfiles.ts} +35 -38
  298. package/src/index.ts +15 -128
  299. package/src/runtime/ManagedAgentRuntime.ts +7 -22
  300. package/src/runtime/herdr/HerdrAgentDiscovery.ts +3 -19
  301. package/src/runtime/tmux/PidPolling.ts +1 -1
  302. package/src/runtime/tmux/TmuxAgentRuntime.ts +1 -1
  303. package/src/{terminal → runtime/tmux}/TmuxManager.ts +9 -30
  304. package/src/runtime/types.ts +1 -1
  305. package/src/terminal/TerminalFocusManager.ts +19 -292
  306. package/src/terminal/TtyWriter.ts +15 -335
  307. package/src/terminal/backends/ghostty.ts +180 -0
  308. package/src/terminal/backends/index.ts +23 -0
  309. package/src/terminal/backends/iterm2.ts +126 -0
  310. package/src/terminal/backends/shared.ts +47 -0
  311. package/src/terminal/backends/terminal-app.ts +122 -0
  312. package/src/terminal/backends/tmux.ts +62 -0
  313. package/src/terminal/backends/wezterm.ts +65 -0
  314. package/src/terminal/types.ts +23 -0
  315. package/src/utils/process.ts +5 -0
  316. package/dist/__tests__/readiness/AgentReadiness.test.js.map +0 -1
  317. package/dist/__tests__/utils/agents.test.js +0 -93
  318. package/dist/__tests__/utils/agents.test.js.map +0 -1
  319. package/dist/capacity/claude.d.ts +0 -17
  320. package/dist/capacity/claude.d.ts.map +0 -1
  321. package/dist/capacity/claude.js.map +0 -1
  322. package/dist/capacity/codex.d.ts.map +0 -1
  323. package/dist/capacity/codex.js.map +0 -1
  324. package/dist/capacity/openai.d.ts +0 -47
  325. package/dist/capacity/openai.d.ts.map +0 -1
  326. package/dist/capacity/openai.js +0 -307
  327. package/dist/capacity/openai.js.map +0 -1
  328. package/dist/capacity/wham.d.ts +0 -16
  329. package/dist/capacity/wham.d.ts.map +0 -1
  330. package/dist/capacity/wham.js +0 -66
  331. package/dist/capacity/wham.js.map +0 -1
  332. package/dist/capacity/zai.d.ts +0 -14
  333. package/dist/capacity/zai.d.ts.map +0 -1
  334. package/dist/capacity/zai.js.map +0 -1
  335. package/dist/readiness/AgentReadiness.d.ts.map +0 -1
  336. package/dist/readiness/AgentReadiness.js +0 -614
  337. package/dist/readiness/AgentReadiness.js.map +0 -1
  338. package/dist/terminal/TmuxManager.d.ts +0 -28
  339. package/dist/terminal/TmuxManager.d.ts.map +0 -1
  340. package/dist/terminal/TmuxManager.js.map +0 -1
  341. package/dist/terminal/index.d.ts +0 -5
  342. package/dist/terminal/index.d.ts.map +0 -1
  343. package/dist/terminal/index.js +0 -5
  344. package/dist/terminal/index.js.map +0 -1
  345. package/dist/utils/agents.d.ts +0 -16
  346. package/dist/utils/agents.d.ts.map +0 -1
  347. package/dist/utils/agents.js +0 -117
  348. package/dist/utils/agents.js.map +0 -1
  349. package/dist/utils/index.d.ts +0 -8
  350. package/dist/utils/index.d.ts.map +0 -1
  351. package/dist/utils/index.js +0 -6
  352. package/dist/utils/index.js.map +0 -1
  353. package/src/__tests__/utils/agents.test.ts +0 -105
  354. package/src/capacity/openai.ts +0 -355
  355. package/src/readiness/AgentReadiness.ts +0 -730
  356. package/src/terminal/index.ts +0 -4
  357. package/src/utils/index.ts +0 -14
@@ -0,0 +1,218 @@
1
+ import Database from "better-sqlite3";
2
+ import * as fs from "fs";
3
+ import * as os from "os";
4
+ import * as path from "path";
5
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
6
+ import { DevinSessionParser } from "../../../harnesses/devin/DevinSessionParser.js";
7
+ import { writeDatabase } from "./fixtures.js";
8
+
9
+ describe("DevinSessionParser", () => {
10
+ let tmpDir: string;
11
+ let dbPath: string;
12
+ let parser: DevinSessionParser;
13
+
14
+ beforeEach(() => {
15
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "devin-parser-test-"));
16
+ dbPath = path.join(tmpDir, "sessions.db");
17
+ parser = new DevinSessionParser();
18
+ });
19
+
20
+ afterEach(() => {
21
+ fs.rmSync(tmpDir, { recursive: true, force: true });
22
+ });
23
+
24
+ function openDb(): Database.Database {
25
+ return new Database(dbPath, { readonly: true });
26
+ }
27
+
28
+ it("returns user and assistant messages in node order, skipping system", () => {
29
+ writeDatabase(dbPath, {
30
+ nodes: [
31
+ { sessionId: "s", nodeId: 1, role: "system", content: "preamble" },
32
+ { sessionId: "s", nodeId: 2, role: "user", content: "hello", isUserInput: true },
33
+ { sessionId: "s", nodeId: 3, role: "assistant", content: "hi" },
34
+ // Later turn roots a fresh preamble chain:
35
+ { sessionId: "s", nodeId: 4, role: "system", content: "more preamble" },
36
+ { sessionId: "s", nodeId: 5, role: "user", content: "again", isUserInput: true },
37
+ { sessionId: "s", nodeId: 6, role: "assistant", content: "done" },
38
+ ],
39
+ });
40
+ const db = openDb();
41
+ try {
42
+ expect(parser.getConversation(db, "s")).toEqual([
43
+ { role: "user", content: "hello" },
44
+ { role: "assistant", content: "hi" },
45
+ { role: "user", content: "again" },
46
+ { role: "assistant", content: "done" },
47
+ ]);
48
+ } finally {
49
+ db.close();
50
+ }
51
+ });
52
+
53
+ it("dedupes sibling revisions by message_id keeping the highest node_id", () => {
54
+ writeDatabase(dbPath, {
55
+ nodes: [
56
+ { sessionId: "s", nodeId: 1, role: "assistant", content: "draft", messageId: "m1" },
57
+ { sessionId: "s", nodeId: 2, role: "assistant", content: "final", messageId: "m1" },
58
+ ],
59
+ });
60
+ const db = openDb();
61
+ try {
62
+ expect(parser.getConversation(db, "s")).toEqual([
63
+ { role: "assistant", content: "final" },
64
+ ]);
65
+ } finally {
66
+ db.close();
67
+ }
68
+ });
69
+
70
+ it("skips non-input user nodes and empty content", () => {
71
+ writeDatabase(dbPath, {
72
+ nodes: [
73
+ { sessionId: "s", nodeId: 1, role: "user", content: "wrapper", isUserInput: false },
74
+ { sessionId: "s", nodeId: 2, role: "user", content: " ", isUserInput: true },
75
+ { sessionId: "s", nodeId: 3, role: "user", content: "real", isUserInput: true },
76
+ ],
77
+ });
78
+ const db = openDb();
79
+ try {
80
+ expect(parser.getConversation(db, "s")).toEqual([{ role: "user", content: "real" }]);
81
+ } finally {
82
+ db.close();
83
+ }
84
+ });
85
+
86
+ it("includes tools and thinking only in verbose mode", () => {
87
+ writeDatabase(dbPath, {
88
+ nodes: [
89
+ {
90
+ sessionId: "s",
91
+ nodeId: 1,
92
+ role: "assistant",
93
+ content: "working",
94
+ thinking: "hmm",
95
+ toolCalls: [{ function: { name: "exec" } }],
96
+ },
97
+ { sessionId: "s", nodeId: 2, role: "tool", content: "tool output", name: "exec" },
98
+ ],
99
+ });
100
+ const db = openDb();
101
+ try {
102
+ expect(parser.getConversation(db, "s")).toEqual([
103
+ { role: "assistant", content: "working" },
104
+ ]);
105
+ expect(parser.getConversation(db, "s", { verbose: true })).toEqual([
106
+ { role: "assistant", content: "[thinking] hmm" },
107
+ { role: "assistant", content: "working" },
108
+ { role: "assistant", content: "[tool: exec]" },
109
+ { role: "assistant", content: "[tool: exec] tool output" },
110
+ ]);
111
+ } finally {
112
+ db.close();
113
+ }
114
+ });
115
+
116
+ it("honors tail and bounds the query window", () => {
117
+ writeDatabase(dbPath, {
118
+ nodes: Array.from({ length: 30 }, (_, i) => ({
119
+ sessionId: "s",
120
+ nodeId: i + 1,
121
+ role: "user" as const,
122
+ content: `msg-${i + 1}`,
123
+ isUserInput: true,
124
+ })),
125
+ });
126
+ const db = openDb();
127
+ try {
128
+ const convo = parser.getConversation(db, "s", { tail: 3 });
129
+ expect(convo).toEqual([
130
+ { role: "user", content: "msg-28" },
131
+ { role: "user", content: "msg-29" },
132
+ { role: "user", content: "msg-30" },
133
+ ]);
134
+ } finally {
135
+ db.close();
136
+ }
137
+ });
138
+
139
+ it("skips malformed chat_message rows and missing sessions", () => {
140
+ writeDatabase(dbPath, {
141
+ nodes: [
142
+ { sessionId: "s", nodeId: 1, raw: "{not json" },
143
+ { sessionId: "s", nodeId: 2, role: "assistant", content: "ok" },
144
+ ],
145
+ });
146
+ const db = openDb();
147
+ try {
148
+ expect(parser.getConversation(db, "s")).toEqual([
149
+ { role: "assistant", content: "ok" },
150
+ ]);
151
+ expect(parser.getConversation(db, "missing")).toEqual([]);
152
+ } finally {
153
+ db.close();
154
+ }
155
+ });
156
+
157
+ it("reports session stats from the frontier node and latest prompt", () => {
158
+ writeDatabase(dbPath, {
159
+ nodes: [
160
+ { sessionId: "s", nodeId: 1, role: "user", content: "go", createdAt: 100 },
161
+ { sessionId: "s", nodeId: 2, role: "assistant", content: "done", createdAt: 200 },
162
+ ],
163
+ prompts: [
164
+ { sessionId: "s", content: "first task", timestamp: 100 },
165
+ { sessionId: "s", content: "/mcp", timestamp: 300 },
166
+ { sessionId: "s", content: "latest task", timestamp: 200 },
167
+ { sessionId: "s", content: "!shell", timestamp: 400, isShell: 1 },
168
+ ],
169
+ });
170
+ const db = openDb();
171
+ try {
172
+ expect(parser.getSessionStats(db, "s")).toEqual({
173
+ lastRole: "assistant",
174
+ lastTimeUpdated: 200_000,
175
+ summary: "latest task",
176
+ });
177
+ expect(parser.getSessionStats(db, "missing")).toEqual({
178
+ lastRole: null,
179
+ lastTimeUpdated: 0,
180
+ summary: "",
181
+ });
182
+ } finally {
183
+ db.close();
184
+ }
185
+ });
186
+
187
+ it("falls back to the first is_user_input node for the summary", () => {
188
+ writeDatabase(dbPath, {
189
+ nodes: [
190
+ { sessionId: "s", nodeId: 1, role: "user", content: "wrapper", isUserInput: false },
191
+ { sessionId: "s", nodeId: 2, role: "user", content: "real first", isUserInput: true },
192
+ ],
193
+ });
194
+ const db = openDb();
195
+ try {
196
+ expect(parser.getFirstUserMessage(db, "s")).toBe("real first");
197
+ } finally {
198
+ db.close();
199
+ }
200
+ });
201
+
202
+ it("falls back to the last is_user_input node for the working-on summary", () => {
203
+ writeDatabase(dbPath, {
204
+ nodes: [
205
+ { sessionId: "s", nodeId: 1, role: "user", content: "first", isUserInput: true },
206
+ { sessionId: "s", nodeId: 2, role: "user", content: "wrapper", isUserInput: false },
207
+ { sessionId: "s", nodeId: 3, role: "user", content: "last real", isUserInput: true },
208
+ ],
209
+ });
210
+ const db = openDb();
211
+ try {
212
+ expect(parser.getLastUserPrompt(db, "s")).toBe("last real");
213
+ expect(parser.getLastUserPrompt(db, "missing")).toBe("");
214
+ } finally {
215
+ db.close();
216
+ }
217
+ });
218
+ });
@@ -0,0 +1,144 @@
1
+ import Database from "better-sqlite3";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+
5
+ export interface DevinSessionInput {
6
+ id: string;
7
+ directory: string;
8
+ title?: string | null;
9
+ timeCreated: number;
10
+ lastActivityAt?: number;
11
+ mainChainId?: number | null;
12
+ hidden?: number;
13
+ }
14
+
15
+ export interface DevinNodeInput {
16
+ nodeId: number;
17
+ parentNodeId?: number | null;
18
+ role: string;
19
+ content?: string;
20
+ messageId?: string;
21
+ createdAt?: number;
22
+ isUserInput?: boolean;
23
+ toolCalls?: { name?: string; function?: { name?: string } }[];
24
+ thinking?: string;
25
+ name?: string;
26
+ /** Raw chat_message text; when set, other fields are ignored. */
27
+ raw?: string;
28
+ }
29
+
30
+ export interface DevinPromptInput {
31
+ sessionId: string;
32
+ content: string;
33
+ timestamp?: number;
34
+ isShell?: number;
35
+ }
36
+
37
+ export function writeDatabase(
38
+ dbPath: string,
39
+ data: {
40
+ sessions?: DevinSessionInput[];
41
+ nodes?: (DevinNodeInput & { sessionId: string })[];
42
+ prompts?: DevinPromptInput[];
43
+ },
44
+ ): void {
45
+ fs.mkdirSync(path.dirname(dbPath), { recursive: true });
46
+ const db = new Database(dbPath);
47
+ try {
48
+ db.exec(`
49
+ CREATE TABLE IF NOT EXISTS sessions (
50
+ id TEXT PRIMARY KEY,
51
+ working_directory TEXT NOT NULL,
52
+ backend_type TEXT NOT NULL DEFAULT 'local',
53
+ model TEXT NOT NULL DEFAULT 'test-model',
54
+ agent_mode TEXT NOT NULL DEFAULT 'normal',
55
+ created_at INTEGER NOT NULL,
56
+ last_activity_at INTEGER NOT NULL,
57
+ title TEXT,
58
+ main_chain_id INTEGER,
59
+ hidden INTEGER NOT NULL DEFAULT 0
60
+ );
61
+ CREATE TABLE IF NOT EXISTS message_nodes (
62
+ row_id INTEGER PRIMARY KEY AUTOINCREMENT,
63
+ session_id TEXT NOT NULL,
64
+ node_id INTEGER NOT NULL,
65
+ parent_node_id INTEGER,
66
+ chat_message TEXT NOT NULL,
67
+ created_at INTEGER NOT NULL,
68
+ UNIQUE(session_id, node_id)
69
+ );
70
+ CREATE TABLE IF NOT EXISTS prompt_history (
71
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
72
+ content TEXT NOT NULL,
73
+ timestamp INTEGER NOT NULL,
74
+ session_id TEXT NOT NULL,
75
+ is_shell INTEGER NOT NULL DEFAULT 0
76
+ );
77
+ `);
78
+
79
+ const insertSession = db.prepare(`
80
+ INSERT INTO sessions (id, working_directory, created_at, last_activity_at, title, main_chain_id, hidden)
81
+ VALUES (?, ?, ?, ?, ?, ?, ?)
82
+ `);
83
+ for (const session of data.sessions ?? []) {
84
+ insertSession.run(
85
+ session.id,
86
+ session.directory,
87
+ session.timeCreated,
88
+ session.lastActivityAt ?? session.timeCreated,
89
+ session.title ?? null,
90
+ session.mainChainId ?? null,
91
+ session.hidden ?? 0,
92
+ );
93
+ }
94
+
95
+ const insertNode = db.prepare(`
96
+ INSERT INTO message_nodes (session_id, node_id, parent_node_id, chat_message, created_at)
97
+ VALUES (?, ?, ?, ?, ?)
98
+ `);
99
+ for (const node of data.nodes ?? []) {
100
+ const chatMessage =
101
+ node.raw ??
102
+ JSON.stringify({
103
+ message_id: node.messageId ?? `msg-${node.nodeId}`,
104
+ role: node.role,
105
+ content: node.content ?? "",
106
+ ...(node.toolCalls ? { tool_calls: node.toolCalls } : {}),
107
+ ...(node.thinking ? { thinking: { thinking: node.thinking } } : {}),
108
+ ...(node.name ? { name: node.name } : {}),
109
+ ...(node.isUserInput !== undefined
110
+ ? { metadata: { is_user_input: node.isUserInput } }
111
+ : {}),
112
+ });
113
+ insertNode.run(
114
+ node.sessionId,
115
+ node.nodeId,
116
+ node.parentNodeId ?? null,
117
+ chatMessage,
118
+ node.createdAt ?? 1000 + node.nodeId,
119
+ );
120
+ }
121
+
122
+ const insertPrompt = db.prepare(`
123
+ INSERT INTO prompt_history (session_id, content, timestamp, is_shell)
124
+ VALUES (?, ?, ?, ?)
125
+ `);
126
+ for (const prompt of data.prompts ?? []) {
127
+ insertPrompt.run(
128
+ prompt.sessionId,
129
+ prompt.content,
130
+ prompt.timestamp ?? 1000,
131
+ prompt.isShell ?? 0,
132
+ );
133
+ }
134
+ } finally {
135
+ db.close();
136
+ }
137
+ }
138
+
139
+ export function writeLocks(locksDir: string, locks: Record<string, number | string>): void {
140
+ fs.mkdirSync(locksDir, { recursive: true });
141
+ for (const [sessionId, pid] of Object.entries(locks)) {
142
+ fs.writeFileSync(path.join(locksDir, `${sessionId}.lock`), String(pid));
143
+ }
144
+ }
@@ -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(),