@roj-ai/sdk 0.1.36 → 0.2.2

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 (925) hide show
  1. package/dist/bootstrap.d.ts +420 -26
  2. package/dist/bootstrap.d.ts.map +1 -1
  3. package/dist/bootstrap.js +55 -24
  4. package/dist/bootstrap.js.map +1 -1
  5. package/dist/bun-platform/fs.d.ts.map +1 -1
  6. package/dist/bun-platform/fs.js +1 -0
  7. package/dist/bun-platform/fs.js.map +1 -1
  8. package/dist/bun-platform/index.d.ts +4 -1
  9. package/dist/bun-platform/index.d.ts.map +1 -1
  10. package/dist/bun-platform/index.js +7 -1
  11. package/dist/bun-platform/index.js.map +1 -1
  12. package/dist/bun-platform/server-lifecycle.d.ts +30 -0
  13. package/dist/bun-platform/server-lifecycle.d.ts.map +1 -0
  14. package/dist/bun-platform/server-lifecycle.js +182 -0
  15. package/dist/bun-platform/server-lifecycle.js.map +1 -0
  16. package/dist/bun-platform/shell.d.ts +33 -0
  17. package/dist/bun-platform/shell.d.ts.map +1 -0
  18. package/dist/bun-platform/shell.js +322 -0
  19. package/dist/bun-platform/shell.js.map +1 -0
  20. package/dist/config.d.ts +34 -0
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +97 -0
  23. package/dist/config.js.map +1 -1
  24. package/dist/core/agents/agent.d.ts +42 -7
  25. package/dist/core/agents/agent.d.ts.map +1 -1
  26. package/dist/core/agents/agent.js +202 -87
  27. package/dist/core/agents/agent.js.map +1 -1
  28. package/dist/core/agents/config.d.ts +8 -1
  29. package/dist/core/agents/config.d.ts.map +1 -1
  30. package/dist/core/agents/config.js +5 -1
  31. package/dist/core/agents/config.js.map +1 -1
  32. package/dist/core/agents/retry.d.ts +1 -1
  33. package/dist/core/agents/retry.d.ts.map +1 -1
  34. package/dist/core/agents/retry.js +14 -16
  35. package/dist/core/agents/retry.js.map +1 -1
  36. package/dist/core/agents/state.d.ts +3 -1
  37. package/dist/core/agents/state.d.ts.map +1 -1
  38. package/dist/core/agents/state.js +1 -1
  39. package/dist/core/agents/state.js.map +1 -1
  40. package/dist/core/context/state.d.ts +3 -3
  41. package/dist/core/context/state.js +2 -2
  42. package/dist/core/events/base-event-store.d.ts.map +1 -1
  43. package/dist/core/events/base-event-store.js +22 -14
  44. package/dist/core/events/base-event-store.js.map +1 -1
  45. package/dist/core/events/file.d.ts +39 -1
  46. package/dist/core/events/file.d.ts.map +1 -1
  47. package/dist/core/events/file.js +159 -20
  48. package/dist/core/events/file.js.map +1 -1
  49. package/dist/core/events/types.d.ts +1 -1
  50. package/dist/core/file-store/containment.d.ts +19 -0
  51. package/dist/core/file-store/containment.d.ts.map +1 -0
  52. package/dist/core/file-store/containment.js +62 -0
  53. package/dist/core/file-store/containment.js.map +1 -0
  54. package/dist/core/file-store/file-store.d.ts +22 -2
  55. package/dist/core/file-store/file-store.d.ts.map +1 -1
  56. package/dist/core/file-store/file-store.js +88 -20
  57. package/dist/core/file-store/file-store.js.map +1 -1
  58. package/dist/core/file-store/types.d.ts +13 -1
  59. package/dist/core/file-store/types.d.ts.map +1 -1
  60. package/dist/core/image/image-processor.d.ts.map +1 -1
  61. package/dist/core/image/image-processor.js +3 -1
  62. package/dist/core/image/image-processor.js.map +1 -1
  63. package/dist/core/image/types.d.ts +2 -0
  64. package/dist/core/image/types.d.ts.map +1 -1
  65. package/dist/core/image/vips-resizer.d.ts.map +1 -1
  66. package/dist/core/image/vips-resizer.js +81 -33
  67. package/dist/core/image/vips-resizer.js.map +1 -1
  68. package/dist/core/llm/anthropic.d.ts +0 -1
  69. package/dist/core/llm/anthropic.d.ts.map +1 -1
  70. package/dist/core/llm/anthropic.js +58 -72
  71. package/dist/core/llm/anthropic.js.map +1 -1
  72. package/dist/core/llm/logger.d.ts +14 -2
  73. package/dist/core/llm/logger.d.ts.map +1 -1
  74. package/dist/core/llm/logger.js +161 -36
  75. package/dist/core/llm/logger.js.map +1 -1
  76. package/dist/core/llm/openrouter.d.ts +0 -1
  77. package/dist/core/llm/openrouter.d.ts.map +1 -1
  78. package/dist/core/llm/openrouter.js +53 -66
  79. package/dist/core/llm/openrouter.js.map +1 -1
  80. package/dist/core/llm/provider-request.d.ts +10 -0
  81. package/dist/core/llm/provider-request.d.ts.map +1 -0
  82. package/dist/core/llm/provider-request.js +41 -0
  83. package/dist/core/llm/provider-request.js.map +1 -0
  84. package/dist/core/llm/provider.d.ts +11 -0
  85. package/dist/core/llm/provider.d.ts.map +1 -1
  86. package/dist/core/llm/provider.js +26 -0
  87. package/dist/core/llm/provider.js.map +1 -1
  88. package/dist/core/llm/state.d.ts +2 -2
  89. package/dist/core/llm/state.js +4 -4
  90. package/dist/core/plugins/plugin-builder.d.ts +57 -3
  91. package/dist/core/plugins/plugin-builder.d.ts.map +1 -1
  92. package/dist/core/plugins/plugin-builder.js +68 -14
  93. package/dist/core/plugins/plugin-builder.js.map +1 -1
  94. package/dist/core/preset/preset-builder.d.ts +3 -2
  95. package/dist/core/preset/preset-builder.d.ts.map +1 -1
  96. package/dist/core/preset/preset-builder.js +7 -16
  97. package/dist/core/preset/preset-builder.js.map +1 -1
  98. package/dist/core/sessions/context.d.ts +23 -5
  99. package/dist/core/sessions/context.d.ts.map +1 -1
  100. package/dist/core/sessions/runtime-activity.d.ts +33 -0
  101. package/dist/core/sessions/runtime-activity.d.ts.map +1 -0
  102. package/dist/core/sessions/runtime-activity.js +55 -0
  103. package/dist/core/sessions/runtime-activity.js.map +1 -0
  104. package/dist/core/sessions/schema.d.ts +23 -2
  105. package/dist/core/sessions/schema.d.ts.map +1 -1
  106. package/dist/core/sessions/schema.js +24 -3
  107. package/dist/core/sessions/schema.js.map +1 -1
  108. package/dist/core/sessions/session-manager.d.ts +83 -6
  109. package/dist/core/sessions/session-manager.d.ts.map +1 -1
  110. package/dist/core/sessions/session-manager.js +517 -118
  111. package/dist/core/sessions/session-manager.js.map +1 -1
  112. package/dist/core/sessions/session-store.d.ts +18 -0
  113. package/dist/core/sessions/session-store.d.ts.map +1 -1
  114. package/dist/core/sessions/session-store.js +33 -0
  115. package/dist/core/sessions/session-store.js.map +1 -1
  116. package/dist/core/sessions/session.d.ts +42 -6
  117. package/dist/core/sessions/session.d.ts.map +1 -1
  118. package/dist/core/sessions/session.js +176 -44
  119. package/dist/core/sessions/session.js.map +1 -1
  120. package/dist/core/sessions/state.d.ts +10 -1
  121. package/dist/core/sessions/state.d.ts.map +1 -1
  122. package/dist/core/sessions/state.js +11 -1
  123. package/dist/core/sessions/state.js.map +1 -1
  124. package/dist/core/system.d.ts +9 -0
  125. package/dist/core/system.d.ts.map +1 -1
  126. package/dist/core/system.js +4 -1
  127. package/dist/core/system.js.map +1 -1
  128. package/dist/core/tools/executor.d.ts +1 -1
  129. package/dist/core/wake-key.d.ts +34 -0
  130. package/dist/core/wake-key.d.ts.map +1 -0
  131. package/dist/core/wake-key.js +51 -0
  132. package/dist/core/wake-key.js.map +1 -0
  133. package/dist/index.d.ts +25 -13
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +23 -8
  136. package/dist/index.js.map +1 -1
  137. package/dist/lib/archive/archive-inspection.d.ts +48 -0
  138. package/dist/lib/archive/archive-inspection.d.ts.map +1 -0
  139. package/dist/lib/archive/archive-inspection.fixtures.d.ts +7 -0
  140. package/dist/lib/archive/archive-inspection.fixtures.d.ts.map +1 -0
  141. package/dist/lib/archive/archive-inspection.fixtures.js +134 -0
  142. package/dist/lib/archive/archive-inspection.fixtures.js.map +1 -0
  143. package/dist/lib/archive/archive-inspection.js +253 -0
  144. package/dist/lib/archive/archive-inspection.js.map +1 -0
  145. package/dist/lib/archive/index.d.ts +3 -0
  146. package/dist/lib/archive/index.d.ts.map +1 -0
  147. package/dist/lib/archive/index.js +2 -0
  148. package/dist/lib/archive/index.js.map +1 -0
  149. package/dist/lib/logger/console.d.ts +5 -12
  150. package/dist/lib/logger/console.d.ts.map +1 -1
  151. package/dist/lib/logger/console.js +5 -47
  152. package/dist/lib/logger/console.js.map +1 -1
  153. package/dist/lib/logger/file.d.ts +8 -11
  154. package/dist/lib/logger/file.d.ts.map +1 -1
  155. package/dist/lib/logger/file.js +26 -37
  156. package/dist/lib/logger/file.js.map +1 -1
  157. package/dist/lib/logger/index.d.ts +3 -1
  158. package/dist/lib/logger/index.d.ts.map +1 -1
  159. package/dist/lib/logger/index.js +3 -1
  160. package/dist/lib/logger/index.js.map +1 -1
  161. package/dist/lib/logger/jsonl.d.ts +21 -0
  162. package/dist/lib/logger/jsonl.d.ts.map +1 -0
  163. package/dist/lib/logger/jsonl.js +29 -0
  164. package/dist/lib/logger/jsonl.js.map +1 -0
  165. package/dist/lib/logger/logger.d.ts +22 -0
  166. package/dist/lib/logger/logger.d.ts.map +1 -1
  167. package/dist/lib/logger/logger.js +37 -0
  168. package/dist/lib/logger/logger.js.map +1 -1
  169. package/dist/lib/logger/session-log.d.ts +21 -0
  170. package/dist/lib/logger/session-log.d.ts.map +1 -0
  171. package/dist/lib/logger/session-log.js +37 -0
  172. package/dist/lib/logger/session-log.js.map +1 -0
  173. package/dist/lib/utils/concurrency.d.ts +1 -1
  174. package/dist/lib/utils/concurrency.d.ts.map +1 -1
  175. package/dist/lib/utils/concurrency.js +30 -7
  176. package/dist/lib/utils/concurrency.js.map +1 -1
  177. package/dist/lib/utils/fs-batch.d.ts +17 -0
  178. package/dist/lib/utils/fs-batch.d.ts.map +1 -0
  179. package/dist/lib/utils/fs-batch.js +38 -0
  180. package/dist/lib/utils/fs-batch.js.map +1 -0
  181. package/dist/lib/utils/result.d.ts +7 -22
  182. package/dist/lib/utils/result.d.ts.map +1 -1
  183. package/dist/lib/utils/result.js +6 -17
  184. package/dist/lib/utils/result.js.map +1 -1
  185. package/dist/lib/utils/sleep.d.ts +10 -0
  186. package/dist/lib/utils/sleep.d.ts.map +1 -0
  187. package/dist/lib/utils/sleep.js +26 -0
  188. package/dist/lib/utils/sleep.js.map +1 -0
  189. package/dist/platform/fs-revision.d.ts +21 -0
  190. package/dist/platform/fs-revision.d.ts.map +1 -0
  191. package/dist/platform/fs-revision.js +9 -0
  192. package/dist/platform/fs-revision.js.map +1 -0
  193. package/dist/platform/fs.d.ts +104 -1
  194. package/dist/platform/fs.d.ts.map +1 -1
  195. package/dist/platform/git.d.ts +59 -0
  196. package/dist/platform/git.d.ts.map +1 -0
  197. package/dist/platform/git.js +8 -0
  198. package/dist/platform/git.js.map +1 -0
  199. package/dist/platform/index.d.ts +40 -1
  200. package/dist/platform/index.d.ts.map +1 -1
  201. package/dist/platform/index.js +1 -1
  202. package/dist/platform/index.js.map +1 -1
  203. package/dist/platform/llm-call-log.d.ts +80 -0
  204. package/dist/platform/llm-call-log.d.ts.map +1 -0
  205. package/dist/platform/llm-call-log.js +12 -0
  206. package/dist/platform/llm-call-log.js.map +1 -0
  207. package/dist/platform/scheduler.d.ts +32 -0
  208. package/dist/platform/scheduler.d.ts.map +1 -0
  209. package/dist/platform/scheduler.js +46 -0
  210. package/dist/platform/scheduler.js.map +1 -0
  211. package/dist/platform/session-log.d.ts +36 -0
  212. package/dist/platform/session-log.d.ts.map +1 -0
  213. package/dist/platform/session-log.js +12 -0
  214. package/dist/platform/session-log.js.map +1 -0
  215. package/dist/platform/shell.d.ts +83 -0
  216. package/dist/platform/shell.d.ts.map +1 -0
  217. package/dist/platform/shell.js +13 -0
  218. package/dist/platform/shell.js.map +1 -0
  219. package/dist/plugins/agent-status/plugin.d.ts.map +1 -1
  220. package/dist/plugins/agent-status/plugin.js +1 -0
  221. package/dist/plugins/agent-status/plugin.js.map +1 -1
  222. package/dist/plugins/agents/plugin.d.ts.map +1 -1
  223. package/dist/plugins/agents/plugin.js +129 -62
  224. package/dist/plugins/agents/plugin.js.map +1 -1
  225. package/dist/plugins/filesystem/listing.d.ts +3 -0
  226. package/dist/plugins/filesystem/listing.d.ts.map +1 -1
  227. package/dist/plugins/filesystem/listing.js +66 -10
  228. package/dist/plugins/filesystem/listing.js.map +1 -1
  229. package/dist/plugins/filesystem/plugin.d.ts.map +1 -1
  230. package/dist/plugins/filesystem/plugin.js +8 -6
  231. package/dist/plugins/filesystem/plugin.js.map +1 -1
  232. package/dist/plugins/git-status/index.d.ts +1 -0
  233. package/dist/plugins/git-status/index.d.ts.map +1 -1
  234. package/dist/plugins/git-status/plugin.d.ts +38 -7
  235. package/dist/plugins/git-status/plugin.d.ts.map +1 -1
  236. package/dist/plugins/git-status/plugin.js +169 -64
  237. package/dist/plugins/git-status/plugin.js.map +1 -1
  238. package/dist/plugins/llm-debug/plugin.d.ts.map +1 -1
  239. package/dist/plugins/llm-debug/plugin.js +1 -0
  240. package/dist/plugins/llm-debug/plugin.js.map +1 -1
  241. package/dist/plugins/logs/plugin.d.ts +1 -4
  242. package/dist/plugins/logs/plugin.d.ts.map +1 -1
  243. package/dist/plugins/logs/plugin.js +7 -0
  244. package/dist/plugins/logs/plugin.js.map +1 -1
  245. package/dist/plugins/mailbox/helpers.d.ts +2 -2
  246. package/dist/plugins/mailbox/helpers.js +1 -1
  247. package/dist/plugins/mailbox/plugin.d.ts.map +1 -1
  248. package/dist/plugins/mailbox/plugin.js +38 -43
  249. package/dist/plugins/mailbox/plugin.js.map +1 -1
  250. package/dist/plugins/mailbox/query.d.ts +7 -2
  251. package/dist/plugins/mailbox/query.d.ts.map +1 -1
  252. package/dist/plugins/mailbox/query.js +14 -7
  253. package/dist/plugins/mailbox/query.js.map +1 -1
  254. package/dist/plugins/mailbox/state.d.ts +5 -4
  255. package/dist/plugins/mailbox/state.d.ts.map +1 -1
  256. package/dist/plugins/mailbox/state.js +6 -5
  257. package/dist/plugins/mailbox/state.js.map +1 -1
  258. package/dist/plugins/resources/filename.d.ts +4 -0
  259. package/dist/plugins/resources/filename.d.ts.map +1 -0
  260. package/dist/plugins/resources/filename.js +18 -0
  261. package/dist/plugins/resources/filename.js.map +1 -0
  262. package/dist/plugins/resources/plugin.d.ts +3 -0
  263. package/dist/plugins/resources/plugin.d.ts.map +1 -1
  264. package/dist/plugins/resources/plugin.js +97 -60
  265. package/dist/plugins/resources/plugin.js.map +1 -1
  266. package/dist/plugins/resources/state.d.ts +1 -1
  267. package/dist/plugins/resources/state.js +1 -1
  268. package/dist/plugins/result-eviction/plugin.d.ts.map +1 -1
  269. package/dist/plugins/result-eviction/plugin.js +6 -1
  270. package/dist/plugins/result-eviction/plugin.js.map +1 -1
  271. package/dist/plugins/services/plugin.d.ts +4 -1
  272. package/dist/plugins/services/plugin.d.ts.map +1 -1
  273. package/dist/plugins/services/plugin.js +251 -100
  274. package/dist/plugins/services/plugin.js.map +1 -1
  275. package/dist/plugins/services/prompt.d.ts.map +1 -1
  276. package/dist/plugins/services/prompt.js +1 -4
  277. package/dist/plugins/services/prompt.js.map +1 -1
  278. package/dist/plugins/services/schema.d.ts +15 -5
  279. package/dist/plugins/services/schema.d.ts.map +1 -1
  280. package/dist/plugins/services/service.d.ts +100 -18
  281. package/dist/plugins/services/service.d.ts.map +1 -1
  282. package/dist/plugins/services/service.js +680 -230
  283. package/dist/plugins/services/service.js.map +1 -1
  284. package/dist/plugins/session-lifecycle/plugin.d.ts +21 -1
  285. package/dist/plugins/session-lifecycle/plugin.d.ts.map +1 -1
  286. package/dist/plugins/session-lifecycle/plugin.js +53 -40
  287. package/dist/plugins/session-lifecycle/plugin.js.map +1 -1
  288. package/dist/plugins/session-state/plugin.d.ts +21 -13
  289. package/dist/plugins/session-state/plugin.d.ts.map +1 -1
  290. package/dist/plugins/session-state/plugin.js +214 -79
  291. package/dist/plugins/session-state/plugin.js.map +1 -1
  292. package/dist/plugins/session-stats/plugin.d.ts.map +1 -1
  293. package/dist/plugins/session-stats/plugin.js +1 -0
  294. package/dist/plugins/session-stats/plugin.js.map +1 -1
  295. package/dist/plugins/shell/executor.d.ts +17 -15
  296. package/dist/plugins/shell/executor.d.ts.map +1 -1
  297. package/dist/plugins/shell/executor.js +130 -195
  298. package/dist/plugins/shell/executor.js.map +1 -1
  299. package/dist/plugins/shell/index.d.ts +2 -2
  300. package/dist/plugins/shell/index.d.ts.map +1 -1
  301. package/dist/plugins/shell/index.js +2 -2
  302. package/dist/plugins/shell/index.js.map +1 -1
  303. package/dist/plugins/shell/plugin.d.ts +5 -4
  304. package/dist/plugins/shell/plugin.d.ts.map +1 -1
  305. package/dist/plugins/shell/plugin.js +4 -8
  306. package/dist/plugins/shell/plugin.js.map +1 -1
  307. package/dist/plugins/skills/discovery.d.ts.map +1 -1
  308. package/dist/plugins/skills/discovery.js +10 -8
  309. package/dist/plugins/skills/discovery.js.map +1 -1
  310. package/dist/plugins/skills/index.d.ts +1 -1
  311. package/dist/plugins/skills/index.d.ts.map +1 -1
  312. package/dist/plugins/skills/plugin.d.ts +1 -1
  313. package/dist/plugins/skills/plugin.d.ts.map +1 -1
  314. package/dist/plugins/skills/plugin.js +23 -30
  315. package/dist/plugins/skills/plugin.js.map +1 -1
  316. package/dist/plugins/skills/prompts.d.ts +3 -3
  317. package/dist/plugins/skills/prompts.d.ts.map +1 -1
  318. package/dist/plugins/skills/prompts.js.map +1 -1
  319. package/dist/plugins/skills/schema.d.ts +4 -2
  320. package/dist/plugins/skills/schema.d.ts.map +1 -1
  321. package/dist/plugins/todo/schema.d.ts +1 -1
  322. package/dist/plugins/uploads/plugin.d.ts +11 -4
  323. package/dist/plugins/uploads/plugin.d.ts.map +1 -1
  324. package/dist/plugins/uploads/plugin.js +891 -225
  325. package/dist/plugins/uploads/plugin.js.map +1 -1
  326. package/dist/plugins/uploads/preprocessor.d.ts +14 -0
  327. package/dist/plugins/uploads/preprocessor.d.ts.map +1 -1
  328. package/dist/plugins/uploads/preprocessor.js +11 -0
  329. package/dist/plugins/uploads/preprocessor.js.map +1 -1
  330. package/dist/plugins/uploads/preprocessors/image-classifier.d.ts +1 -1
  331. package/dist/plugins/uploads/preprocessors/image-classifier.d.ts.map +1 -1
  332. package/dist/plugins/uploads/preprocessors/image-classifier.js +51 -26
  333. package/dist/plugins/uploads/preprocessors/image-classifier.js.map +1 -1
  334. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.d.ts +2 -2
  335. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.d.ts.map +1 -1
  336. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js +41 -16
  337. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js.map +1 -1
  338. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.d.ts +1 -1
  339. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.d.ts.map +1 -1
  340. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.js +29 -14
  341. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.js.map +1 -1
  342. package/dist/plugins/uploads/preprocessors/zip-preprocessor.d.ts +1 -1
  343. package/dist/plugins/uploads/preprocessors/zip-preprocessor.d.ts.map +1 -1
  344. package/dist/plugins/uploads/preprocessors/zip-preprocessor.js +62 -34
  345. package/dist/plugins/uploads/preprocessors/zip-preprocessor.js.map +1 -1
  346. package/dist/plugins/uploads/schema.d.ts +25 -2
  347. package/dist/plugins/uploads/schema.d.ts.map +1 -1
  348. package/dist/plugins/uploads/schema.js +24 -3
  349. package/dist/plugins/uploads/schema.js.map +1 -1
  350. package/dist/plugins/uploads/state.d.ts +13 -1
  351. package/dist/plugins/uploads/state.d.ts.map +1 -1
  352. package/dist/plugins/uploads/state.js +4 -1
  353. package/dist/plugins/uploads/state.js.map +1 -1
  354. package/dist/plugins/user-chat/plugin.d.ts +12 -5
  355. package/dist/plugins/user-chat/plugin.d.ts.map +1 -1
  356. package/dist/plugins/user-chat/plugin.js +141 -32
  357. package/dist/plugins/user-chat/plugin.js.map +1 -1
  358. package/dist/plugins/workers/context.d.ts +35 -13
  359. package/dist/plugins/workers/context.d.ts.map +1 -1
  360. package/dist/plugins/workers/context.js +82 -32
  361. package/dist/plugins/workers/context.js.map +1 -1
  362. package/dist/plugins/workers/definition.d.ts +7 -0
  363. package/dist/plugins/workers/definition.d.ts.map +1 -1
  364. package/dist/plugins/workers/definition.js.map +1 -1
  365. package/dist/plugins/workers/index.d.ts +4 -4
  366. package/dist/plugins/workers/index.d.ts.map +1 -1
  367. package/dist/plugins/workers/index.js +2 -2
  368. package/dist/plugins/workers/index.js.map +1 -1
  369. package/dist/plugins/workers/plugin.d.ts +10 -57
  370. package/dist/plugins/workers/plugin.d.ts.map +1 -1
  371. package/dist/plugins/workers/plugin.js +385 -123
  372. package/dist/plugins/workers/plugin.js.map +1 -1
  373. package/dist/plugins/workers/state.d.ts +69 -0
  374. package/dist/plugins/workers/state.d.ts.map +1 -0
  375. package/dist/plugins/workers/state.js +52 -0
  376. package/dist/plugins/workers/state.js.map +1 -0
  377. package/dist/plugins/workers/worker.d.ts +15 -4
  378. package/dist/plugins/workers/worker.d.ts.map +1 -1
  379. package/dist/testing/conformance.d.ts +106 -0
  380. package/dist/testing/conformance.d.ts.map +1 -0
  381. package/dist/testing/conformance.js +1463 -0
  382. package/dist/testing/conformance.js.map +1 -0
  383. package/dist/testing/node-platform.d.ts.map +1 -1
  384. package/dist/testing/node-platform.js +5 -0
  385. package/dist/testing/node-platform.js.map +1 -1
  386. package/dist/testing/test-harness.d.ts +11 -1
  387. package/dist/testing/test-harness.d.ts.map +1 -1
  388. package/dist/testing/test-harness.js +17 -37
  389. package/dist/testing/test-harness.js.map +1 -1
  390. package/dist/testing/wait-helpers.d.ts.map +1 -1
  391. package/dist/testing/wait-helpers.js +1 -3
  392. package/dist/testing/wait-helpers.js.map +1 -1
  393. package/dist/transport/adapter/client-adapter.d.ts +6 -0
  394. package/dist/transport/adapter/client-adapter.d.ts.map +1 -1
  395. package/dist/transport/adapter/client-adapter.js +50 -3
  396. package/dist/transport/adapter/client-adapter.js.map +1 -1
  397. package/dist/transport/adapter/heartbeat.d.ts +16 -0
  398. package/dist/transport/adapter/heartbeat.d.ts.map +1 -0
  399. package/dist/transport/adapter/heartbeat.js +41 -0
  400. package/dist/transport/adapter/heartbeat.js.map +1 -0
  401. package/dist/transport/adapter/server-adapter.d.ts.map +1 -1
  402. package/dist/transport/adapter/server-adapter.js +6 -0
  403. package/dist/transport/adapter/server-adapter.js.map +1 -1
  404. package/dist/transport/http/app.d.ts +3 -30
  405. package/dist/transport/http/app.d.ts.map +1 -1
  406. package/dist/transport/http/app.js +3 -7
  407. package/dist/transport/http/app.js.map +1 -1
  408. package/dist/transport/http/context.d.ts +40 -0
  409. package/dist/transport/http/context.d.ts.map +1 -0
  410. package/dist/transport/http/context.js +17 -0
  411. package/dist/transport/http/context.js.map +1 -0
  412. package/dist/transport/http/fetch-guard.d.ts +49 -0
  413. package/dist/transport/http/fetch-guard.d.ts.map +1 -0
  414. package/dist/transport/http/fetch-guard.js +312 -0
  415. package/dist/transport/http/fetch-guard.js.map +1 -0
  416. package/dist/transport/http/index.d.ts +1 -1
  417. package/dist/transport/http/index.d.ts.map +1 -1
  418. package/dist/transport/http/middleware/bearer-auth.d.ts +1 -1
  419. package/dist/transport/http/middleware/bearer-auth.d.ts.map +1 -1
  420. package/dist/transport/http/middleware/error-handler.d.ts +2 -2
  421. package/dist/transport/http/middleware/error-handler.d.ts.map +1 -1
  422. package/dist/transport/http/path-containment.d.ts +20 -0
  423. package/dist/transport/http/path-containment.d.ts.map +1 -0
  424. package/dist/transport/http/path-containment.js +31 -0
  425. package/dist/transport/http/path-containment.js.map +1 -0
  426. package/dist/transport/http/responses.d.ts +30 -0
  427. package/dist/transport/http/responses.d.ts.map +1 -0
  428. package/dist/transport/http/responses.js +5 -0
  429. package/dist/transport/http/responses.js.map +1 -0
  430. package/dist/transport/http/routes/files.d.ts +1 -1
  431. package/dist/transport/http/routes/files.d.ts.map +1 -1
  432. package/dist/transport/http/routes/files.js +54 -155
  433. package/dist/transport/http/routes/files.js.map +1 -1
  434. package/dist/transport/http/routes/resources.d.ts +1 -1
  435. package/dist/transport/http/routes/resources.d.ts.map +1 -1
  436. package/dist/transport/http/routes/resources.js +92 -57
  437. package/dist/transport/http/routes/resources.js.map +1 -1
  438. package/dist/transport/http/routes/rpc.d.ts +6 -1
  439. package/dist/transport/http/routes/rpc.d.ts.map +1 -1
  440. package/dist/transport/http/routes/rpc.js +51 -21
  441. package/dist/transport/http/routes/rpc.js.map +1 -1
  442. package/dist/transport/http/routes/upload.d.ts +1 -1
  443. package/dist/transport/http/routes/upload.d.ts.map +1 -1
  444. package/dist/transport/http/routes/upload.js +256 -169
  445. package/dist/transport/http/routes/upload.js.map +1 -1
  446. package/dist/user-config.d.ts +34 -7
  447. package/dist/user-config.d.ts.map +1 -1
  448. package/dist/user-config.js +71 -0
  449. package/dist/user-config.js.map +1 -1
  450. package/package.json +17 -7
  451. package/src/bootstrap.ts +119 -35
  452. package/src/bun-platform/fs.ts +1 -0
  453. package/src/bun-platform/index.ts +18 -1
  454. package/src/bun-platform/server-lifecycle.ts +218 -0
  455. package/src/bun-platform/shell.ts +362 -0
  456. package/src/config.ts +130 -0
  457. package/src/core/agents/agent.ts +210 -92
  458. package/src/core/agents/config.ts +8 -0
  459. package/src/core/agents/retry.ts +16 -17
  460. package/src/core/agents/state.ts +2 -0
  461. package/src/core/events/base-event-store.ts +24 -16
  462. package/src/core/events/file.ts +198 -22
  463. package/src/core/file-store/containment.ts +75 -0
  464. package/src/core/file-store/file-store.ts +106 -25
  465. package/src/core/file-store/types.ts +14 -1
  466. package/src/core/image/image-processor.ts +3 -1
  467. package/src/core/image/types.ts +2 -0
  468. package/src/core/image/vips-resizer.ts +102 -37
  469. package/src/core/llm/anthropic.ts +63 -79
  470. package/src/core/llm/logger.ts +175 -37
  471. package/src/core/llm/openrouter.ts +57 -72
  472. package/src/core/llm/provider-request.ts +40 -0
  473. package/src/core/llm/provider.ts +28 -0
  474. package/src/core/plugins/plugin-builder.ts +106 -14
  475. package/src/core/preset/preset-builder.ts +12 -22
  476. package/src/core/sessions/context.ts +18 -0
  477. package/src/core/sessions/runtime-activity.ts +78 -0
  478. package/src/core/sessions/schema.ts +29 -3
  479. package/src/core/sessions/session-manager.ts +560 -140
  480. package/src/core/sessions/session-store.ts +38 -0
  481. package/src/core/sessions/session.ts +187 -47
  482. package/src/core/sessions/state.ts +11 -0
  483. package/src/core/system.ts +15 -0
  484. package/src/core/wake-key.ts +65 -0
  485. package/src/index.ts +32 -12
  486. package/src/lib/archive/archive-inspection.fixtures.ts +138 -0
  487. package/src/lib/archive/archive-inspection.ts +359 -0
  488. package/src/lib/archive/index.ts +17 -0
  489. package/src/lib/logger/console.ts +7 -57
  490. package/src/lib/logger/file.ts +28 -50
  491. package/src/lib/logger/index.ts +3 -1
  492. package/src/lib/logger/jsonl.ts +36 -0
  493. package/src/lib/logger/logger.ts +48 -0
  494. package/src/lib/logger/session-log.ts +42 -0
  495. package/src/lib/utils/concurrency.ts +37 -8
  496. package/src/lib/utils/fs-batch.ts +49 -0
  497. package/src/lib/utils/result.ts +7 -31
  498. package/src/lib/utils/sleep.ts +23 -0
  499. package/src/platform/fs-revision.ts +21 -0
  500. package/src/platform/fs.ts +109 -1
  501. package/src/platform/git.ts +67 -0
  502. package/src/platform/index.ts +51 -1
  503. package/src/platform/llm-call-log.ts +86 -0
  504. package/src/platform/scheduler.ts +71 -0
  505. package/src/platform/session-log.ts +39 -0
  506. package/src/platform/shell.ts +89 -0
  507. package/src/plugins/agent-status/plugin.ts +1 -0
  508. package/src/plugins/agents/plugin.ts +134 -81
  509. package/src/plugins/filesystem/listing.ts +70 -12
  510. package/src/plugins/filesystem/plugin.ts +8 -6
  511. package/src/plugins/git-status/index.ts +1 -0
  512. package/src/plugins/git-status/plugin.ts +211 -77
  513. package/src/plugins/llm-debug/plugin.ts +1 -0
  514. package/src/plugins/logs/plugin.ts +9 -0
  515. package/src/plugins/mailbox/plugin.ts +46 -64
  516. package/src/plugins/mailbox/query.ts +15 -7
  517. package/src/plugins/mailbox/state.ts +1 -0
  518. package/src/plugins/resources/filename.ts +19 -0
  519. package/src/plugins/resources/plugin.ts +111 -59
  520. package/src/plugins/result-eviction/plugin.ts +6 -1
  521. package/src/plugins/services/plugin.ts +254 -98
  522. package/src/plugins/services/prompt.ts +1 -6
  523. package/src/plugins/services/schema.ts +17 -3
  524. package/src/plugins/services/service.ts +702 -252
  525. package/src/plugins/session-lifecycle/plugin.ts +56 -41
  526. package/src/plugins/session-state/plugin.ts +242 -88
  527. package/src/plugins/session-stats/plugin.ts +1 -0
  528. package/src/plugins/shell/executor.ts +144 -226
  529. package/src/plugins/shell/index.ts +1 -4
  530. package/src/plugins/shell/plugin.ts +7 -9
  531. package/src/plugins/skills/discovery.ts +10 -8
  532. package/src/plugins/skills/index.ts +1 -1
  533. package/src/plugins/skills/plugin.ts +19 -27
  534. package/src/plugins/skills/prompts.ts +3 -3
  535. package/src/plugins/skills/schema.ts +5 -2
  536. package/src/plugins/uploads/plugin.ts +991 -273
  537. package/src/plugins/uploads/preprocessor.ts +25 -0
  538. package/src/plugins/uploads/preprocessors/image-classifier.ts +56 -25
  539. package/src/plugins/uploads/preprocessors/markitdown-preprocessor.ts +41 -15
  540. package/src/plugins/uploads/preprocessors/pdf-preprocessor.ts +32 -16
  541. package/src/plugins/uploads/preprocessors/zip-preprocessor.ts +67 -38
  542. package/src/plugins/uploads/schema.ts +30 -3
  543. package/src/plugins/uploads/state.ts +12 -0
  544. package/src/plugins/user-chat/plugin.ts +196 -40
  545. package/src/plugins/workers/context.ts +102 -39
  546. package/src/plugins/workers/definition.ts +7 -0
  547. package/src/plugins/workers/index.ts +4 -4
  548. package/src/plugins/workers/plugin.ts +461 -151
  549. package/src/plugins/workers/state.ts +64 -0
  550. package/src/plugins/workers/worker.ts +15 -4
  551. package/src/testing/conformance.ts +1751 -0
  552. package/src/testing/node-platform.ts +5 -0
  553. package/src/testing/test-harness.ts +21 -38
  554. package/src/testing/wait-helpers.ts +1 -4
  555. package/src/transport/adapter/client-adapter.ts +60 -3
  556. package/src/transport/adapter/heartbeat.ts +50 -0
  557. package/src/transport/adapter/server-adapter.ts +6 -0
  558. package/src/transport/http/app.ts +7 -35
  559. package/src/transport/http/context.ts +46 -0
  560. package/src/transport/http/fetch-guard.ts +318 -0
  561. package/src/transport/http/index.ts +1 -1
  562. package/src/transport/http/middleware/bearer-auth.ts +1 -1
  563. package/src/transport/http/middleware/error-handler.ts +1 -1
  564. package/src/transport/http/path-containment.ts +44 -0
  565. package/src/transport/http/responses.ts +20 -0
  566. package/src/transport/http/routes/files.ts +69 -159
  567. package/src/transport/http/routes/resources.ts +124 -93
  568. package/src/transport/http/routes/rpc.ts +63 -26
  569. package/src/transport/http/routes/upload.ts +327 -258
  570. package/src/user-config.ts +93 -7
  571. package/dist/config.test.d.ts +0 -2
  572. package/dist/config.test.d.ts.map +0 -1
  573. package/dist/config.test.js +0 -155
  574. package/dist/config.test.js.map +0 -1
  575. package/dist/core/agent-loop.integration.test.d.ts +0 -2
  576. package/dist/core/agent-loop.integration.test.d.ts.map +0 -1
  577. package/dist/core/agent-loop.integration.test.js +0 -414
  578. package/dist/core/agent-loop.integration.test.js.map +0 -1
  579. package/dist/core/agents/agent-config.test.d.ts +0 -2
  580. package/dist/core/agents/agent-config.test.d.ts.map +0 -1
  581. package/dist/core/agents/agent-config.test.js +0 -194
  582. package/dist/core/agents/agent-config.test.js.map +0 -1
  583. package/dist/core/agents/agent-shutdown.test.d.ts +0 -6
  584. package/dist/core/agents/agent-shutdown.test.d.ts.map +0 -1
  585. package/dist/core/agents/agent-shutdown.test.js +0 -180
  586. package/dist/core/agents/agent-shutdown.test.js.map +0 -1
  587. package/dist/core/agents/agent.test.d.ts +0 -2
  588. package/dist/core/agents/agent.test.d.ts.map +0 -1
  589. package/dist/core/agents/agent.test.js +0 -313
  590. package/dist/core/agents/agent.test.js.map +0 -1
  591. package/dist/core/agents/communicator.d.ts +0 -3
  592. package/dist/core/agents/communicator.d.ts.map +0 -1
  593. package/dist/core/agents/communicator.js +0 -13
  594. package/dist/core/agents/communicator.js.map +0 -1
  595. package/dist/core/agents/handler-events.test.d.ts +0 -5
  596. package/dist/core/agents/handler-events.test.d.ts.map +0 -1
  597. package/dist/core/agents/handler-events.test.js +0 -115
  598. package/dist/core/agents/handler-events.test.js.map +0 -1
  599. package/dist/core/agents/response-sanitizer.test.d.ts +0 -2
  600. package/dist/core/agents/response-sanitizer.test.d.ts.map +0 -1
  601. package/dist/core/agents/response-sanitizer.test.js +0 -101
  602. package/dist/core/agents/response-sanitizer.test.js.map +0 -1
  603. package/dist/core/error-recovery.integration.test.d.ts +0 -2
  604. package/dist/core/error-recovery.integration.test.d.ts.map +0 -1
  605. package/dist/core/error-recovery.integration.test.js +0 -288
  606. package/dist/core/error-recovery.integration.test.js.map +0 -1
  607. package/dist/core/event-sourcing.integration.test.d.ts +0 -2
  608. package/dist/core/event-sourcing.integration.test.d.ts.map +0 -1
  609. package/dist/core/event-sourcing.integration.test.js +0 -154
  610. package/dist/core/event-sourcing.integration.test.js.map +0 -1
  611. package/dist/core/events/file.test.d.ts +0 -2
  612. package/dist/core/events/file.test.d.ts.map +0 -1
  613. package/dist/core/events/file.test.js +0 -284
  614. package/dist/core/events/file.test.js.map +0 -1
  615. package/dist/core/events/memory.test.d.ts +0 -2
  616. package/dist/core/events/memory.test.d.ts.map +0 -1
  617. package/dist/core/events/memory.test.js +0 -502
  618. package/dist/core/events/memory.test.js.map +0 -1
  619. package/dist/core/image/image-processor.test.d.ts +0 -2
  620. package/dist/core/image/image-processor.test.d.ts.map +0 -1
  621. package/dist/core/image/image-processor.test.js +0 -171
  622. package/dist/core/image/image-processor.test.js.map +0 -1
  623. package/dist/core/image/vips-resizer.test.d.ts +0 -2
  624. package/dist/core/image/vips-resizer.test.d.ts.map +0 -1
  625. package/dist/core/image/vips-resizer.test.js +0 -336
  626. package/dist/core/image/vips-resizer.test.js.map +0 -1
  627. package/dist/core/llm/anthropic.test.d.ts +0 -2
  628. package/dist/core/llm/anthropic.test.d.ts.map +0 -1
  629. package/dist/core/llm/anthropic.test.js +0 -464
  630. package/dist/core/llm/anthropic.test.js.map +0 -1
  631. package/dist/core/llm/cache-breakpoints.test.d.ts +0 -2
  632. package/dist/core/llm/cache-breakpoints.test.d.ts.map +0 -1
  633. package/dist/core/llm/cache-breakpoints.test.js +0 -69
  634. package/dist/core/llm/cache-breakpoints.test.js.map +0 -1
  635. package/dist/core/llm/cache-live.test.d.ts +0 -16
  636. package/dist/core/llm/cache-live.test.d.ts.map +0 -1
  637. package/dist/core/llm/cache-live.test.js +0 -137
  638. package/dist/core/llm/cache-live.test.js.map +0 -1
  639. package/dist/core/llm/logger.test.d.ts +0 -7
  640. package/dist/core/llm/logger.test.d.ts.map +0 -1
  641. package/dist/core/llm/logger.test.js +0 -228
  642. package/dist/core/llm/logger.test.js.map +0 -1
  643. package/dist/core/llm/message-sanitization.test.d.ts +0 -2
  644. package/dist/core/llm/message-sanitization.test.d.ts.map +0 -1
  645. package/dist/core/llm/message-sanitization.test.js +0 -181
  646. package/dist/core/llm/message-sanitization.test.js.map +0 -1
  647. package/dist/core/llm/mock.test.d.ts +0 -2
  648. package/dist/core/llm/mock.test.d.ts.map +0 -1
  649. package/dist/core/llm/mock.test.js +0 -318
  650. package/dist/core/llm/mock.test.js.map +0 -1
  651. package/dist/core/llm/model-shortlist-live.test.d.ts +0 -35
  652. package/dist/core/llm/model-shortlist-live.test.d.ts.map +0 -1
  653. package/dist/core/llm/model-shortlist-live.test.js +0 -452
  654. package/dist/core/llm/model-shortlist-live.test.js.map +0 -1
  655. package/dist/core/llm/openrouter-mapping.test.d.ts +0 -2
  656. package/dist/core/llm/openrouter-mapping.test.d.ts.map +0 -1
  657. package/dist/core/llm/openrouter-mapping.test.js +0 -190
  658. package/dist/core/llm/openrouter-mapping.test.js.map +0 -1
  659. package/dist/core/llm/openrouter.test.d.ts +0 -2
  660. package/dist/core/llm/openrouter.test.d.ts.map +0 -1
  661. package/dist/core/llm/openrouter.test.js +0 -377
  662. package/dist/core/llm/openrouter.test.js.map +0 -1
  663. package/dist/core/llm/provider-integration.test.d.ts +0 -12
  664. package/dist/core/llm/provider-integration.test.d.ts.map +0 -1
  665. package/dist/core/llm/provider-integration.test.js +0 -350
  666. package/dist/core/llm/provider-integration.test.js.map +0 -1
  667. package/dist/core/llm/reasoning-details.test.d.ts +0 -2
  668. package/dist/core/llm/reasoning-details.test.d.ts.map +0 -1
  669. package/dist/core/llm/reasoning-details.test.js +0 -144
  670. package/dist/core/llm/reasoning-details.test.js.map +0 -1
  671. package/dist/core/llm/routing-provider.test.d.ts +0 -2
  672. package/dist/core/llm/routing-provider.test.d.ts.map +0 -1
  673. package/dist/core/llm/routing-provider.test.js +0 -94
  674. package/dist/core/llm/routing-provider.test.js.map +0 -1
  675. package/dist/core/llm/snapshot-middleware.test.d.ts +0 -2
  676. package/dist/core/llm/snapshot-middleware.test.d.ts.map +0 -1
  677. package/dist/core/llm/snapshot-middleware.test.js +0 -144
  678. package/dist/core/llm/snapshot-middleware.test.js.map +0 -1
  679. package/dist/core/llm/thinking-blocks.test.d.ts +0 -2
  680. package/dist/core/llm/thinking-blocks.test.d.ts.map +0 -1
  681. package/dist/core/llm/thinking-blocks.test.js +0 -291
  682. package/dist/core/llm/thinking-blocks.test.js.map +0 -1
  683. package/dist/core/multi-agent.integration.test.d.ts +0 -2
  684. package/dist/core/multi-agent.integration.test.d.ts.map +0 -1
  685. package/dist/core/multi-agent.integration.test.js +0 -298
  686. package/dist/core/multi-agent.integration.test.js.map +0 -1
  687. package/dist/core/plugin-hooks.integration.test.d.ts +0 -2
  688. package/dist/core/plugin-hooks.integration.test.d.ts.map +0 -1
  689. package/dist/core/plugin-hooks.integration.test.js +0 -458
  690. package/dist/core/plugin-hooks.integration.test.js.map +0 -1
  691. package/dist/core/reasoning-round-trip.integration.test.d.ts +0 -2
  692. package/dist/core/reasoning-round-trip.integration.test.d.ts.map +0 -1
  693. package/dist/core/reasoning-round-trip.integration.test.js +0 -150
  694. package/dist/core/reasoning-round-trip.integration.test.js.map +0 -1
  695. package/dist/core/session-lifecycle.integration.test.d.ts +0 -2
  696. package/dist/core/session-lifecycle.integration.test.d.ts.map +0 -1
  697. package/dist/core/session-lifecycle.integration.test.js +0 -159
  698. package/dist/core/session-lifecycle.integration.test.js.map +0 -1
  699. package/dist/core/sessions/fork-utils.test.d.ts +0 -2
  700. package/dist/core/sessions/fork-utils.test.d.ts.map +0 -1
  701. package/dist/core/sessions/fork-utils.test.js +0 -129
  702. package/dist/core/sessions/fork-utils.test.js.map +0 -1
  703. package/dist/core/sessions/session-overrides.integration.test.d.ts +0 -2
  704. package/dist/core/sessions/session-overrides.integration.test.d.ts.map +0 -1
  705. package/dist/core/sessions/session-overrides.integration.test.js +0 -154
  706. package/dist/core/sessions/session-overrides.integration.test.js.map +0 -1
  707. package/dist/core/sessions/session.test.d.ts +0 -2
  708. package/dist/core/sessions/session.test.d.ts.map +0 -1
  709. package/dist/core/sessions/session.test.js +0 -1100
  710. package/dist/core/sessions/session.test.js.map +0 -1
  711. package/dist/core/tools/executor.test.d.ts +0 -2
  712. package/dist/core/tools/executor.test.d.ts.map +0 -1
  713. package/dist/core/tools/executor.test.js +0 -144
  714. package/dist/core/tools/executor.test.js.map +0 -1
  715. package/dist/lib/logger/console.test.d.ts +0 -2
  716. package/dist/lib/logger/console.test.d.ts.map +0 -1
  717. package/dist/lib/logger/console.test.js +0 -258
  718. package/dist/lib/logger/console.test.js.map +0 -1
  719. package/dist/lib/never.d.ts +0 -2
  720. package/dist/lib/never.d.ts.map +0 -1
  721. package/dist/lib/never.js +0 -4
  722. package/dist/lib/never.js.map +0 -1
  723. package/dist/lib/utils/concurrency.test.d.ts +0 -2
  724. package/dist/lib/utils/concurrency.test.d.ts.map +0 -1
  725. package/dist/lib/utils/concurrency.test.js +0 -135
  726. package/dist/lib/utils/concurrency.test.js.map +0 -1
  727. package/dist/plugins/agent-status/agent-status.test.d.ts +0 -2
  728. package/dist/plugins/agent-status/agent-status.test.d.ts.map +0 -1
  729. package/dist/plugins/agent-status/agent-status.test.js +0 -136
  730. package/dist/plugins/agent-status/agent-status.test.js.map +0 -1
  731. package/dist/plugins/agents/agents.integration.test.d.ts +0 -2
  732. package/dist/plugins/agents/agents.integration.test.d.ts.map +0 -1
  733. package/dist/plugins/agents/agents.integration.test.js +0 -830
  734. package/dist/plugins/agents/agents.integration.test.js.map +0 -1
  735. package/dist/plugins/agents/supervision.integration.test.d.ts +0 -2
  736. package/dist/plugins/agents/supervision.integration.test.d.ts.map +0 -1
  737. package/dist/plugins/agents/supervision.integration.test.js +0 -215
  738. package/dist/plugins/agents/supervision.integration.test.js.map +0 -1
  739. package/dist/plugins/context-compact/compaction-live.test.d.ts +0 -17
  740. package/dist/plugins/context-compact/compaction-live.test.d.ts.map +0 -1
  741. package/dist/plugins/context-compact/compaction-live.test.js +0 -177
  742. package/dist/plugins/context-compact/compaction-live.test.js.map +0 -1
  743. package/dist/plugins/context-compact/context-compact.integration.test.d.ts +0 -2
  744. package/dist/plugins/context-compact/context-compact.integration.test.d.ts.map +0 -1
  745. package/dist/plugins/context-compact/context-compact.integration.test.js +0 -364
  746. package/dist/plugins/context-compact/context-compact.integration.test.js.map +0 -1
  747. package/dist/plugins/context-compact/context-compactor.test.d.ts +0 -2
  748. package/dist/plugins/context-compact/context-compactor.test.d.ts.map +0 -1
  749. package/dist/plugins/context-compact/context-compactor.test.js +0 -858
  750. package/dist/plugins/context-compact/context-compactor.test.js.map +0 -1
  751. package/dist/plugins/context-compact/history-offloader.test.d.ts +0 -2
  752. package/dist/plugins/context-compact/history-offloader.test.d.ts.map +0 -1
  753. package/dist/plugins/context-compact/history-offloader.test.js +0 -77
  754. package/dist/plugins/context-compact/history-offloader.test.js.map +0 -1
  755. package/dist/plugins/filesystem/filesystem.integration.test.d.ts +0 -2
  756. package/dist/plugins/filesystem/filesystem.integration.test.d.ts.map +0 -1
  757. package/dist/plugins/filesystem/filesystem.integration.test.js +0 -447
  758. package/dist/plugins/filesystem/filesystem.integration.test.js.map +0 -1
  759. package/dist/plugins/filesystem/schema.d.ts +0 -7
  760. package/dist/plugins/filesystem/schema.d.ts.map +0 -1
  761. package/dist/plugins/filesystem/schema.js +0 -2
  762. package/dist/plugins/filesystem/schema.js.map +0 -1
  763. package/dist/plugins/limits-guard/limit-guard.test.d.ts +0 -2
  764. package/dist/plugins/limits-guard/limit-guard.test.d.ts.map +0 -1
  765. package/dist/plugins/limits-guard/limit-guard.test.js +0 -194
  766. package/dist/plugins/limits-guard/limit-guard.test.js.map +0 -1
  767. package/dist/plugins/limits-guard/limits-guard.integration.test.d.ts +0 -2
  768. package/dist/plugins/limits-guard/limits-guard.integration.test.d.ts.map +0 -1
  769. package/dist/plugins/limits-guard/limits-guard.integration.test.js +0 -887
  770. package/dist/plugins/limits-guard/limits-guard.integration.test.js.map +0 -1
  771. package/dist/plugins/llm-debug/llm-debug.integration.test.d.ts +0 -2
  772. package/dist/plugins/llm-debug/llm-debug.integration.test.d.ts.map +0 -1
  773. package/dist/plugins/llm-debug/llm-debug.integration.test.js +0 -157
  774. package/dist/plugins/llm-debug/llm-debug.integration.test.js.map +0 -1
  775. package/dist/plugins/mailbox/mailbox.integration.test.d.ts +0 -2
  776. package/dist/plugins/mailbox/mailbox.integration.test.d.ts.map +0 -1
  777. package/dist/plugins/mailbox/mailbox.integration.test.js +0 -678
  778. package/dist/plugins/mailbox/mailbox.integration.test.js.map +0 -1
  779. package/dist/plugins/resources/resources.integration.test.d.ts +0 -2
  780. package/dist/plugins/resources/resources.integration.test.d.ts.map +0 -1
  781. package/dist/plugins/resources/resources.integration.test.js +0 -62
  782. package/dist/plugins/resources/resources.integration.test.js.map +0 -1
  783. package/dist/plugins/result-eviction/result-eviction.integration.test.d.ts +0 -2
  784. package/dist/plugins/result-eviction/result-eviction.integration.test.d.ts.map +0 -1
  785. package/dist/plugins/result-eviction/result-eviction.integration.test.js +0 -294
  786. package/dist/plugins/result-eviction/result-eviction.integration.test.js.map +0 -1
  787. package/dist/plugins/services/pid-registry.test.d.ts +0 -2
  788. package/dist/plugins/services/pid-registry.test.d.ts.map +0 -1
  789. package/dist/plugins/services/pid-registry.test.js +0 -161
  790. package/dist/plugins/services/pid-registry.test.js.map +0 -1
  791. package/dist/plugins/services/services.integration.test.d.ts +0 -2
  792. package/dist/plugins/services/services.integration.test.d.ts.map +0 -1
  793. package/dist/plugins/services/services.integration.test.js +0 -1057
  794. package/dist/plugins/services/services.integration.test.js.map +0 -1
  795. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.d.ts +0 -2
  796. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.d.ts.map +0 -1
  797. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js +0 -498
  798. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js.map +0 -1
  799. package/dist/plugins/session-stats/plugin.test.d.ts +0 -2
  800. package/dist/plugins/session-stats/plugin.test.d.ts.map +0 -1
  801. package/dist/plugins/session-stats/plugin.test.js +0 -145
  802. package/dist/plugins/session-stats/plugin.test.js.map +0 -1
  803. package/dist/plugins/shell/shell.integration.test.d.ts +0 -2
  804. package/dist/plugins/shell/shell.integration.test.d.ts.map +0 -1
  805. package/dist/plugins/shell/shell.integration.test.js +0 -234
  806. package/dist/plugins/shell/shell.integration.test.js.map +0 -1
  807. package/dist/plugins/shell/shell.test.d.ts +0 -2
  808. package/dist/plugins/shell/shell.test.d.ts.map +0 -1
  809. package/dist/plugins/shell/shell.test.js +0 -236
  810. package/dist/plugins/shell/shell.test.js.map +0 -1
  811. package/dist/plugins/skills/discovery.test.d.ts +0 -2
  812. package/dist/plugins/skills/discovery.test.d.ts.map +0 -1
  813. package/dist/plugins/skills/discovery.test.js +0 -312
  814. package/dist/plugins/skills/discovery.test.js.map +0 -1
  815. package/dist/plugins/skills/skills.integration.test.d.ts +0 -2
  816. package/dist/plugins/skills/skills.integration.test.d.ts.map +0 -1
  817. package/dist/plugins/skills/skills.integration.test.js +0 -475
  818. package/dist/plugins/skills/skills.integration.test.js.map +0 -1
  819. package/dist/plugins/todo/todo.integration.test.d.ts +0 -2
  820. package/dist/plugins/todo/todo.integration.test.d.ts.map +0 -1
  821. package/dist/plugins/todo/todo.integration.test.js +0 -605
  822. package/dist/plugins/todo/todo.integration.test.js.map +0 -1
  823. package/dist/plugins/uploads/preprocessors/image-classifier.test.d.ts +0 -2
  824. package/dist/plugins/uploads/preprocessors/image-classifier.test.d.ts.map +0 -1
  825. package/dist/plugins/uploads/preprocessors/image-classifier.test.js +0 -113
  826. package/dist/plugins/uploads/preprocessors/image-classifier.test.js.map +0 -1
  827. package/dist/plugins/uploads/uploads.integration.test.d.ts +0 -2
  828. package/dist/plugins/uploads/uploads.integration.test.d.ts.map +0 -1
  829. package/dist/plugins/uploads/uploads.integration.test.js +0 -639
  830. package/dist/plugins/uploads/uploads.integration.test.js.map +0 -1
  831. package/dist/plugins/user-chat/user-chat.integration.test.d.ts +0 -2
  832. package/dist/plugins/user-chat/user-chat.integration.test.d.ts.map +0 -1
  833. package/dist/plugins/user-chat/user-chat.integration.test.js +0 -754
  834. package/dist/plugins/user-chat/user-chat.integration.test.js.map +0 -1
  835. package/dist/plugins/workers/workers.integration.test.d.ts +0 -2
  836. package/dist/plugins/workers/workers.integration.test.d.ts.map +0 -1
  837. package/dist/plugins/workers/workers.integration.test.js +0 -629
  838. package/dist/plugins/workers/workers.integration.test.js.map +0 -1
  839. package/dist/prompts/macros.test.d.ts +0 -2
  840. package/dist/prompts/macros.test.d.ts.map +0 -1
  841. package/dist/prompts/macros.test.js +0 -80
  842. package/dist/prompts/macros.test.js.map +0 -1
  843. package/dist/testing/test-harness.test.d.ts +0 -2
  844. package/dist/testing/test-harness.test.d.ts.map +0 -1
  845. package/dist/testing/test-harness.test.js +0 -92
  846. package/dist/testing/test-harness.test.js.map +0 -1
  847. package/dist/transport/http/routes/rpc.integration.test.d.ts +0 -2
  848. package/dist/transport/http/routes/rpc.integration.test.d.ts.map +0 -1
  849. package/dist/transport/http/routes/rpc.integration.test.js +0 -189
  850. package/dist/transport/http/routes/rpc.integration.test.js.map +0 -1
  851. package/dist/transport/http/routes/rpc.test.d.ts +0 -2
  852. package/dist/transport/http/routes/rpc.test.d.ts.map +0 -1
  853. package/dist/transport/http/routes/rpc.test.js +0 -316
  854. package/dist/transport/http/routes/rpc.test.js.map +0 -1
  855. package/src/config.test.ts +0 -174
  856. package/src/core/agent-loop.integration.test.ts +0 -503
  857. package/src/core/agents/agent-config.test.ts +0 -240
  858. package/src/core/agents/agent-shutdown.test.ts +0 -236
  859. package/src/core/agents/agent.test.ts +0 -387
  860. package/src/core/agents/communicator.ts +0 -16
  861. package/src/core/agents/handler-events.test.ts +0 -167
  862. package/src/core/agents/response-sanitizer.test.ts +0 -137
  863. package/src/core/error-recovery.integration.test.ts +0 -343
  864. package/src/core/event-sourcing.integration.test.ts +0 -191
  865. package/src/core/events/file.test.ts +0 -436
  866. package/src/core/events/memory.test.ts +0 -741
  867. package/src/core/image/image-processor.test.ts +0 -218
  868. package/src/core/image/vips-resizer.test.ts +0 -388
  869. package/src/core/llm/anthropic.test.ts +0 -546
  870. package/src/core/llm/cache-breakpoints.test.ts +0 -85
  871. package/src/core/llm/cache-live.test.ts +0 -155
  872. package/src/core/llm/logger.test.ts +0 -270
  873. package/src/core/llm/message-sanitization.test.ts +0 -217
  874. package/src/core/llm/mock.test.ts +0 -402
  875. package/src/core/llm/model-shortlist-live.test.ts +0 -577
  876. package/src/core/llm/openrouter-mapping.test.ts +0 -234
  877. package/src/core/llm/openrouter.test.ts +0 -499
  878. package/src/core/llm/provider-integration.test.ts +0 -408
  879. package/src/core/llm/reasoning-details.test.ts +0 -177
  880. package/src/core/llm/routing-provider.test.ts +0 -113
  881. package/src/core/llm/snapshot-middleware.test.ts +0 -168
  882. package/src/core/llm/thinking-blocks.test.ts +0 -345
  883. package/src/core/multi-agent.integration.test.ts +0 -340
  884. package/src/core/plugin-hooks.integration.test.ts +0 -568
  885. package/src/core/reasoning-round-trip.integration.test.ts +0 -188
  886. package/src/core/session-lifecycle.integration.test.ts +0 -202
  887. package/src/core/sessions/fork-utils.test.ts +0 -158
  888. package/src/core/sessions/session-overrides.integration.test.ts +0 -210
  889. package/src/core/sessions/session.test.ts +0 -1736
  890. package/src/core/tools/executor.test.ts +0 -161
  891. package/src/lib/logger/console.test.ts +0 -348
  892. package/src/lib/never.ts +0 -3
  893. package/src/lib/utils/concurrency.test.ts +0 -169
  894. package/src/plugins/agent-status/agent-status.test.ts +0 -164
  895. package/src/plugins/agents/agents.integration.test.ts +0 -976
  896. package/src/plugins/agents/supervision.integration.test.ts +0 -249
  897. package/src/plugins/context-compact/compaction-live.test.ts +0 -221
  898. package/src/plugins/context-compact/context-compact.integration.test.ts +0 -418
  899. package/src/plugins/context-compact/context-compactor.test.ts +0 -1036
  900. package/src/plugins/context-compact/history-offloader.test.ts +0 -100
  901. package/src/plugins/filesystem/filesystem.integration.test.ts +0 -529
  902. package/src/plugins/filesystem/schema.ts +0 -6
  903. package/src/plugins/limits-guard/limit-guard.test.ts +0 -253
  904. package/src/plugins/limits-guard/limits-guard.integration.test.ts +0 -1012
  905. package/src/plugins/llm-debug/llm-debug.integration.test.ts +0 -192
  906. package/src/plugins/mailbox/mailbox.integration.test.ts +0 -794
  907. package/src/plugins/resources/resources.integration.test.ts +0 -68
  908. package/src/plugins/result-eviction/result-eviction.integration.test.ts +0 -332
  909. package/src/plugins/services/pid-registry.test.ts +0 -180
  910. package/src/plugins/services/services.integration.test.ts +0 -1223
  911. package/src/plugins/session-lifecycle/session-lifecycle.integration.test.ts +0 -639
  912. package/src/plugins/session-stats/plugin.test.ts +0 -160
  913. package/src/plugins/shell/shell.integration.test.ts +0 -273
  914. package/src/plugins/shell/shell.test.ts +0 -314
  915. package/src/plugins/skills/discovery.test.ts +0 -395
  916. package/src/plugins/skills/skills.integration.test.ts +0 -580
  917. package/src/plugins/todo/todo.integration.test.ts +0 -687
  918. package/src/plugins/uploads/preprocessors/image-classifier.test.ts +0 -142
  919. package/src/plugins/uploads/uploads.integration.test.ts +0 -831
  920. package/src/plugins/user-chat/user-chat.integration.test.ts +0 -893
  921. package/src/plugins/workers/workers.integration.test.ts +0 -778
  922. package/src/prompts/macros.test.ts +0 -107
  923. package/src/testing/test-harness.test.ts +0 -114
  924. package/src/transport/http/routes/rpc.integration.test.ts +0 -243
  925. package/src/transport/http/routes/rpc.test.ts +0 -372
