@0xmaxma/claude-gateway 2.0.10 → 2.0.11

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 (345) hide show
  1. package/README.md +15 -0
  2. package/config.template.json +1 -1
  3. package/dist/agent/runner.d.ts +119 -11
  4. package/dist/agent/runner.d.ts.map +1 -1
  5. package/dist/agent/runner.js +58 -8
  6. package/dist/agent/runner.js.map +1 -1
  7. package/dist/api/browser-bindings-router.d.ts +6 -0
  8. package/dist/api/browser-bindings-router.d.ts.map +1 -0
  9. package/dist/api/browser-bindings-router.js +150 -0
  10. package/dist/api/browser-bindings-router.js.map +1 -0
  11. package/dist/api/connectors-router.js +1 -1
  12. package/dist/api/connectors-router.js.map +1 -1
  13. package/dist/api/gateway-router.d.ts.map +1 -1
  14. package/dist/api/gateway-router.js +30 -2
  15. package/dist/api/gateway-router.js.map +1 -1
  16. package/dist/api/jev-router.d.ts +8 -0
  17. package/dist/api/jev-router.d.ts.map +1 -0
  18. package/dist/api/jev-router.js +128 -0
  19. package/dist/api/jev-router.js.map +1 -0
  20. package/dist/api/router.d.ts.map +1 -1
  21. package/dist/api/router.js +53 -6
  22. package/dist/api/router.js.map +1 -1
  23. package/dist/api/voice-router.d.ts.map +1 -1
  24. package/dist/api/voice-router.js +42 -3
  25. package/dist/api/voice-router.js.map +1 -1
  26. package/dist/automation/browser-command.d.ts +79 -0
  27. package/dist/automation/browser-command.d.ts.map +1 -0
  28. package/dist/automation/browser-command.js +118 -0
  29. package/dist/automation/browser-command.js.map +1 -0
  30. package/dist/automation/browser-outcome.d.ts +3 -0
  31. package/dist/automation/browser-outcome.d.ts.map +1 -0
  32. package/dist/automation/browser-outcome.js +78 -0
  33. package/dist/automation/browser-outcome.js.map +1 -0
  34. package/dist/automation/browser-steps.d.ts +33 -0
  35. package/dist/automation/browser-steps.d.ts.map +1 -0
  36. package/dist/automation/browser-steps.js +293 -0
  37. package/dist/automation/browser-steps.js.map +1 -0
  38. package/dist/automation/browser-trace.d.ts +60 -0
  39. package/dist/automation/browser-trace.d.ts.map +1 -0
  40. package/dist/automation/browser-trace.js +24 -0
  41. package/dist/automation/browser-trace.js.map +1 -0
  42. package/dist/automation/browser-use.d.ts +210 -0
  43. package/dist/automation/browser-use.d.ts.map +1 -0
  44. package/dist/automation/browser-use.js +1271 -0
  45. package/dist/automation/browser-use.js.map +1 -0
  46. package/dist/automation/command-speech.d.ts +33 -0
  47. package/dist/automation/command-speech.d.ts.map +1 -0
  48. package/dist/automation/command-speech.js +117 -0
  49. package/dist/automation/command-speech.js.map +1 -0
  50. package/dist/automation/command-steps.d.ts +35 -0
  51. package/dist/automation/command-steps.d.ts.map +1 -0
  52. package/dist/automation/command-steps.js +155 -0
  53. package/dist/automation/command-steps.js.map +1 -0
  54. package/dist/automation/computer-choice-ids.d.ts +7 -0
  55. package/dist/automation/computer-choice-ids.d.ts.map +1 -0
  56. package/dist/automation/computer-choice-ids.js +24 -0
  57. package/dist/automation/computer-choice-ids.js.map +1 -0
  58. package/dist/automation/computer-command.d.ts +126 -0
  59. package/dist/automation/computer-command.d.ts.map +1 -0
  60. package/dist/automation/computer-command.js +313 -0
  61. package/dist/automation/computer-command.js.map +1 -0
  62. package/dist/automation/computer-outcome.d.ts +8 -0
  63. package/dist/automation/computer-outcome.d.ts.map +1 -0
  64. package/dist/automation/computer-outcome.js +82 -0
  65. package/dist/automation/computer-outcome.js.map +1 -0
  66. package/dist/automation/computer-policy.d.ts +84 -0
  67. package/dist/automation/computer-policy.d.ts.map +1 -0
  68. package/dist/automation/computer-policy.js +56 -0
  69. package/dist/automation/computer-policy.js.map +1 -0
  70. package/dist/automation/computer-safety.d.ts +27 -0
  71. package/dist/automation/computer-safety.d.ts.map +1 -0
  72. package/dist/automation/computer-safety.js +47 -0
  73. package/dist/automation/computer-safety.js.map +1 -0
  74. package/dist/automation/computer-steps.d.ts +20 -0
  75. package/dist/automation/computer-steps.d.ts.map +1 -0
  76. package/dist/automation/computer-steps.js +251 -0
  77. package/dist/automation/computer-steps.js.map +1 -0
  78. package/dist/automation/computer-use.d.ts +315 -0
  79. package/dist/automation/computer-use.d.ts.map +1 -0
  80. package/dist/automation/computer-use.js +864 -0
  81. package/dist/automation/computer-use.js.map +1 -0
  82. package/dist/automation/direct-command.d.ts +51 -0
  83. package/dist/automation/direct-command.d.ts.map +1 -0
  84. package/dist/automation/direct-command.js +152 -0
  85. package/dist/automation/direct-command.js.map +1 -0
  86. package/dist/automation/interrupt.d.ts +4 -0
  87. package/dist/automation/interrupt.d.ts.map +1 -0
  88. package/dist/automation/interrupt.js +26 -0
  89. package/dist/automation/interrupt.js.map +1 -0
  90. package/dist/build-provenance.json +4 -4
  91. package/dist/child-env-exclusions.d.ts +4 -0
  92. package/dist/child-env-exclusions.d.ts.map +1 -0
  93. package/dist/child-env-exclusions.js +23 -0
  94. package/dist/child-env-exclusions.js.map +1 -0
  95. package/dist/cli/startup-diagnostics.d.ts.map +1 -1
  96. package/dist/cli/startup-diagnostics.js +19 -0
  97. package/dist/cli/startup-diagnostics.js.map +1 -1
  98. package/dist/config/loader.d.ts.map +1 -1
  99. package/dist/config/loader.js +4 -0
  100. package/dist/config/loader.js.map +1 -1
  101. package/dist/config/reload-policy.d.ts.map +1 -1
  102. package/dist/config/reload-policy.js +2 -1
  103. package/dist/config/reload-policy.js.map +1 -1
  104. package/dist/jev/automatic-browser-bindings.d.ts +15 -0
  105. package/dist/jev/automatic-browser-bindings.d.ts.map +1 -0
  106. package/dist/jev/automatic-browser-bindings.js +115 -0
  107. package/dist/jev/automatic-browser-bindings.js.map +1 -0
  108. package/dist/jev/browser-connector.d.ts +29 -0
  109. package/dist/jev/browser-connector.d.ts.map +1 -0
  110. package/dist/jev/browser-connector.js +347 -0
  111. package/dist/jev/browser-connector.js.map +1 -0
  112. package/dist/jev/browser-consent.d.ts +6 -0
  113. package/dist/jev/browser-consent.d.ts.map +1 -0
  114. package/dist/jev/browser-consent.js +50 -0
  115. package/dist/jev/browser-consent.js.map +1 -0
  116. package/dist/jev/browser-contract.d.ts +215 -0
  117. package/dist/jev/browser-contract.d.ts.map +1 -0
  118. package/dist/jev/browser-contract.js +10 -0
  119. package/dist/jev/browser-contract.js.map +1 -0
  120. package/dist/jev/browser-evidence-summary.d.ts +73 -0
  121. package/dist/jev/browser-evidence-summary.d.ts.map +1 -0
  122. package/dist/jev/browser-evidence-summary.js +22 -0
  123. package/dist/jev/browser-evidence-summary.js.map +1 -0
  124. package/dist/jev/browser-module-import.d.ts +3 -0
  125. package/dist/jev/browser-module-import.d.ts.map +1 -0
  126. package/dist/jev/browser-module-import.js +6 -0
  127. package/dist/jev/browser-module-import.js.map +1 -0
  128. package/dist/jev/child-env.d.ts +11 -0
  129. package/dist/jev/child-env.d.ts.map +1 -0
  130. package/dist/jev/child-env.js +60 -0
  131. package/dist/jev/child-env.js.map +1 -0
  132. package/dist/jev/computer-connector.d.ts +34 -0
  133. package/dist/jev/computer-connector.d.ts.map +1 -0
  134. package/dist/jev/computer-connector.js +82 -0
  135. package/dist/jev/computer-connector.js.map +1 -0
  136. package/dist/jev/computer-inputs.d.ts +41 -0
  137. package/dist/jev/computer-inputs.d.ts.map +1 -0
  138. package/dist/jev/computer-inputs.js +7 -0
  139. package/dist/jev/computer-inputs.js.map +1 -0
  140. package/dist/jev/index.d.ts +6 -0
  141. package/dist/jev/index.d.ts.map +1 -0
  142. package/dist/jev/index.js +25 -0
  143. package/dist/jev/index.js.map +1 -0
  144. package/dist/jev/relay-grants.d.ts +9 -0
  145. package/dist/jev/relay-grants.d.ts.map +1 -0
  146. package/dist/jev/relay-grants.js +49 -0
  147. package/dist/jev/relay-grants.js.map +1 -0
  148. package/dist/jev/service.d.ts +27 -0
  149. package/dist/jev/service.d.ts.map +1 -0
  150. package/dist/jev/service.js +264 -0
  151. package/dist/jev/service.js.map +1 -0
  152. package/dist/jev/thinking-provider.d.ts +7 -0
  153. package/dist/jev/thinking-provider.d.ts.map +1 -0
  154. package/dist/jev/thinking-provider.js +25 -0
  155. package/dist/jev/thinking-provider.js.map +1 -0
  156. package/dist/jev/types.d.ts +124 -0
  157. package/dist/jev/types.d.ts.map +1 -0
  158. package/dist/jev/types.js +13 -0
  159. package/dist/jev/types.js.map +1 -0
  160. package/dist/jev/validation.d.ts +45 -0
  161. package/dist/jev/validation.d.ts.map +1 -0
  162. package/dist/jev/validation.js +179 -0
  163. package/dist/jev/validation.js.map +1 -0
  164. package/dist/load-dotenv.d.ts.map +1 -1
  165. package/dist/load-dotenv.js +5 -1
  166. package/dist/load-dotenv.js.map +1 -1
  167. package/dist/orchestration/agent-tool-schemas.d.ts.map +1 -1
  168. package/dist/orchestration/agent-tool-schemas.js +12 -7
  169. package/dist/orchestration/agent-tool-schemas.js.map +1 -1
  170. package/dist/orchestration/background-work.d.ts +1 -0
  171. package/dist/orchestration/background-work.d.ts.map +1 -1
  172. package/dist/orchestration/background-work.js +1 -0
  173. package/dist/orchestration/background-work.js.map +1 -1
  174. package/dist/orchestration/bridge.d.ts +4 -0
  175. package/dist/orchestration/bridge.d.ts.map +1 -1
  176. package/dist/orchestration/bridge.js +176 -41
  177. package/dist/orchestration/bridge.js.map +1 -1
  178. package/dist/orchestration/browser-fields.d.ts +25 -0
  179. package/dist/orchestration/browser-fields.d.ts.map +1 -0
  180. package/dist/orchestration/browser-fields.js +23 -0
  181. package/dist/orchestration/browser-fields.js.map +1 -0
  182. package/dist/orchestration/browser-routing.d.ts +1 -1
  183. package/dist/orchestration/browser-routing.d.ts.map +1 -1
  184. package/dist/orchestration/browser-routing.js +7 -3
  185. package/dist/orchestration/browser-routing.js.map +1 -1
  186. package/dist/orchestration/capabilities.d.ts +4 -1
  187. package/dist/orchestration/capabilities.d.ts.map +1 -1
  188. package/dist/orchestration/capabilities.js +15 -9
  189. package/dist/orchestration/capabilities.js.map +1 -1
  190. package/dist/orchestration/channel-controls.js +1 -1
  191. package/dist/orchestration/channel-controls.js.map +1 -1
  192. package/dist/orchestration/cli-skills.d.ts.map +1 -1
  193. package/dist/orchestration/cli-skills.js +3 -2
  194. package/dist/orchestration/cli-skills.js.map +1 -1
  195. package/dist/orchestration/computer-end-screenshot.d.ts +11 -0
  196. package/dist/orchestration/computer-end-screenshot.d.ts.map +1 -0
  197. package/dist/orchestration/computer-end-screenshot.js +37 -0
  198. package/dist/orchestration/computer-end-screenshot.js.map +1 -0
  199. package/dist/orchestration/computer-prompt.d.ts +6 -0
  200. package/dist/orchestration/computer-prompt.d.ts.map +1 -0
  201. package/dist/orchestration/computer-prompt.js +24 -0
  202. package/dist/orchestration/computer-prompt.js.map +1 -0
  203. package/dist/orchestration/config.d.ts +17 -0
  204. package/dist/orchestration/config.d.ts.map +1 -1
  205. package/dist/orchestration/config.js +10 -4
  206. package/dist/orchestration/config.js.map +1 -1
  207. package/dist/orchestration/container-tool-schemas.d.ts +47 -3
  208. package/dist/orchestration/container-tool-schemas.d.ts.map +1 -1
  209. package/dist/orchestration/container-tool-schemas.js +41 -6
  210. package/dist/orchestration/container-tool-schemas.js.map +1 -1
  211. package/dist/orchestration/container.d.ts +4 -1
  212. package/dist/orchestration/container.d.ts.map +1 -1
  213. package/dist/orchestration/container.js +48 -29
  214. package/dist/orchestration/container.js.map +1 -1
  215. package/dist/orchestration/context-footprint.d.ts +1 -1
  216. package/dist/orchestration/context-footprint.d.ts.map +1 -1
  217. package/dist/orchestration/context-footprint.js +5 -5
  218. package/dist/orchestration/context-footprint.js.map +1 -1
  219. package/dist/orchestration/control-notification.d.ts +6 -0
  220. package/dist/orchestration/control-notification.d.ts.map +1 -0
  221. package/dist/orchestration/control-notification.js +23 -0
  222. package/dist/orchestration/control-notification.js.map +1 -0
  223. package/dist/orchestration/dashboard-reader-worker.js +2 -2
  224. package/dist/orchestration/dashboard-reader-worker.js.map +1 -1
  225. package/dist/orchestration/execution-observation.d.ts +3 -0
  226. package/dist/orchestration/execution-observation.d.ts.map +1 -1
  227. package/dist/orchestration/execution-observation.js.map +1 -1
  228. package/dist/orchestration/gateway-tasks/browser.d.ts +59 -0
  229. package/dist/orchestration/gateway-tasks/browser.d.ts.map +1 -0
  230. package/dist/orchestration/gateway-tasks/browser.js +426 -0
  231. package/dist/orchestration/gateway-tasks/browser.js.map +1 -0
  232. package/dist/orchestration/gateway-tasks/computer-context.d.ts +6 -0
  233. package/dist/orchestration/gateway-tasks/computer-context.d.ts.map +1 -0
  234. package/dist/orchestration/gateway-tasks/computer-context.js +19 -0
  235. package/dist/orchestration/gateway-tasks/computer-context.js.map +1 -0
  236. package/dist/orchestration/gateway-tasks/computer.d.ts +123 -0
  237. package/dist/orchestration/gateway-tasks/computer.d.ts.map +1 -0
  238. package/dist/orchestration/gateway-tasks/computer.js +519 -0
  239. package/dist/orchestration/gateway-tasks/computer.js.map +1 -0
  240. package/dist/orchestration/gateway-tasks/controller.d.ts +40 -6
  241. package/dist/orchestration/gateway-tasks/controller.d.ts.map +1 -1
  242. package/dist/orchestration/gateway-tasks/controller.js +118 -12
  243. package/dist/orchestration/gateway-tasks/controller.js.map +1 -1
  244. package/dist/orchestration/gateway-tasks/safemode.d.ts.map +1 -1
  245. package/dist/orchestration/gateway-tasks/safemode.js +2 -1
  246. package/dist/orchestration/gateway-tasks/safemode.js.map +1 -1
  247. package/dist/orchestration/jev-gateway.d.ts +25 -0
  248. package/dist/orchestration/jev-gateway.d.ts.map +1 -0
  249. package/dist/orchestration/jev-gateway.js +103 -0
  250. package/dist/orchestration/jev-gateway.js.map +1 -0
  251. package/dist/orchestration/jev-tool.d.ts +45 -0
  252. package/dist/orchestration/jev-tool.d.ts.map +1 -0
  253. package/dist/orchestration/jev-tool.js +10 -0
  254. package/dist/orchestration/jev-tool.js.map +1 -0
  255. package/dist/orchestration/live-execution-input.d.ts +26 -0
  256. package/dist/orchestration/live-execution-input.d.ts.map +1 -0
  257. package/dist/orchestration/live-execution-input.js +70 -0
  258. package/dist/orchestration/live-execution-input.js.map +1 -0
  259. package/dist/orchestration/notification-mailbox.d.ts.map +1 -1
  260. package/dist/orchestration/notification-mailbox.js +5 -2
  261. package/dist/orchestration/notification-mailbox.js.map +1 -1
  262. package/dist/orchestration/process-platform.d.ts +0 -3
  263. package/dist/orchestration/process-platform.d.ts.map +1 -1
  264. package/dist/orchestration/process-platform.js +0 -4
  265. package/dist/orchestration/process-platform.js.map +1 -1
  266. package/dist/orchestration/process-turn.d.ts +8 -0
  267. package/dist/orchestration/process-turn.d.ts.map +1 -1
  268. package/dist/orchestration/process-turn.js +65 -8
  269. package/dist/orchestration/process-turn.js.map +1 -1
  270. package/dist/orchestration/response-errors.d.ts.map +1 -1
  271. package/dist/orchestration/response-errors.js +1 -0
  272. package/dist/orchestration/response-errors.js.map +1 -1
  273. package/dist/orchestration/runtime.d.ts +51 -1
  274. package/dist/orchestration/runtime.d.ts.map +1 -1
  275. package/dist/orchestration/runtime.js +383 -27
  276. package/dist/orchestration/runtime.js.map +1 -1
  277. package/dist/orchestration/skill-catalog-budget.d.ts +6 -0
  278. package/dist/orchestration/skill-catalog-budget.d.ts.map +1 -0
  279. package/dist/orchestration/skill-catalog-budget.js +9 -0
  280. package/dist/orchestration/skill-catalog-budget.js.map +1 -0
  281. package/dist/orchestration/skills.d.ts +4 -2
  282. package/dist/orchestration/skills.d.ts.map +1 -1
  283. package/dist/orchestration/skills.js +44 -3
  284. package/dist/orchestration/skills.js.map +1 -1
  285. package/dist/orchestration/store.d.ts +1 -0
  286. package/dist/orchestration/store.d.ts.map +1 -1
  287. package/dist/orchestration/store.js +2 -0
  288. package/dist/orchestration/store.js.map +1 -1
  289. package/dist/orchestration/task-controls.d.ts +78 -8
  290. package/dist/orchestration/task-controls.d.ts.map +1 -1
  291. package/dist/orchestration/task-controls.js +6 -1
  292. package/dist/orchestration/task-controls.js.map +1 -1
  293. package/dist/orchestration/tasks/automation-session.d.ts +25 -0
  294. package/dist/orchestration/tasks/automation-session.d.ts.map +1 -0
  295. package/dist/orchestration/tasks/automation-session.js +68 -0
  296. package/dist/orchestration/tasks/automation-session.js.map +1 -0
  297. package/dist/orchestration/tasks/driver.d.ts.map +1 -1
  298. package/dist/orchestration/tasks/driver.js +3 -2
  299. package/dist/orchestration/tasks/driver.js.map +1 -1
  300. package/dist/orchestration/tasks/service.d.ts +68 -7
  301. package/dist/orchestration/tasks/service.d.ts.map +1 -1
  302. package/dist/orchestration/tasks/service.js +646 -44
  303. package/dist/orchestration/tasks/service.js.map +1 -1
  304. package/dist/orchestration/types.d.ts +82 -3
  305. package/dist/orchestration/types.d.ts.map +1 -1
  306. package/dist/orchestration/types.js.map +1 -1
  307. package/dist/session/codex-extension-discovery.d.ts.map +1 -1
  308. package/dist/session/codex-extension-discovery.js +4 -2
  309. package/dist/session/codex-extension-discovery.js.map +1 -1
  310. package/dist/session/codex-native-mcp-client.d.ts.map +1 -1
  311. package/dist/session/codex-native-mcp-client.js +2 -1
  312. package/dist/session/codex-native-mcp-client.js.map +1 -1
  313. package/dist/session/codex-process.d.ts.map +1 -1
  314. package/dist/session/codex-process.js +9 -4
  315. package/dist/session/codex-process.js.map +1 -1
  316. package/dist/session/process.d.ts +16 -4
  317. package/dist/session/process.d.ts.map +1 -1
  318. package/dist/session/process.js +153 -75
  319. package/dist/session/process.js.map +1 -1
  320. package/dist/session/runtime-profile.d.ts +10 -5
  321. package/dist/session/runtime-profile.d.ts.map +1 -1
  322. package/dist/session/runtime-profile.js +5 -5
  323. package/dist/session/runtime-profile.js.map +1 -1
  324. package/dist/session/worker-extensions.d.ts.map +1 -1
  325. package/dist/session/worker-extensions.js +2 -1
  326. package/dist/session/worker-extensions.js.map +1 -1
  327. package/dist/types.d.ts +5 -0
  328. package/dist/types.d.ts.map +1 -1
  329. package/dist/ui/dashboard-client.d.ts.map +1 -1
  330. package/dist/ui/dashboard-client.js +33 -3
  331. package/dist/ui/dashboard-client.js.map +1 -1
  332. package/dist/ui/web-ui.js +1 -1
  333. package/lib/automation/browser-thinking.cjs +9 -0
  334. package/lib/automation/browser-thinking.d.cts +2 -0
  335. package/lib/automation/computer-thinking.cjs +10 -0
  336. package/lib/automation/computer-thinking.d.cts +2 -0
  337. package/lib/automation/index.cjs +47 -0
  338. package/lib/automation/index.d.cts +3 -0
  339. package/lib/automation/reasoning-instructions.cjs +5 -0
  340. package/lib/automation/thinking.cjs +35 -0
  341. package/lib/automation/thinking.d.cts +2 -0
  342. package/mcp/capability-catalog.ts +2 -2
  343. package/mcp/server.ts +1 -1
  344. package/mcp/tools/tasks/module.ts +9 -0
  345. package/package.json +5 -3
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.SessionProcess = exports.INTERRUPTED_NO_REPLY_TEXT = exports.MAX_HISTORY_MESSAGES = void 0;
40
40
  exports.resolveMaxHistoryMessages = resolveMaxHistoryMessages;
