@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,292 @@
1
+ import * as fs from "fs";
2
+ import * as os from "os";
3
+ import * as path from "path";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import { AgentStatus, type ProcessInfo } from "../../../adapters/AgentAdapter.js";
6
+ import { DevinAdapter } from "../../../harnesses/devin/DevinAdapter.js";
7
+ import { writeDatabase, writeLocks } from "./fixtures.js";
8
+
9
+ describe("DevinAdapter", () => {
10
+ let adapter: DevinAdapter;
11
+ let tmpDir: string;
12
+ let dbPath: string;
13
+ let locksDir: string;
14
+
15
+ beforeEach(() => {
16
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "devin-adapter-test-"));
17
+ dbPath = path.join(tmpDir, "sessions.db");
18
+ locksDir = path.join(tmpDir, "session_locks");
19
+ adapter = new DevinAdapter(dbPath, locksDir);
20
+ });
21
+
22
+ afterEach(() => {
23
+ adapter.close();
24
+ fs.rmSync(tmpDir, { recursive: true, force: true });
25
+ });
26
+
27
+ it("accepts agent invocations and rejects utility subcommands", () => {
28
+ const cases: [string, boolean][] = [
29
+ ["devin", true],
30
+ ["/usr/local/bin/devin", true],
31
+ ["devin -r brawny-shirt", true],
32
+ ["devin --resume brawny-shirt --model x", true],
33
+ ["devin -p fix the bug", true],
34
+ ["devin -p update the schema", true],
35
+ ["devin --print list files", true],
36
+ ["devin -r", true],
37
+ ["devin --resume", true],
38
+ ["devin --cloud", true],
39
+ ["devin acp", true],
40
+ ["/Users/x/.local/bin/devin acp --cloud", true],
41
+ ["devin -- list the files", true],
42
+ ["devin list", false],
43
+ ["devin ls", false],
44
+ ["devin doctor", false],
45
+ ["devin auth status", false],
46
+ ["devin ssh sess-1", false],
47
+ ["devin forward 8080", false],
48
+ ["devin models", false],
49
+ ["devin skills list", false],
50
+ ["devin rules", false],
51
+ ["devin mcp add x", false],
52
+ ["devin plugins list", false],
53
+ ["devin cloud ls", false],
54
+ ["devin desktop /repo", false],
55
+ ["devin update", false],
56
+ ["devin version", false],
57
+ ["devin migrate", false],
58
+ ["devin sandbox run", false],
59
+ ["devin setup", false],
60
+ ["devin uninstall", false],
61
+ ["devin rm sess-1", false],
62
+ ["devin help", false],
63
+ ["devin --model opus list", false],
64
+ ["devin --model=opus list", false],
65
+ ["devin --config /tmp/c.json update", false],
66
+ ["devin --prompt-file /tmp/p.txt rm", false],
67
+ ["node devin.js", false],
68
+ ["devinition", false],
69
+ ];
70
+ for (const [command, expected] of cases) {
71
+ expect(adapter.canHandle({ pid: 1, command, cwd: "/repo", tty: "ttys001" })).toBe(
72
+ expected,
73
+ command,
74
+ );
75
+ }
76
+ });
77
+
78
+ it("returns process-only agents when no database or lock exists", async () => {
79
+ const agents = await adapter.detectAgents({
80
+ processes: [{ pid: 100, command: "devin", cwd: "/repo", tty: "ttys001" }],
81
+ });
82
+
83
+ expect(agents).toEqual([
84
+ expect.objectContaining({
85
+ type: "devin",
86
+ status: AgentStatus.RUNNING,
87
+ pid: 100,
88
+ sessionId: "pid-100",
89
+ summary: "Devin process running",
90
+ }),
91
+ ]);
92
+ });
93
+
94
+ it("matches a TUI to its session through the acp backend's lock", async () => {
95
+ const now = Math.floor(Date.now() / 1000);
96
+ writeDatabase(dbPath, {
97
+ sessions: [{ id: "brawny-shirt", directory: "/repo", timeCreated: now - 100 }],
98
+ nodes: [
99
+ {
100
+ sessionId: "brawny-shirt",
101
+ nodeId: 1,
102
+ role: "user",
103
+ content: "fix the tests",
104
+ isUserInput: true,
105
+ createdAt: now - 90,
106
+ },
107
+ {
108
+ sessionId: "brawny-shirt",
109
+ nodeId: 2,
110
+ role: "assistant",
111
+ content: "on it",
112
+ createdAt: now - 60,
113
+ },
114
+ ],
115
+ prompts: [{ sessionId: "brawny-shirt", content: "fix the tests", timestamp: now - 90 }],
116
+ });
117
+ writeLocks(locksDir, { "brawny-shirt": 201 });
118
+
119
+ const tui: ProcessInfo = { pid: 200, command: "devin", cwd: "/repo", tty: "ttys001" };
120
+ const acp: ProcessInfo = {
121
+ pid: 201,
122
+ ppid: 200,
123
+ command: "/usr/local/bin/devin acp",
124
+ cwd: "/repo",
125
+ tty: "??",
126
+ };
127
+ const agents = await adapter.detectAgents({ processes: [tui, acp] });
128
+
129
+ expect(agents).toHaveLength(1);
130
+ expect(agents[0]).toMatchObject({
131
+ type: "devin",
132
+ status: AgentStatus.WAITING,
133
+ pid: 200,
134
+ sessionId: "brawny-shirt",
135
+ summary: "fix the tests",
136
+ sessionFilePath: `${dbPath}::brawny-shirt`,
137
+ });
138
+ });
139
+
140
+ it("lists a standalone devin acp process as an agent via its own lock", async () => {
141
+ const now = Math.floor(Date.now() / 1000);
142
+ writeDatabase(dbPath, {
143
+ sessions: [{ id: "merry-frog", directory: "/repo", timeCreated: now - 50 }],
144
+ nodes: [
145
+ {
146
+ sessionId: "merry-frog",
147
+ nodeId: 1,
148
+ role: "tool",
149
+ content: "running",
150
+ createdAt: now - 10,
151
+ },
152
+ ],
153
+ });
154
+ writeLocks(locksDir, { "merry-frog": 300 });
155
+
156
+ const acp: ProcessInfo = {
157
+ pid: 300,
158
+ ppid: 999,
159
+ command: "devin acp",
160
+ cwd: "/repo",
161
+ tty: "??",
162
+ };
163
+ const agents = await adapter.detectAgents({ processes: [acp] });
164
+
165
+ expect(agents).toHaveLength(1);
166
+ expect(agents[0]).toMatchObject({
167
+ type: "devin",
168
+ status: AgentStatus.RUNNING,
169
+ pid: 300,
170
+ sessionId: "merry-frog",
171
+ });
172
+ });
173
+
174
+ it("ignores stale locks whose holder is not a live devin process", async () => {
175
+ const now = Math.floor(Date.now() / 1000);
176
+ writeDatabase(dbPath, {
177
+ sessions: [{ id: "dead-session", directory: "/repo", timeCreated: now - 500 }],
178
+ });
179
+ writeLocks(locksDir, { "dead-session": 4242 });
180
+
181
+ const agents = await adapter.detectAgents({
182
+ processes: [{ pid: 100, command: "devin", cwd: "/repo", tty: "ttys001" }],
183
+ });
184
+
185
+ // No lock match; cwd fallback still finds the session row.
186
+ expect(agents).toHaveLength(1);
187
+ expect(agents[0]).toMatchObject({ type: "devin", sessionId: "dead-session", pid: 100 });
188
+ });
189
+
190
+ it("ignores a lock when its pid is reused by a non-devin process", async () => {
191
+ const now = Math.floor(Date.now() / 1000);
192
+ writeDatabase(dbPath, {
193
+ sessions: [{ id: "reused-pid", directory: "/other", timeCreated: now - 500 }],
194
+ });
195
+ writeLocks(locksDir, { "reused-pid": 777 });
196
+
197
+ const processes: ProcessInfo[] = [
198
+ { pid: 777, command: "redis-server", cwd: "/", tty: "??" },
199
+ { pid: 100, command: "devin", cwd: "/repo", tty: "ttys001" },
200
+ ];
201
+ const agents = await adapter.detectAgents({ processes });
202
+
203
+ expect(agents).toHaveLength(1);
204
+ expect(agents[0]).toMatchObject({ sessionId: "pid-100" });
205
+ });
206
+
207
+ it("disambiguates two TUIs in the same directory via their locks", async () => {
208
+ const now = Math.floor(Date.now() / 1000);
209
+ writeDatabase(dbPath, {
210
+ sessions: [
211
+ { id: "first", directory: "/repo", timeCreated: now - 200 },
212
+ { id: "second", directory: "/repo", timeCreated: now - 100 },
213
+ ],
214
+ nodes: [
215
+ { sessionId: "first", nodeId: 1, role: "assistant", content: "a", createdAt: now - 50 },
216
+ { sessionId: "second", nodeId: 1, role: "assistant", content: "b", createdAt: now - 40 },
217
+ ],
218
+ });
219
+ writeLocks(locksDir, { first: 401, second: 501 });
220
+
221
+ const processes: ProcessInfo[] = [
222
+ { pid: 400, command: "devin", cwd: "/repo", tty: "ttys001" },
223
+ { pid: 401, ppid: 400, command: "devin acp", cwd: "/repo", tty: "??" },
224
+ { pid: 500, command: "devin", cwd: "/repo", tty: "ttys002" },
225
+ { pid: 501, ppid: 500, command: "devin acp", cwd: "/repo", tty: "??" },
226
+ ];
227
+ const agents = await adapter.detectAgents({ processes });
228
+
229
+ expect(agents).toHaveLength(2);
230
+ expect(agents.find((a) => a.pid === 400)?.sessionId).toBe("first");
231
+ expect(agents.find((a) => a.pid === 500)?.sessionId).toBe("second");
232
+ });
233
+
234
+ it("falls back to working_directory matching without a lock", async () => {
235
+ const now = Math.floor(Date.now() / 1000);
236
+ writeDatabase(dbPath, {
237
+ sessions: [
238
+ { id: "older", directory: "/repo", timeCreated: now - 300, lastActivityAt: now - 300 },
239
+ { id: "newer", directory: "/repo", timeCreated: now - 200, lastActivityAt: now - 60 },
240
+ { id: "hidden-sess", directory: "/repo", timeCreated: now - 10, hidden: 1 },
241
+ ],
242
+ nodes: [
243
+ { sessionId: "newer", nodeId: 1, role: "user", content: "hi", createdAt: now - 60 },
244
+ ],
245
+ });
246
+
247
+ const agents = await adapter.detectAgents({
248
+ processes: [{ pid: 100, command: "devin -p work", cwd: "/repo", tty: "ttys001" }],
249
+ });
250
+
251
+ expect(agents).toHaveLength(1);
252
+ expect(agents[0]).toMatchObject({ sessionId: "newer", type: "devin" });
253
+ });
254
+
255
+ it("survives an unreadable database", async () => {
256
+ fs.writeFileSync(dbPath, "not sqlite at all");
257
+ const agents = await adapter.detectAgents({
258
+ processes: [{ pid: 100, command: "devin", cwd: "/repo", tty: "ttys001" }],
259
+ });
260
+ expect(agents).toEqual([expect.objectContaining({ sessionId: "pid-100" })]);
261
+ });
262
+
263
+ it("returns conversation messages for encoded session refs", () => {
264
+ writeDatabase(dbPath, {
265
+ sessions: [{ id: "sess-1", directory: "/repo", timeCreated: 1000 }],
266
+ nodes: [
267
+ { sessionId: "sess-1", nodeId: 1, role: "user", content: "hello", isUserInput: true },
268
+ { sessionId: "sess-1", nodeId: 2, role: "assistant", content: "hi there" },
269
+ ],
270
+ });
271
+
272
+ expect(adapter.getConversation(`${dbPath}::sess-1`)).toEqual([
273
+ { role: "user", content: "hello" },
274
+ { role: "assistant", content: "hi there" },
275
+ ]);
276
+ expect(adapter.getConversation("/not-a-ref")).toEqual([]);
277
+ });
278
+
279
+ it("finds sessions by exact slug", async () => {
280
+ writeDatabase(dbPath, {
281
+ sessions: [
282
+ { id: "wanted", directory: "/repo", timeCreated: 1000 },
283
+ { id: "other", directory: "/other", timeCreated: 999 },
284
+ ],
285
+ });
286
+
287
+ await expect(adapter.findSessionsById("wanted")).resolves.toEqual([
288
+ expect.objectContaining({ type: "devin", sessionId: "wanted" }),
289
+ ]);
290
+ await expect(adapter.findSessionsById("missing")).resolves.toEqual([]);
291
+ });
292
+ });
@@ -0,0 +1,88 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { AgentStatus, type ProcessInfo } from "../../../adapters/AgentAdapter.js";
3
+ import { DevinAgentMapper } from "../../../harnesses/devin/DevinAgentMapper.js";
4
+ import type { DevinSession } from "../../../harnesses/devin/DevinSessionLocator.js";
5
+
6
+ const DB_PATH = "/data/devin/cli/sessions.db";
7
+
8
+ function session(overrides: Partial<DevinSession> = {}): DevinSession {
9
+ return {
10
+ sessionId: "brawny-shirt",
11
+ directory: "/repo",
12
+ title: null,
13
+ timeCreated: Date.now() - 60_000,
14
+ lastActivityAt: Date.now() - 30_000,
15
+ ...overrides,
16
+ };
17
+ }
18
+
19
+ function proc(overrides: Partial<ProcessInfo> = {}): ProcessInfo {
20
+ return { pid: 42, command: "devin", cwd: "/repo", tty: "ttys001", ...overrides };
21
+ }
22
+
23
+ describe("DevinAgentMapper", () => {
24
+ const mapper = new DevinAgentMapper(DB_PATH);
25
+
26
+ it("maps a session to a waiting agent when the frontier node is assistant", () => {
27
+ const agent = mapper.mapSessionToAgent(
28
+ session(),
29
+ { lastRole: "assistant", lastTimeUpdated: Date.now() - 1000, summary: "fix tests" },
30
+ proc(),
31
+ );
32
+
33
+ expect(agent).toMatchObject({
34
+ type: "devin",
35
+ status: AgentStatus.WAITING,
36
+ pid: 42,
37
+ projectPath: "/repo",
38
+ sessionId: "brawny-shirt",
39
+ summary: "fix tests",
40
+ sessionFilePath: `${DB_PATH}::brawny-shirt`,
41
+ });
42
+ });
43
+
44
+ it("maps running status for user/tool frontier nodes", () => {
45
+ for (const lastRole of ["user", "tool", null]) {
46
+ const agent = mapper.mapSessionToAgent(
47
+ session(),
48
+ { lastRole, lastTimeUpdated: Date.now() - 1000, summary: "" },
49
+ proc(),
50
+ );
51
+ expect(agent.status).toBe(AgentStatus.RUNNING);
52
+ }
53
+ });
54
+
55
+ it("marks stale sessions idle", () => {
56
+ const agent = mapper.mapSessionToAgent(
57
+ session(),
58
+ {
59
+ lastRole: "assistant",
60
+ lastTimeUpdated: Date.now() - 10 * 60 * 1000,
61
+ summary: "",
62
+ },
63
+ proc(),
64
+ );
65
+ expect(agent.status).toBe(AgentStatus.IDLE);
66
+ });
67
+
68
+ it("falls back to session title then directory for summary and project path", () => {
69
+ const agent = mapper.mapSessionToAgent(
70
+ session({ title: "Hello Greeting Session" }),
71
+ { lastRole: "assistant", lastTimeUpdated: 0, summary: "" },
72
+ proc({ cwd: "/elsewhere" }),
73
+ );
74
+ expect(agent.summary).toBe("Hello Greeting Session");
75
+ expect(agent.projectPath).toBe("/repo");
76
+ });
77
+
78
+ it("maps a process-only agent", () => {
79
+ const agent = mapper.mapProcessOnlyAgent(proc({ pid: 7 }));
80
+ expect(agent).toMatchObject({
81
+ type: "devin",
82
+ status: AgentStatus.RUNNING,
83
+ pid: 7,
84
+ sessionId: "pid-7",
85
+ summary: "Devin process running",
86
+ });
87
+ });
88
+ });
@@ -0,0 +1,139 @@
1
+ import * as fs from "fs";
2
+ import * as os from "os";
3
+ import * as path from "path";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import { DevinSessionLocator } from "../../../harnesses/devin/DevinSessionLocator.js";
6
+ import { writeDatabase, writeLocks } from "./fixtures.js";
7
+
8
+ describe("DevinSessionLocator", () => {
9
+ let tmpDir: string;
10
+ let dbPath: string;
11
+ let locksDir: string;
12
+ let locator: DevinSessionLocator;
13
+
14
+ beforeEach(() => {
15
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "devin-locator-test-"));
16
+ dbPath = path.join(tmpDir, "sessions.db");
17
+ locksDir = path.join(tmpDir, "session_locks");
18
+ locator = new DevinSessionLocator(dbPath, locksDir);
19
+ });
20
+
21
+ afterEach(() => {
22
+ locator.close();
23
+ fs.rmSync(tmpDir, { recursive: true, force: true });
24
+ });
25
+
26
+ it("lists active locks and skips malformed entries", () => {
27
+ writeLocks(locksDir, { "alpha-session": 100, "beta-session": "200" });
28
+ fs.writeFileSync(path.join(locksDir, "broken.lock"), "not-a-pid");
29
+ fs.writeFileSync(path.join(locksDir, "empty.lock"), "");
30
+ fs.writeFileSync(path.join(locksDir, ".lock"), "300");
31
+ fs.writeFileSync(path.join(locksDir, "not-a-lock.txt"), "400");
32
+
33
+ expect(locator.listActiveLocks()).toEqual([
34
+ { sessionId: "alpha-session", pid: 100 },
35
+ { sessionId: "beta-session", pid: 200 },
36
+ ]);
37
+ });
38
+
39
+ it("returns an empty lock list when the directory is missing", () => {
40
+ expect(locator.listActiveLocks()).toEqual([]);
41
+ });
42
+
43
+ it("finds the most recent visible session for a directory", () => {
44
+ writeDatabase(dbPath, {
45
+ sessions: [
46
+ { id: "older", directory: "/repo", timeCreated: 100, lastActivityAt: 100 },
47
+ { id: "newer", directory: "/repo", timeCreated: 200, lastActivityAt: 300 },
48
+ { id: "hidden", directory: "/repo", timeCreated: 400, lastActivityAt: 400, hidden: 1 },
49
+ ],
50
+ });
51
+
52
+ const db = locator.openDb()!;
53
+ expect(locator.findSessionForDirectory(db, "/repo")?.sessionId).toBe("newer");
54
+ expect(locator.findSessionForDirectory(db, "/missing")).toBeNull();
55
+ });
56
+
57
+ it("finds a session by id for the lock join", () => {
58
+ writeDatabase(dbPath, {
59
+ sessions: [
60
+ { id: "by-id", directory: "/repo", timeCreated: 100, title: "Title" },
61
+ { id: "gone", directory: "/repo", timeCreated: 100, hidden: 1 },
62
+ ],
63
+ });
64
+
65
+ const db = locator.openDb()!;
66
+ const session = locator.findSessionById(db, "by-id");
67
+ expect(session).toMatchObject({
68
+ sessionId: "by-id",
69
+ directory: "/repo",
70
+ title: "Title",
71
+ timeCreated: 100_000,
72
+ });
73
+ expect(locator.findSessionById(db, "gone")).toBeNull();
74
+ expect(locator.findSessionById(db, "missing")).toBeNull();
75
+ });
76
+
77
+ it("lists sessions with cwd filtering, hidden skip, and prompt summary", () => {
78
+ writeDatabase(dbPath, {
79
+ sessions: [
80
+ { id: "a", directory: "/repo", timeCreated: 100, lastActivityAt: 150 },
81
+ { id: "b", directory: "/other", timeCreated: 200, lastActivityAt: 250 },
82
+ { id: "c", directory: "/repo", timeCreated: 300, hidden: 1 },
83
+ ],
84
+ prompts: [
85
+ { sessionId: "a", content: "first prompt", timestamp: 110 },
86
+ { sessionId: "a", content: "!shell cmd", timestamp: 105, isShell: 1 },
87
+ { sessionId: "b", content: "other prompt", timestamp: 210 },
88
+ ],
89
+ });
90
+
91
+ const all = locator.listSessions();
92
+ expect(all.map((s) => s.sessionId)).toEqual(["b", "a"]);
93
+
94
+ const filtered = locator.listSessions({ cwd: "/repo" });
95
+ expect(filtered).toEqual([
96
+ expect.objectContaining({
97
+ type: "devin",
98
+ sessionId: "a",
99
+ cwd: "/repo",
100
+ firstUserMessage: "first prompt",
101
+ lastActive: new Date(150_000),
102
+ startedAt: new Date(100_000),
103
+ sessionFilePath: `${dbPath}::a`,
104
+ }),
105
+ ]);
106
+ });
107
+
108
+ it("resolves the db path from XDG_DATA_HOME or ~/.local/share", () => {
109
+ const prevXdg = process.env.XDG_DATA_HOME;
110
+ const prevHome = process.env.HOME;
111
+ try {
112
+ process.env.XDG_DATA_HOME = "/xdg";
113
+ expect(DevinSessionLocator.resolveDbPath()).toBe(
114
+ path.join("/xdg", "devin", "cli", "sessions.db"),
115
+ );
116
+ delete process.env.XDG_DATA_HOME;
117
+ process.env.HOME = "/home/u";
118
+ expect(DevinSessionLocator.resolveDbPath()).toBe(
119
+ path.join("/home/u", ".local", "share", "devin", "cli", "sessions.db"),
120
+ );
121
+ } finally {
122
+ if (prevXdg === undefined) delete process.env.XDG_DATA_HOME;
123
+ else process.env.XDG_DATA_HOME = prevXdg;
124
+ if (prevHome === undefined) delete process.env.HOME;
125
+ else process.env.HOME = prevHome;
126
+ }
127
+ });
128
+
129
+ it("returns empty results when the database is missing or corrupt", () => {
130
+ expect(locator.openDb()).toBeNull();
131
+ expect(locator.listSessions()).toEqual([]);
132
+ expect(locator.findSessionsById("x")).toEqual([]);
133
+
134
+ fs.writeFileSync(dbPath, "garbage");
135
+ const fresh = new DevinSessionLocator(dbPath, locksDir);
136
+ expect(fresh.listSessions()).toEqual([]);
137
+ fresh.close();
138
+ });
139
+ });