@@ -9,19 +9,26 @@ import type { PortPool } from './port-pool.js'
9
9
  import { buildServiceStatusMessage } from './prompt.js'
10
10
  import type { ServiceConfig, ServiceEntry } from './schema.js'
11
11
  import type { ServicePidRegistry } from './pid-registry.js'
12
- import { getProcessStartTime, ServiceExecutor } from './service.js'
12
+ import { ServiceExecutor } from './service.js'
13
+ import type { RuntimeLeaseRelease } from '~/core/sessions/runtime-activity.js'
13
14
 
14
15
  export const serviceEvents = createEventsFactory({
15
16
  events: {
16
17
  service_status_changed: z.object({
17
18
  serviceType: z.string(),
18
- toStatus: z.enum(['stopped', 'starting', 'ready', 'stopping', 'failed', 'paused']),
19
+ toStatus: z.enum(['stopped', 'starting', 'ready', 'stopping', 'failed']),
19
20
  port: z.number().optional(),
20
21
  error: z.string().optional(),
21
22
  cwd: z.string().optional(),
22
23
  command: z.string().optional(),
23
24
  pid: z.number().optional(),
24
25
  pidStartTime: z.number().optional(),
26
+ /**
27
+ * Who asked for the stop, on a `stopped` change. Absent from logs written
28
+ * before the discriminator existed — the reducer reads those as `agent`,
29
+ * the only default that cannot resurrect a service meant to stay down.
30
+ */
31
+ stoppedBy: z.enum(['agent', 'eviction']).optional(),
25
32
  /**
26
33
  * Set on a `failed` change when the `restartPolicy` has already queued a
27
34
  * revival, so that no consumer — agent prompt, SPA, platform — mistakes it
@@ -36,6 +43,17 @@ export const serviceEvents = createEventsFactory({
36
43
 
37
44
  export type ServiceStatusChangedEvent = (typeof serviceEvents)['Events']['service_status_changed']
38
45
 
46
+ /** Ephemeral status broadcast — mirrors the durable event, minus the fields no client reads. */
47
+ const serviceStatusNotificationSchema = z.object({
48
+ sessionId: z.string(),
49
+ serviceType: z.string(),
50
+ status: z.enum(['stopped', 'starting', 'ready', 'stopping', 'failed']),
51
+ port: z.number().optional(),
52
+ restartAt: z.number().optional(),
53
+ restartAttempt: z.number().optional(),
54
+ restartMaxRetries: z.number().optional(),
55
+ })
56
+
39
57
  /**
40
58
  * Session-wide service configuration.
41
59
  */
@@ -54,7 +72,9 @@ export interface ServiceAgentConfig {
54
72
  }
55
73
 
56
74
  export const servicePlugin = definePlugin('services')
75
+ .order(100)
57
76
  .pluginConfig<ServicePluginConfig>()
77
+ .notification('serviceStatus', { schema: serviceStatusNotificationSchema })
58
78
  .isSessionEnabled(({ pluginConfig }) => pluginConfig !== undefined && pluginConfig.services.length > 0)
59
79
  .events([serviceEvents, sessionEvents])
60
80
  .state({
@@ -70,6 +90,7 @@ export const servicePlugin = definePlugin('services')
70
90
  newServices.set(event.serviceType, {
71
91
  serviceType: event.serviceType,
72
92
  status: event.toStatus,
93
+ stoppedBy: 'never',
73
94
  port: event.port,
74
95
  cwd: event.cwd,
75
96
  command: event.command,
@@ -88,6 +109,7 @@ export const servicePlugin = definePlugin('services')
88
109
  }
89
110
  if (event.toStatus === 'starting') {
90
111
  updated.startedAt = event.timestamp
112
+ updated.stoppedBy = 'never'
91
113
  updated.error = undefined
92
114
  updated.port = event.port
93
115
  updated.cwd = event.cwd
@@ -107,13 +129,17 @@ export const servicePlugin = definePlugin('services')
107
129
  updated.command = event.command
108
130
  }
109
131
  }
110
- if (event.toStatus === 'failed' && event.error) {
111
- updated.error = event.error
112
- updated.pid = undefined
113
- updated.pidStartTime = undefined
132
+ if (event.toStatus === 'failed') {
133
+ if (event.error) updated.error = event.error
134
+ // `pid` is a claim on a process we spawned and have not seen exit — the
135
+ // only handle a later boot has on it. A `failed` change carries it while
136
+ // the process may still be alive, and omits it once the exit is confirmed.
137
+ updated.pid = event.pid
138
+ updated.pidStartTime = event.pidStartTime
114
139
  }
115
140
  if (event.toStatus === 'stopped') {
116
141
  updated.stoppedAt = event.timestamp
142
+ updated.stoppedBy = event.stoppedBy ?? 'agent'
117
143
  updated.pid = undefined
118
144
  updated.pidStartTime = undefined
119
145
  }
@@ -127,9 +153,11 @@ export const servicePlugin = definePlugin('services')
127
153
  let changed = false
128
154
  const newServices = new Map(services)
129
155
  for (const [serviceType, entry] of services) {
130
- const running = entry.status === 'starting' || entry.status === 'ready'
156
+ // `stopping` counts as live: a runtime that died mid-stop leaves it
157
+ // behind and no other path ever clears it.
158
+ const live = entry.status === 'starting' || entry.status === 'ready' || entry.status === 'stopping'
131
159
  // Any queued revival died with the runtime that held its timer.
132
- if (!running && entry.restartAt === undefined) continue
160
+ if (!live && entry.restartAt === undefined) continue
133
161
 
134
162
  const updated: ServiceEntry = {
135
163
  ...entry,
@@ -137,12 +165,15 @@ export const servicePlugin = definePlugin('services')
137
165
  restartAttempt: undefined,
138
166
  restartMaxRetries: undefined,
139
167
  }
140
- if (running) {
168
+ if (live) {
141
169
  updated.status = 'stopped'
170
+ // The runtime died under it — nobody decided to stop it.
171
+ updated.stoppedBy = 'eviction'
142
172
  updated.port = undefined
143
- updated.pid = undefined
144
- updated.pidStartTime = undefined
145
173
  updated.stoppedAt = event.timestamp
174
+ // `pid` deliberately survives: nothing killed that process, and this is
175
+ // the only handle left to find it with. This event is emitted immediately
176
+ // before `onSessionReady`, whose reconcile is what reclaims it.
146
177
  }
147
178
  newServices.set(serviceType, updated)
148
179
  changed = true
@@ -156,39 +187,159 @@ export const servicePlugin = definePlugin('services')
156
187
  },
157
188
  })
158
189
  .context(async (ctx, pluginConfig) => {
159
- const executor = new ServiceExecutor(ctx.logger, pluginConfig.portPool, {
190
+ const logger = ctx.logger
191
+ const emitEvent = ctx.emitEvent
192
+ const notify = ctx.notify
193
+ const runtimeActivity = ctx.runtimeActivity
194
+ interface ServiceLease {
195
+ release: RuntimeLeaseRelease
196
+ terminalPending: boolean
197
+ }
198
+ const serviceLeases = new Map<string, ServiceLease>()
199
+ /** Status publications still in flight per type — a lease has to outlive them. */
200
+ const pendingPublications = new Map<string, number>()
201
+ const statusEffects = new Set<Promise<void>>()
202
+ let statusEffectTail = Promise.resolve()
203
+ let publicationEnabled = true
204
+ const executor = new ServiceExecutor(logger, pluginConfig.portPool, {
160
205
  fs: ctx.platform.fs,
161
206
  process: ctx.platform.process,
162
207
  pidRegistry: pluginConfig.pidRegistry,
163
208
  })
209
+ const beginLifecycle = (serviceType: string): ServiceLease | undefined => {
210
+ const existing = serviceLeases.get(serviceType)
211
+ if (existing && !existing.terminalPending) return existing
212
+
213
+ // Undefined once the runtime unloads — the close tail that runs then is
214
+ // already awaited by disposal, so nothing is left unguarded.
215
+ const release = runtimeActivity.tryAcquire(`service:${serviceType}`)
216
+ if (!release) return undefined
217
+ const lease: ServiceLease = { release, terminalPending: false }
218
+ serviceLeases.set(serviceType, lease)
219
+ return lease
220
+ }
221
+ const releaseLease = (serviceType: string, lease: ServiceLease): void => {
222
+ if (serviceLeases.get(serviceType) === lease) serviceLeases.delete(serviceType)
223
+ lease.release()
224
+ }
225
+ /**
226
+ * A healthy service must not pin its runtime: eviction stops services and the
227
+ * rebuild starts them again, so a dev server sitting at `ready` for hours is
228
+ * exactly what eviction is for. Only work that cannot survive disposal keeps
229
+ * the lease — a transition in progress, a queued revival, an unpublished status.
230
+ */
231
+ const needsRuntime = (serviceType: string): boolean => {
232
+ if ((pendingPublications.get(serviceType) ?? 0) > 0) return true
233
+ const status = executor.getStatus(serviceType)
234
+ return status === 'starting' || status === 'stopping' || executor.hasScheduledRestart(serviceType)
235
+ }
236
+ const releaseLeaseWhenIdle = (serviceType: string, lease: ServiceLease): void => {
237
+ if (serviceLeases.get(serviceType) !== lease || lease.terminalPending) return
238
+ if (!needsRuntime(serviceType)) releaseLease(serviceType, lease)
239
+ }
240
+ const startService = async (
241
+ config: ServiceConfig,
242
+ sessionId: Parameters<ServiceExecutor['start']>[1],
243
+ workspaceDir?: string,
244
+ preferredPort?: number,
245
+ ) => {
246
+ const lease = beginLifecycle(config.type)
247
+ try {
248
+ return await executor.start(config, sessionId, workspaceDir, preferredPort)
249
+ } finally {
250
+ if (lease) releaseLeaseWhenIdle(config.type, lease)
251
+ }
252
+ }
253
+ const restartService = async (
254
+ config: ServiceConfig,
255
+ sessionId: Parameters<ServiceExecutor['restart']>[1],
256
+ workspaceDir?: string,
257
+ preferredPort?: number,
258
+ ) => {
259
+ const lease = beginLifecycle(config.type)
260
+ try {
261
+ return await executor.restart(config, sessionId, workspaceDir, preferredPort)
262
+ } finally {
263
+ if (lease) releaseLeaseWhenIdle(config.type, lease)
264
+ }
265
+ }
266
+ const waitForStatusEffects = async (): Promise<void> => {
267
+ while (statusEffects.size > 0) {
268
+ await Promise.allSettled([...statusEffects])
269
+ }
270
+ }
271
+ executor.onStartSettled = (serviceType) => {
272
+ const lease = serviceLeases.get(serviceType)
273
+ if (lease) releaseLeaseWhenIdle(serviceType, lease)
274
+ }
164
275
  executor.onStatusChanged = (sessionId, serviceType, status, details) => {
165
- void ctx.emitEvent(serviceEvents.create('service_status_changed', {
166
- serviceType,
167
- toStatus: status,
168
- port: details.port,
169
- error: details.error,
170
- cwd: details.cwd,
171
- command: details.command,
172
- pid: details.pid,
173
- pidStartTime: details.pidStartTime,
174
- restartAt: details.restartAt,
175
- restartAttempt: details.restartAttempt,
176
- restartMaxRetries: details.restartMaxRetries,
177
- }))
178
- // Broadcast service status to connected clients (DO → SPA) via WS.
179
- // restartAt rides along so a consumer can hold on to a preview URL it
180
- // would otherwise tear down on `failed`.
181
- ctx.notify('serviceStatus', {
182
- sessionId: String(sessionId),
183
- serviceType,
184
- status,
185
- port: details.port,
186
- restartAt: details.restartAt,
187
- restartAttempt: details.restartAttempt,
188
- restartMaxRetries: details.restartMaxRetries,
276
+ if (!publicationEnabled) return
277
+ const terminal = status === 'stopped' || (status === 'failed' && details.restartAt === undefined)
278
+ const lease = terminal ? serviceLeases.get(serviceType) : beginLifecycle(serviceType)
279
+ if (terminal && lease) lease.terminalPending = true
280
+ pendingPublications.set(serviceType, (pendingPublications.get(serviceType) ?? 0) + 1)
281
+
282
+ const effect = statusEffectTail.then(async () => {
283
+ try {
284
+ await emitEvent(serviceEvents.create('service_status_changed', {
285
+ serviceType,
286
+ toStatus: status,
287
+ port: details.port,
288
+ error: details.error,
289
+ cwd: details.cwd,
290
+ command: details.command,
291
+ pid: details.pid,
292
+ pidStartTime: details.pidStartTime,
293
+ stoppedBy: details.stoppedBy,
294
+ restartAt: details.restartAt,
295
+ restartAttempt: details.restartAttempt,
296
+ restartMaxRetries: details.restartMaxRetries,
297
+ }))
298
+ // Broadcast only after the durable projection catches up.
299
+ notify('serviceStatus', {
300
+ sessionId: String(sessionId),
301
+ serviceType,
302
+ status,
303
+ port: details.port,
304
+ restartAt: details.restartAt,
305
+ restartAttempt: details.restartAttempt,
306
+ restartMaxRetries: details.restartMaxRetries,
307
+ })
308
+ } catch (error) {
309
+ logger.error('Failed to publish service status', error instanceof Error ? error : new Error(String(error)), {
310
+ serviceType,
311
+ status,
312
+ })
313
+ } finally {
314
+ const remaining = (pendingPublications.get(serviceType) ?? 1) - 1
315
+ if (remaining > 0) pendingPublications.set(serviceType, remaining)
316
+ else pendingPublications.delete(serviceType)
317
+ if (lease) {
318
+ if (terminal) releaseLease(serviceType, lease)
319
+ else releaseLeaseWhenIdle(serviceType, lease)
320
+ }
321
+ }
189
322
  })
323
+ statusEffectTail = effect.then(() => undefined, () => undefined)
324
+ statusEffects.add(effect)
325
+ const removeEffect = () => statusEffects.delete(effect)
326
+ void effect.then(removeEffect, removeEffect)
190
327
  }
191
- return { executor }
328
+ const close = async (
329
+ sessionId: Parameters<ServiceExecutor['close']>[0],
330
+ reason: Parameters<ServiceExecutor['close']>[1],
331
+ ): Promise<void> => {
332
+ try {
333
+ await executor.close(sessionId, reason)
334
+ } finally {
335
+ publicationEnabled = false
336
+ executor.onStatusChanged = undefined
337
+ executor.onStartSettled = undefined
338
+ await waitForStatusEffects()
339
+ for (const [serviceType, lease] of serviceLeases) releaseLease(serviceType, lease)
340
+ }
341
+ }
342
+ return { executor, startService, restartService, close }
192
343
  })
193
344
  .agentConfig<ServiceAgentConfig>()
194
345
  .method('start', {
@@ -214,7 +365,7 @@ export const servicePlugin = definePlugin('services')
214
365
  }
215
366
 
216
367
  const preferredPort = ctx.pluginState.get(input.serviceType)?.port
217
- const startResult = await ctx.pluginContext.executor.start(svcConfig, ctx.sessionId, ctx.sessionState.workspaceDir, preferredPort)
368
+ const startResult = await ctx.pluginContext.startService(svcConfig, ctx.sessionId, ctx.sessionState.workspaceDir, preferredPort)
218
369
  if (!startResult.ok) return Err(ValidationErrors.invalid(startResult.error.message))
219
370
  started.push(input.serviceType)
220
371
  } else {
@@ -229,7 +380,7 @@ export const servicePlugin = definePlugin('services')
229
380
  }
230
381
  } else {
231
382
  const preferredPort = ctx.pluginState.get(svcConfig.type)?.port
232
- const startResult = await ctx.pluginContext.executor.start(svcConfig, ctx.sessionId, ctx.sessionState.workspaceDir, preferredPort)
383
+ const startResult = await ctx.pluginContext.startService(svcConfig, ctx.sessionId, ctx.sessionState.workspaceDir, preferredPort)
233
384
  if (!startResult.ok) return Err(ValidationErrors.invalid(startResult.error.message))
234
385
  started.push(svcConfig.type)
235
386
  }
@@ -269,7 +420,7 @@ export const servicePlugin = definePlugin('services')
269
420
  if (!svcConfig) return Err(ValidationErrors.invalid(`Service ${input.serviceType} not found`))
270
421
 
271
422
  const preferredPort = ctx.pluginState.get(input.serviceType)?.port
272
- const result = await ctx.pluginContext.executor.restart(svcConfig, ctx.sessionId, ctx.sessionState.workspaceDir, preferredPort)
423
+ const result = await ctx.pluginContext.restartService(svcConfig, ctx.sessionId, ctx.sessionState.workspaceDir, preferredPort)
273
424
  if (!result.ok) return Err(ValidationErrors.invalid(result.error.message))
274
425
  return Ok({})
275
426
  },
@@ -347,78 +498,83 @@ export const servicePlugin = definePlugin('services')
347
498
  },
348
499
  })
349
500
  .sessionHook('onSessionReady', async (ctx) => {
350
- // Reconcile: kill orphaned process groups from previous server instance
351
- // and mark corresponding services as stopped. Port is preserved in state
352
- // so the next start() reuses it via preferredPort.
353
- // Also re-notify running services so DO re-registers their URLs.
501
+ // Reconcile what a previous runtime left behind: kill orphaned process groups and
502
+ // settle the entries that claimed them. Port is preserved in state so the next
503
+ // start() reuses it via preferredPort. Also re-notify running services so DO
504
+ // re-registers their URLs.
505
+ //
506
+ // Driven off the recorded pid rather than a list of running statuses: a process we
507
+ // spawned and never saw exit is an orphan whatever the entry says, and `failed` or
508
+ // `stopped` reaches the next boot still owning one just as often as `ready` does.
354
509
  for (const [serviceType, entry] of ctx.pluginState) {
355
- if (entry.status === 'starting' || entry.status === 'ready' || entry.status === 'paused') {
356
- const executorStatus = ctx.pluginContext.executor.getStatus(serviceType)
357
- if (!executorStatus) {
358
- if (entry.pid !== undefined) {
359
- // PID-reuse guard: only kill if we can confirm this PID still
360
- // belongs to the process we spawned. If we stored a pidStartTime,
361
- // the current start time must match — a mismatch means the kernel
362
- // recycled the PID for an unrelated process and SIGKILL would be
363
- // disastrous. On non-Linux (no /proc), start times are always
364
- // undefined and we fall back to the pre-existing kill-and-hope path.
365
- const currentStartTime = await getProcessStartTime(ctx.platform.fs, entry.pid)
366
- const pidReused = entry.pidStartTime !== undefined
367
- && currentStartTime !== undefined
368
- && currentStartTime !== entry.pidStartTime
369
-
370
- if (pidReused) {
371
- ctx.logger.warn('PID reuse detected during orphan reconcile — refusing to kill', {
372
- serviceType,
373
- pid: entry.pid,
374
- storedStartTime: entry.pidStartTime,
375
- currentStartTime,
376
- })
377
- } else {
378
- try {
379
- process.kill(-entry.pid, 'SIGKILL')
380
- ctx.logger.info('Killed orphaned service process group', { serviceType, pid: entry.pid })
381
- } catch (err) {
382
- ctx.logger.debug('Orphaned service process already gone', { serviceType, pid: entry.pid, err })
383
- }
384
- }
385
- }
386
- await ctx.emitEvent(serviceEvents.create('service_status_changed', {
387
- serviceType,
388
- toStatus: 'stopped',
389
- }))
390
- } else if (executorStatus === 'ready' && entry.port) {
510
+ // `stopping` counts as live: a runtime that died mid-stop leaves it behind, and
511
+ // it is reachable by no other recovery path.
512
+ const live = entry.status === 'starting' || entry.status === 'ready' || entry.status === 'stopping'
513
+ if (!live && entry.pid === undefined) continue
514
+
515
+ const executorStatus = ctx.pluginContext.executor.getStatus(serviceType)
516
+ if (executorStatus) {
517
+ if (executorStatus === 'ready' && entry.port) {
391
518
  // Re-notify so DO can re-register service URL after reconnect
392
519
  ctx.notify('serviceStatus', { sessionId: String(ctx.sessionId), serviceType, status: 'ready', port: entry.port })
393
520
  }
521
+ continue
394
522
  }
395
- }
396
523
 
397
- // Auto-start services configured with autoStart
398
- for (const svcConfig of ctx.pluginConfig.services) {
399
- if (svcConfig.autoStart) {
400
- const status = ctx.pluginContext.executor.getStatus(svcConfig.type)
401
- if (status !== 'ready' && status !== 'starting') {
402
- const preferredPort = ctx.pluginState.get(svcConfig.type)?.port
403
- const startResult = await ctx.pluginContext.executor.start(svcConfig, ctx.sessionId, ctx.sessionState.workspaceDir, preferredPort)
404
- if (!startResult.ok) {
405
- ctx.logger.debug('Auto-start service skipped', { serviceType: svcConfig.type, error: startResult.error.message })
406
- }
524
+ if (entry.pid !== undefined) {
525
+ // Guarded and loud when it fails: a signal that did not land must not look
526
+ // like one that did.
527
+ const reaped = await ctx.pluginContext.executor.reapProcessGroup(
528
+ { pid: entry.pid, pidStartTime: entry.pidStartTime },
529
+ { serviceType },
530
+ )
531
+ if (!reaped.ok) {
532
+ ctx.logger.warn('Could not kill orphaned service process group', {
533
+ serviceType,
534
+ pid: entry.pid,
535
+ error: reaped.error.message,
536
+ })
537
+ } else if (reaped.value === 'killed') {
538
+ ctx.logger.info('Killed orphaned service process group', { serviceType, pid: entry.pid })
407
539
  }
408
540
  }
541
+
542
+ // A `failed` entry keeps its status and the error that explains it — only its
543
+ // claim on a process is taken away. Everything else settles as stopped.
544
+ await ctx.emitEvent(serviceEvents.create('service_status_changed', entry.status === 'failed'
545
+ ? { serviceType, toStatus: 'failed' }
546
+ : {
547
+ serviceType,
548
+ toStatus: 'stopped',
549
+ // The runtime died under it — nobody decided to stop it, so autoStart may revive it.
550
+ stoppedBy: 'eviction',
551
+ }))
409
552
  }
410
- })
411
- .sessionHook('onSessionClose', async (ctx) => {
553
+
554
+ // Auto-start services configured with autoStart
412
555
  for (const svcConfig of ctx.pluginConfig.services) {
556
+ if (!svcConfig.autoStart) continue
413
557
  const status = ctx.pluginContext.executor.getStatus(svcConfig.type)
414
- // A queued revival outlives the session otherwise: its timer holds the
415
- // executor alive and spawns a process into a session that is already gone.
416
- const revivalQueued = ctx.pluginContext.executor.hasScheduledRestart(svcConfig.type)
417
- if (status === 'ready' || status === 'starting' || revivalQueued) {
418
- await ctx.pluginContext.executor.stop(svcConfig.type, ctx.sessionId)
558
+ if (status === 'ready' || status === 'starting') continue
559
+
560
+ // On a fresh runtime the executor knows nothing, so the persisted decision is
561
+ // the only thing that can tell an evicted service (bring it back) from one the
562
+ // agent stopped on purpose (leave it down).
563
+ const entry = ctx.pluginState.get(svcConfig.type)
564
+ if (entry?.status === 'stopped' && entry.stoppedBy === 'agent') {
565
+ ctx.logger.debug('Auto-start skipped — the agent stopped this service', { serviceType: svcConfig.type })
566
+ continue
567
+ }
568
+
569
+ const startResult = await ctx.pluginContext.startService(svcConfig, ctx.sessionId, ctx.sessionState.workspaceDir, entry?.port)
570
+ if (!startResult.ok) {
571
+ ctx.logger.debug('Auto-start service skipped', { serviceType: svcConfig.type, error: startResult.error.message })
419
572
  }
420
573
  }
421
574
  })
575
+ .sessionHook('onSessionClose', async (ctx) => {
576
+ await ctx.pluginContext.close(ctx.sessionId, ctx.reason)
577
+ })
422
578
  .tools((ctx) => {
423
579
  const serviceMap = new Map(ctx.pluginConfig.services.map((svc) => [svc.type, svc]))
424
580
  const visibleServices = ctx.pluginAgentConfig?.services ?? []
@@ -31,12 +31,7 @@ export function buildServiceStatusMessage(
31
31
  const status = entry?.status ?? 'stopped'
32
32
  let line = `- ${config.type}: ${config.description} — ${status}`
33
33
 
34
- if (
35
- entry?.port !== undefined
36
- && entry.status !== 'stopped'
37
- && entry.status !== 'failed'
38
- && entry.status !== 'paused'
39
- ) {
34
+ if (entry?.port !== undefined && entry.status !== 'stopped' && entry.status !== 'failed') {
40
35
  line += ` (port ${entry.port})`
41
36
  }
42
37
  if (entry?.error) {
@@ -13,7 +13,17 @@
13
13
  /**
14
14
  * Service lifecycle status.
15
15
  */
16
- export type ServiceStatus = 'stopped' | 'starting' | 'ready' | 'stopping' | 'failed' | 'paused'
16
+ export type ServiceStatus = 'stopped' | 'starting' | 'ready' | 'stopping' | 'failed'
17
+
18
+ /**
19
+ * Who asked for a stop. Every runtime-lifecycle stop — idle eviction, session
20
+ * close, server shutdown — records `eviction`, because none of them is the
21
+ * agent's decision and all of them may be undone by the next runtime.
22
+ */
23
+ export type ServiceStopSource = 'agent' | 'eviction'
24
+
25
+ /** `never` means the service has not been stopped since its last start. */
26
+ export type ServiceStoppedBy = ServiceStopSource | 'never'
17
27
 
18
28
  // ============================================================================
19
29
  // Service Config (declared in presets)
@@ -123,8 +133,6 @@ export interface ServiceConfig {
123
133
  /** Uptime that counts as healthy and resets the budget (default: 60000) */
124
134
  healthyAfterMs?: number
125
135
  }
126
- /** Auto-pause configuration (interface prepared, not yet implemented) */
127
- autoPause?: { inactivityMs: number }
128
136
  /**
129
137
  * When false, the service is hidden from the owning agent: excluded from its
130
138
  * service_* tools and the session-context status block. It still runs at the
@@ -146,6 +154,12 @@ export interface ServiceConfig {
146
154
  export interface ServiceEntry {
147
155
  serviceType: string
148
156
  status: ServiceStatus
157
+ /**
158
+ * Who stopped the service. An idle eviction stops services and the rebuilt
159
+ * runtime starts them again, so autoStart needs this to tell a parked
160
+ * service from one the agent deliberately shut down and expects to stay down.
161
+ */
162
+ stoppedBy: ServiceStoppedBy
149
163
  port?: number
150
164
  error?: string
151
165
  /** Resolved working directory used for the current/last start. */