41
+ const child_env_1 = require("../jev/child-env");
41
42
  const worker_environment_1 = require("./worker-environment");
42
43
  const process_diagnostics_1 = require("./process-diagnostics");
43
44
  const managed_connectors_1 = require("./managed-connectors");
@@ -52,12 +53,12 @@ const path = __importStar(require("path"));
52
53
  const runtime_profile_1 = require("./runtime-profile");
53
54
  const string_decoder_1 = require("string_decoder");
54
55
  const process_supervisor_1 = require("../orchestration/process-supervisor");
55
- const process_platform_1 = require("../orchestration/process-platform");
56
56
  const capacity_1 = require("../orchestration/capacity");
57
+ const types_1 = require("../orchestration/types");
57
58
  const chokidar_1 = __importDefault(require("chokidar"));
58
59
  const knowledge_1 = require("../agent/knowledge");
59
60
  const config_1 = require("../agent/dreaming/config");
60
- const types_1 = require("../history/types");
61
+ const types_2 = require("../history/types");
61
62
  const logger_1 = require("../logger");
62
63
  const pty_stream_registry_1 = require("../shell/pty-stream-registry");
63
64
  const screen_1 = require("../shell/screen");
@@ -253,6 +254,10 @@ class SessionProcess extends events_1.EventEmitter {
253
254
  runtimeProfile) {
254
255
  super();
255
256
  this.runtimeProfile = runtimeProfile;
257
+ /** Bumped by stop(): a spawnProcess() that awaited across it abandons its spawn. */
258
+ this.spawnEpoch = 0;
259
+ // Bumped by every start(): a stop() still awaiting after one ran no longer owns the session's live state.
260
+ this.starts = 0;
256
261
  this.managedGroupStopped = false;
257
262
  this.lastActivityAt = Date.now(); // accessible by AgentRunner for eviction sort
258
263
  // Wall-clock time of the most recent BACKGROUND_DISPATCH_TOOLS tool_use seen
@@ -370,7 +375,7 @@ class SessionProcess extends events_1.EventEmitter {
370
375
  this.sessionId = sessionId;
371
376
  this.source = source;
372
377
  this.chatId = chatId ?? sessionId;
373
- this.sessionChannel = (0, types_1.toChatChannel)(source);
378
+ this.sessionChannel = (0, types_2.toChatChannel)(source);
374
379
  this.agentConfig = agentConfig;
375
380
  this.gatewayConfig = gatewayConfig;
376
381
  this.sessionStore = sessionStore;
@@ -422,6 +427,7 @@ class SessionProcess extends events_1.EventEmitter {
422
427
  return this.agentConfig.claude.model;
423
428
  }
424
429
  async start() {
430
+ this.starts++;
425
431
  this.stopping = false;
426
432
  this.restartCount = 0;
427
433
  this.setupRestartWatcher();
@@ -697,17 +703,22 @@ class SessionProcess extends events_1.EventEmitter {
697
703
  return false;
698
704
  return [...this.spawnedConnectors.keys()].some(id => name.startsWith(`mcp__${id}__`) && name.length > id.length + 7);
699
705
  }
700
- /** Host spawns where the command line is capped (Windows) move the appended
701
- * system prompt into a 0600 file beside the attempt's MCP config (a 0700
702
- * directory). Containers are skipped: their CLI sees container paths. */
706
+ /** The appended system prompt never travels on the command line: Windows caps a
707
+ * whole command line at 32767 characters and Linux caps ONE argument at 128 KiB
708
+ * (MAX_ARG_STRLEN), so a large workspace context or skill catalog would fail
709
+ * every spawn (#559); argv is also world-readable through /proc/<pid>/cmdline.
710
+ * The host CLI reads a 0600 file beside the attempt's MCP config (a 0700
711
+ * directory), named per spawn so stopping one spawn never removes another's.
712
+ * A container CLI reads one that prepareContainerProfile writes in its attempt
713
+ * directory, in the same docker exec as the attempt's mcp.json and ticket. */
703
714
  writeSystemPromptFile(args, mcpConfigPath) {
704
- if (!this.runtimeProfile || !(0, process_platform_1.commandLineLimited)() || this.agentConfig.type === 'app-agent')
715
+ if (!this.runtimeProfile)
705
716
  return args;
706
- const file = path.join(path.dirname(mcpConfigPath ?? this.runtimeProfile.mcpConfigPath), `system-prompt-${this.sessionId.replace(/[^\w.-]/g, '_')}.md`);
717
+ const file = path.join(path.dirname(mcpConfigPath ?? this.runtimeProfile.mcpConfigPath), `system-prompt-${this.sessionId.replace(/[^\w.-]/g, '_')}-${(0, crypto_1.randomUUID)()}.md`);
707
718
  const moved = (0, runtime_profile_1.appendSystemPromptViaFile)(args, file);
708
719
  if (moved.prompt === undefined)
709
720
  return args;
710
- fs.writeFileSync(file, moved.prompt, { mode: 0o600 });
721
+ fs.writeFileSync(file, moved.prompt, { mode: 0o600, flag: 'wx' });
711
722
  this.systemPromptPath = file;
712
723
  return moved.args;
713
724
  }
@@ -722,7 +733,11 @@ class SessionProcess extends events_1.EventEmitter {
722
733
  const { servers, connectors } = (0, managed_connectors_1.prepareManagedConnectors)(this.agentConfig, this.gatewayConfig, this.runtimeProfile, this.managedConnectorPaths);
723
734
  this.spawnedConnectors = new Map(Object.entries(connectors).map(([id, server]) => [id, connectorFingerprint(server)]));
724
735
  const configPath = path.join(path.dirname(this.runtimeProfile.mcpConfigPath), 'managed-connectors.json');
725
- fs.writeFileSync(configPath, JSON.stringify({ mcpServers: { ...servers, ...ticket.mcpServers } }), { mode: 0o600 });
736
+ const mcpServers = { ...servers, ...ticket.mcpServers };
737
+ for (const server of Object.values(mcpServers))
738
+ if (server?.env)
739
+ server.env = (0, child_env_1.sanitizeJevChildEnv)(server.env, this.gatewayConfig.gateway.jev);
740
+ fs.writeFileSync(configPath, JSON.stringify({ mcpServers }), { mode: 0o600 });
726
741
  fs.chmodSync(configPath, 0o600);
727
742
  this.managedMcpConfigPath = configPath;
728
743
  return configPath;
@@ -739,6 +754,7 @@ class SessionProcess extends events_1.EventEmitter {
739
754
  throw new Error('invalid session id');
740
755
  }
741
756
  fs.mkdirSync(sessionDir, { recursive: true, mode: 0o700 });
757
+ this.sessionDirPath = sessionDir;
742
758
  const mcpServerPath = path.resolve(__dirname, '..', '..', 'mcp', 'server.ts');
743
759
  // Merge stdio servers from Claude Code user + project configs (project overrides user).
744
760
  // Skip the gateway's own server names from both — gateway always generates its own
@@ -884,6 +900,9 @@ class SessionProcess extends events_1.EventEmitter {
884
900
  },
885
901
  };
886
902
  const configPath = path.join(sessionDir, 'mcp-config.json');
903
+ for (const server of Object.values(mcpConfig.mcpServers))
904
+ if (server?.env)
905
+ server.env = (0, child_env_1.sanitizeJevChildEnv)(server.env, this.gatewayConfig.gateway.jev);
887
906
  fs.writeFileSync(configPath, JSON.stringify(mcpConfig, null, 2), { mode: 0o600 });
888
907
  const serverNames = Object.keys(mcpConfig.mcpServers);
889
908
  this.logger.debug('MCP config written', { sessionId: this.sessionId, servers: serverNames });
@@ -915,7 +934,7 @@ class SessionProcess extends events_1.EventEmitter {
915
934
  const shared = (0, knowledge_1.resolveSharedConfig)(this.agentConfig.knowledge?.shared, this.gatewayConfig.gateway.knowledge?.shared).staleness;
916
935
  return (personal.enabled && personal.recordRetrievals) || (shared.enabled && shared.recordRetrievals) ? '1' : '';
917
936
  }
918
- buildArgs(mcpConfigPath, model) {
937
+ buildArgs(mcpConfigPath, model, containerAttempt = this.containerAttempt) {
919
938
  const args = [
920
939
  '--model', model,
921
940
  '--input-format', 'stream-json',
@@ -941,7 +960,7 @@ class SessionProcess extends events_1.EventEmitter {
941
960
  throw error;
942
961
  }
943
962
  }
944
- const profileArgs = (0, runtime_profile_1.runtimeProfileArgs)({ ...this.runtimeProfile, context, checkpointCommand: this.containerAttempt && this.runtimeProfile.checkpointCommand ? `node ${this.containerAttempt.directory}/checkpoint.cjs ${this.containerAttempt.directory}/ticket.json` : this.runtimeProfile.checkpointCommand, containerExecution: this.agentConfig.type === 'app-agent', mcpConfigPath: this.containerAttempt?.config ?? mcpConfigPath ?? this.runtimeProfile.mcpConfigPath, skillPluginDir: this.containerAttempt && this.runtimeProfile.skillPluginDir ? this.containerAttempt.directory + '/skill-plugin' : this.runtimeProfile.skillPluginDir }, this.agentConfig.claude.extraFlags ?? []);
963
+ const profileArgs = (0, runtime_profile_1.runtimeProfileArgs)({ ...this.runtimeProfile, context, checkpointCommand: containerAttempt && this.runtimeProfile.checkpointCommand ? `node ${containerAttempt.directory}/checkpoint.cjs ${containerAttempt.directory}/ticket.json` : this.runtimeProfile.checkpointCommand, containerExecution: this.agentConfig.type === 'app-agent', mcpConfigPath: containerAttempt?.config ?? mcpConfigPath ?? this.runtimeProfile.mcpConfigPath, skillPluginDir: containerAttempt && this.runtimeProfile.skillPluginDir ? containerAttempt.directory + '/skill-plugin' : this.runtimeProfile.skillPluginDir }, this.agentConfig.claude.extraFlags ?? []);
945
964
  args.push(...profileArgs);
946
965
  if (this.runtimeProfile.cliSession) {
947
966
  const session = this.runtimeProfile.cliSession;
@@ -979,15 +998,33 @@ class SessionProcess extends events_1.EventEmitter {
979
998
  message: { role: 'user', content: [{ type: 'text', text }, ...images] },
980
999
  });
981
1000
  }
1001
+ /** Resolves false when a stop() during its awaits abandoned the spawn: nothing was
1002
+ * started, and a container attempt it prepared is already cleaned up. */
982
1003
  async spawnProcess() {
1004
+ const epoch = this.spawnEpoch;
983
1005
  const { historyPrompt, loadedAtSpawn, archivedCount, messageCountAtSpawn } = await this.buildInitialPrompt();
1006
+ if (epoch !== this.spawnEpoch)
1007
+ return false;
984
1008
  this.spawnContext = { loadedAtSpawn, archivedCount, messageCountAtSpawn };
985
1009
  // Determine if this is a docker-exec app-agent before computing paths
986
1010
  (0, container_1.assertContainerBinding)(this.agentConfig, this.runtimeProfile);
987
1011
  const isAppAgent = this.agentConfig.type === 'app-agent' && !!this.agentConfig.container;
1012
+ const freshModel = this.readFreshModel();
1013
+ let containerArgs;
988
1014
  if (isAppAgent && this.runtimeProfile) {
989
- this.containerAttempt = await (0, container_1.prepareContainerProfile)(this.agentConfig, this.runtimeProfile);
990
- this.runtimeProfile.context = await (0, container_1.containerNode)(this.agentConfig.container, "process.stdout.write(require('fs').readFileSync('/workspace/CLAUDE.md','utf8'))");
1015
+ const profile = this.runtimeProfile, container = this.agentConfig.container;
1016
+ const attempt = await (0, container_1.prepareContainerProfile)(this.agentConfig, profile, async (directory) => {
1017
+ profile.context = await (0, container_1.containerNode)(container, "process.stdout.write(require('fs').readFileSync('/workspace/CLAUDE.md','utf8'))");
1018
+ const moved = (0, runtime_profile_1.appendSystemPromptViaFile)(this.buildArgs(null, freshModel, { directory, config: directory + '/mcp.json' }), directory + '/system-prompt.md');
1019
+ containerArgs = moved.args;
1020
+ return moved.prompt;
1021
+ });
1022
+ // stop() could not see this attempt yet; remove its ticket and prompt here.
1023
+ if (epoch !== this.spawnEpoch) {
1024
+ await (0, container_1.stopContainerProfile)(container, attempt.directory);
1025
+ return false;
1026
+ }
1027
+ this.containerAttempt = attempt;
991
1028
  }
992
1029
  const mcpConfigPath = this.writeMcpConfig();
993
1030
  // For app-agents, Claude runs inside the container where /workspace is mounted.
@@ -995,8 +1032,7 @@ class SessionProcess extends events_1.EventEmitter {
995
1032
  const toContainerPath = (hostPath) => `/workspace/${path.relative(this.agentConfig.workspace, hostPath)}`;
996
1033
  const effectiveMcpPath = (isAppAgent && mcpConfigPath) ? toContainerPath(mcpConfigPath) : mcpConfigPath;
997
1034
  const containerRestartPath = isAppAgent ? toContainerPath(this.restartSignalPath) : this.restartSignalPath;
998
- const freshModel = this.readFreshModel();
999
- const args = this.writeSystemPromptFile(this.buildArgs(effectiveMcpPath, freshModel), effectiveMcpPath);
1035
+ const args = containerArgs ?? this.writeSystemPromptFile(this.buildArgs(effectiveMcpPath, freshModel), mcpConfigPath);
1000
1036
  // Resolve the claude binary. An explicit CLAUDE_BIN (which may carry args) is
1001
1037
  // parsed by parseClaudeBin; otherwise probe PATH and the native-installer / legacy
1002
1038
  // install locations so a gateway launched with a minimal PATH still finds it.
@@ -1087,10 +1123,13 @@ class SessionProcess extends events_1.EventEmitter {
1087
1123
  containerUid = os.userInfo().uid;
1088
1124
  }
1089
1125
  catch { /* use 1000 */ }
1090
- const configuredWorkerEnvironment = this.runtimeProfile?.role === 'worker' ? (0, worker_environment_1.workerEnvironment)(this.agentConfig, this.gatewayConfig) : {};
1126
+ const configuredWorkerEnvironment = (0, child_env_1.sanitizeJevChildEnv)(this.runtimeProfile?.role === 'worker' ? (0, worker_environment_1.workerEnvironment)(this.agentConfig, this.gatewayConfig) : {}, this.gatewayConfig.gateway.jev);
1127
+ const turnEnvironment = this.runtimeProfile?.role === 'agent' && this.runtimeProfile.claudeEffort
1128
+ ? { CLAUDE_CODE_EFFORT_LEVEL: this.runtimeProfile.claudeEffort } : {};
1091
1129
  const containerEnv = {
1092
1130
  HOME: os.homedir(),
1093
1131
  CLAUDE_WORKSPACE: '/workspace',
1132
+ ...turnEnvironment,
1094
1133
  GATEWAY_RESTART_SIGNAL_PATH: containerRestartPath,
1095
1134
  };
1096
1135
  if (!this.runtimeProfile && process.env.GATEWAY_API_URL)
@@ -1109,6 +1148,8 @@ class SessionProcess extends events_1.EventEmitter {
1109
1148
  const dockerEnvFlags = [
1110
1149
  ...Object.entries(containerEnv).flatMap(([k, v]) => ['-e', `${k}=${v}`]),
1111
1150
  ...byNameKeys.flatMap((k) => ['-e', k]),
1151
+ // Also mask values baked into an existing container's own environment.
1152
+ ...(0, child_env_1.jevCredentialEnvNames)(this.gatewayConfig.gateway.jev).flatMap(k => ['-e', `${k}=`]),
1112
1153
  ];
1113
1154
  const spawnArgs = isAppAgent
1114
1155
  ? [
@@ -1146,13 +1187,14 @@ class SessionProcess extends events_1.EventEmitter {
1146
1187
  let proc;
1147
1188
  try {
1148
1189
  proc = (0, child_process_1.spawn)(spawnBin, spawnArgs, {
1149
- env: {
1190
+ env: (0, child_env_1.sanitizeJevChildEnv)({
1150
1191
  ...process.env,
1151
1192
  ...(!isAppAgent && this.runtimeProfile?.checkpointCommand && !this.runtimeProfile.hostExecution ? Object.fromEntries(CONTAINER_CREDENTIAL_KEYS.map(key => [key, undefined])) : {}),
1152
1193
  ...containerAuthEnv,
1153
1194
  ...(toolCapture ? { OTEL_LOG_RAW_API_BODIES: 'file:' + toolCapture.directory } : {}),
1154
1195
  ...(hardenedPath ? { PATH: hardenedPath } : {}),
1155
1196
  ...configuredWorkerEnvironment,
1197
+ ...turnEnvironment,
1156
1198
  GATEWAY_ORIGIN_SESSION_ID: this.runtimeProfile?.originSessionId ?? this.sessionId,
1157
1199
  GATEWAY_TASK_ID: this.runtimeProfile?.taskId ?? '',
1158
1200
  GATEWAY_TASK_ATTEMPT_ID: this.runtimeProfile?.attemptId ?? '',
@@ -1162,7 +1204,7 @@ class SessionProcess extends events_1.EventEmitter {
1162
1204
  ...(ptyRealBin ? { CLAUDE_REAL_BIN: ptyRealBin } : {}),
1163
1205
  ...(ptyHeartbeatPath ? { PTY_SHELL_HEARTBEAT_PATH: ptyHeartbeatPath } : {}),
1164
1206
  ...(ptyStreamSocketPath ? { PTY_SHELL_STREAM_SOCKET: ptyStreamSocketPath } : {}),
1165
- },
1207
+ }, this.gatewayConfig.gateway.jev),
1166
1208
  cwd: this.agentConfig.workspace,
1167
1209
  ...(this.runtimeProfile?.role === 'worker' && (0, process_supervisor_1.processSupervisorSupported)() && (0, process_supervisor_1.workerSpawnDetached)() ? { detached: true } : {}),
1168
1210
  windowsHide: true,
@@ -1172,9 +1214,18 @@ class SessionProcess extends events_1.EventEmitter {
1172
1214
  catch (error) {
1173
1215
  toolCapture?.close();
1174
1216
  releaseCapacity();
1217
+ // Node throws E2BIG/ENAMETOOLONG (and most other execve failures) from spawn()
1218
+ // itself; they never reach proc.on('error') below, so log them here. Sizes
1219
+ // only: the arguments may carry prompts and settings.
1220
+ const cause = error.code;
1221
+ const bytes = [spawnBin, ...spawnArgs].map(arg => Buffer.byteLength(arg));
1222
+ this.logger.error('session subprocess could not be spawned', { sessionId: this.sessionId, code: cause, argCount: bytes.length, largestArgBytes: Math.max(...bytes), totalArgBytes: bytes.reduce((sum, n) => sum + n, 0) });
1223
+ if (cause === 'E2BIG' || cause === 'ENAMETOOLONG')
1224
+ throw new types_1.OrchestrationError('PROCESS_ARGS_TOO_LARGE', `spawn ${cause}`);
1175
1225
  throw error;
1176
1226
  }
1177
1227
  this.process = proc;
1228
+ const startsAtSpawn = this.starts;
1178
1229
  proc.once('exit', releaseCapacity);
1179
1230
  proc.once('exit', () => { setTimeout(() => toolCapture?.close(), 200).unref(); });
1180
1231
  proc.once('error', () => toolCapture?.close());
@@ -1563,6 +1614,15 @@ class SessionProcess extends events_1.EventEmitter {
1563
1614
  });
1564
1615
  if (ptyStreamSocketPath)
1565
1616
  pty_stream_registry_1.ptyStreamRegistry.close(ptyStreamSocketPath);
1617
+ // A start() while an earlier stop() still waited for this exit owns the
1618
+ // session now, whether or not its child is attached yet; this exit is not
1619
+ // that session's death, so no 'exit' listener may see it and nothing restarts.
1620
+ // The stopped turn settles when its stop() resolves.
1621
+ if (this.starts !== startsAtSpawn || (this.process && this.process !== proc)) {
1622
+ if (this.process === proc)
1623
+ this.process = null;
1624
+ return;
1625
+ }
1566
1626
  this.process = null;
1567
1627
  this._exited = true;
1568
1628
  this.resetBackgroundDispatchState();
@@ -1608,6 +1668,7 @@ class SessionProcess extends events_1.EventEmitter {
1608
1668
  this.emit('startup-error', Object.assign(new Error(code), { code }));
1609
1669
  }
1610
1670
  });
1671
+ return true;
1611
1672
  }
1612
1673
  scheduleRestart() {
1613
1674
  // Graceful self-restart requested by agent — reset counter so it doesn't
@@ -1647,9 +1708,12 @@ class SessionProcess extends events_1.EventEmitter {
1647
1708
  // sendMessage() will no longer silently no-op. Emitted on every
1648
1709
  // successful crash-triggered respawn — cheap, and nothing currently
1649
1710
  // listens outside that one call site.
1650
- .then(() => {
1711
+ .then(spawned => {
1651
1712
  this._restartScheduled = false;
1652
- this.emit('restarted');
1713
+ if (spawned)
1714
+ this.emit('restarted');
1715
+ else
1716
+ this.emit('restartFailed', new Error('Session restart abandoned: session stopping'));
1653
1717
  })
1654
1718
  .catch(err => {
1655
1719
  this._restartScheduled = false;
@@ -2010,28 +2074,56 @@ class SessionProcess extends events_1.EventEmitter {
2010
2074
  if (this.diagnostics.outcome === 'pending' && !this.diagnostics.stopReason)
2011
2075
  this.diagnostics.stopReason = 'shutdown';
2012
2076
  this.stopping = true;
2013
- if (this.containerAttempt && this.agentConfig.container) {
2014
- this.managedGroupStopped = await (0, container_1.stopContainerProfile)(this.agentConfig.container, this.containerAttempt.directory);
2015
- this.containerAttempt = undefined;
2077
+ this.spawnEpoch++;
2078
+ // Take over what the spawn being stopped wrote, so a start() while this stop
2079
+ // still waits for the exit records its own files from scratch. Connector and
2080
+ // MCP config files keep fixed names, and such a start() rewrites them in place:
2081
+ // at the exit, removeSessionDir skips every path that newer spawn holds again.
2082
+ const owned = {
2083
+ systemPrompt: this.systemPromptPath,
2084
+ connectors: [...this.managedConnectorPaths],
2085
+ managedMcpConfig: this.managedMcpConfigPath,
2086
+ };
2087
+ this.systemPromptPath = undefined;
2088
+ this.managedConnectorPaths = new Set();
2089
+ this.managedMcpConfigPath = undefined;
2090
+ this.sessionDirPath = undefined;
2091
+ // The same for the spawn's live state: a start() during the awaits below
2092
+ // attaches its own child, group, attempt and watcher, which this stop must
2093
+ // neither signal nor clear. A newer stop() of that spawn handles them.
2094
+ const starts = this.starts;
2095
+ const superseded = () => this.starts !== starts;
2096
+ const proc = this.process;
2097
+ const attempt = this.containerAttempt;
2098
+ const group = this.managedProcessGroup;
2099
+ const watcher = this.restartWatcher;
2100
+ this.restartWatcher = null;
2101
+ let exited = false;
2102
+ const exit = proc ? new Promise(resolve => proc.once('exit', () => { exited = true; resolve(); })) : undefined;
2103
+ this.resetBackgroundDispatchState();
2104
+ if (attempt && this.agentConfig.container) {
2105
+ this.managedGroupStopped = await (0, container_1.stopContainerProfile)(this.agentConfig.container, attempt.directory);
2106
+ if (this.containerAttempt === attempt)
2107
+ this.containerAttempt = undefined;
2016
2108
  }
2017
- if (this.managedProcessGroup) {
2018
- const hostStopped = await (0, process_supervisor_1.stopProcessGroup)(this.managedProcessGroup);
2109
+ if (group) {
2110
+ const hostStopped = await (0, process_supervisor_1.stopProcessGroup)(group);
2019
2111
  this.managedGroupStopped = this.agentConfig.type === 'app-agent' ? this.managedGroupStopped && hostStopped : hostStopped;
2020
- if (this.managedGroupStopped)
2112
+ if (this.managedGroupStopped && this.managedProcessGroup === group)
2021
2113
  this.managedProcessGroup = undefined;
2022
2114
  }
2023
- this.resetBackgroundDispatchState();
2024
- await this.restartWatcher?.close();
2025
- this.restartWatcher = null;
2026
- try {
2027
- fs.rmSync(this.restartSignalPath, { force: true });
2028
- }
2029
- catch { }
2030
- if (this.source === 'telegram' && !this.runtimeProfile) {
2115
+ await watcher?.close();
2116
+ if (!superseded()) {
2031
2117
  try {
2032
- fs.rmSync(path.join(this.typingDir, `${this.chatId}.processing`), { force: true });
2118
+ fs.rmSync(this.restartSignalPath, { force: true });
2033
2119
  }
2034
2120
  catch { }
2121
+ if (this.source === 'telegram' && !this.runtimeProfile) {
2122
+ try {
2123
+ fs.rmSync(path.join(this.typingDir, `${this.chatId}.processing`), { force: true });
2124
+ }
2125
+ catch { }
2126
+ }
2035
2127
  }
2036
2128
  // mcp-config.json under here holds fully-substituted secrets (channel bot
2037
2129
  // tokens, GATEWAY_API_KEY, connector OAuth tokens) — it must not outlive
@@ -2041,56 +2133,42 @@ class SessionProcess extends events_1.EventEmitter {
2041
2133
  // subprocess (or, for a container agent, the still-running container that
2042
2134
  // bind-mounts this path) can be alive for up to the 10s graceful-shutdown
2043
2135
  // window immediately after this point, and must not find it gone under it.
2136
+ // A newer spawn that wrote the shared directory owns it now; its stop removes it.
2044
2137
  const removeSessionDir = () => {
2045
- for (const filename of this.managedConnectorPaths) {
2046
- try {
2047
- fs.rmSync(filename, { force: true });
2048
- }
2049
- catch { }
2050
- }
2051
- this.managedConnectorPaths.clear();
2052
- if (this.managedMcpConfigPath) {
2053
- try {
2054
- fs.rmSync(this.managedMcpConfigPath, { force: true });
2055
- }
2056
- catch { }
2057
- this.managedMcpConfigPath = undefined;
2058
- }
2059
- if (this.systemPromptPath) {
2060
- try {
2061
- fs.rmSync(this.systemPromptPath, { force: true });
2138
+ const reclaimed = (file) => this.managedConnectorPaths.has(file) || file === this.managedMcpConfigPath;
2139
+ for (const file of [...owned.connectors, owned.managedMcpConfig, owned.systemPrompt]) {
2140
+ if (file && !reclaimed(file)) {
2141
+ try {
2142
+ fs.rmSync(file, { force: true });
2143
+ }
2144
+ catch { }
2062
2145
  }
2063
- catch { }
2064
- this.systemPromptPath = undefined;
2065
2146
  }
2147
+ if (this.sessionDirPath)
2148
+ return;
2066
2149
  try {
2067
2150
  fs.rmSync(path.join(this.agentConfig.workspace, '.sessions', this.sessionId), { recursive: true, force: true });
2068
2151
  }
2069
2152
  catch { }
2070
2153
  };
2071
- if (!this.process) {
2154
+ // A child that failed to spawn never exits; its 'error' handler already let go of it.
2155
+ if (!proc || exited || (this.process !== proc && !proc.pid)) {
2072
2156
  removeSessionDir();
2073
2157
  return;
2074
2158
  }
2075
- return new Promise((resolve) => {
2076
- const proc = this.process;
2077
- let forceKillTimer = null;
2078
- proc.once('exit', () => {
2079
- if (forceKillTimer !== null) {
2080
- clearTimeout(forceKillTimer);
2081
- forceKillTimer = null;
2082
- }
2083
- this.process = null;
2084
- removeSessionDir();
2085
- resolve();
2086
- });
2087
- proc.kill('SIGTERM');
2088
- forceKillTimer = setTimeout(() => {
2089
- forceKillTimer = null;
2090
- if (this.process)
2091
- proc.kill('SIGKILL');
2092
- }, 10000);
2093
- });
2159
+ let forceKillTimer = null;
2160
+ proc.kill('SIGTERM');
2161
+ forceKillTimer = setTimeout(() => {
2162
+ forceKillTimer = null;
2163
+ if (!exited)
2164
+ proc.kill('SIGKILL');
2165
+ }, 10000);
2166
+ await exit;
2167
+ if (forceKillTimer !== null)
2168
+ clearTimeout(forceKillTimer);
2169
+ if (this.process === proc)
2170
+ this.process = null;
2171
+ removeSessionDir();
2094
2172
  }
2095
2173
  }
2096
2174
  exports.SessionProcess = SessionProcess;