visionclaw 0.1.218 → 0.1.219-dev.codex-issue-2805-worker-runtime.1

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 (595) hide show
  1. package/dist/agent/api-proxy.d.ts +0 -16
  2. package/dist/agent/api-proxy.d.ts.map +1 -1
  3. package/dist/agent/api-proxy.js +9 -8
  4. package/dist/agent/api-proxy.js.map +1 -1
  5. package/dist/agent/browser-launcher.d.ts +3 -0
  6. package/dist/agent/browser-launcher.d.ts.map +1 -1
  7. package/dist/agent/browser-launcher.js +101 -43
  8. package/dist/agent/browser-launcher.js.map +1 -1
  9. package/dist/agent/coding-conventions.d.ts +8 -0
  10. package/dist/agent/coding-conventions.d.ts.map +1 -0
  11. package/dist/agent/coding-conventions.js +19 -0
  12. package/dist/agent/coding-conventions.js.map +1 -0
  13. package/dist/agent/command-handlers.d.ts.map +1 -1
  14. package/dist/agent/command-handlers.js +4 -16
  15. package/dist/agent/command-handlers.js.map +1 -1
  16. package/dist/agent/context-action-restart-fallback.d.ts.map +1 -1
  17. package/dist/agent/context-action-restart-fallback.js +9 -3
  18. package/dist/agent/context-action-restart-fallback.js.map +1 -1
  19. package/dist/agent/context-refresh.d.ts.map +1 -1
  20. package/dist/agent/context-refresh.js +0 -7
  21. package/dist/agent/context-refresh.js.map +1 -1
  22. package/dist/agent/context.d.ts +2 -4
  23. package/dist/agent/context.d.ts.map +1 -1
  24. package/dist/agent/context.js +12 -21
  25. package/dist/agent/context.js.map +1 -1
  26. package/dist/agent/engine-fallback.d.ts +0 -35
  27. package/dist/agent/engine-fallback.d.ts.map +1 -1
  28. package/dist/agent/engine-fallback.js +4 -3
  29. package/dist/agent/engine-fallback.js.map +1 -1
  30. package/dist/agent/engine-switch.d.ts +19 -38
  31. package/dist/agent/engine-switch.d.ts.map +1 -1
  32. package/dist/agent/engine-switch.js +46 -111
  33. package/dist/agent/engine-switch.js.map +1 -1
  34. package/dist/agent/engines/browser-tool-policy.d.ts +12 -1
  35. package/dist/agent/engines/browser-tool-policy.d.ts.map +1 -1
  36. package/dist/agent/engines/browser-tool-policy.js +17 -2
  37. package/dist/agent/engines/browser-tool-policy.js.map +1 -1
  38. package/dist/agent/engines/claude/executor-shell-groups.d.ts +11 -0
  39. package/dist/agent/engines/claude/executor-shell-groups.d.ts.map +1 -0
  40. package/dist/agent/engines/claude/executor-shell-groups.js +22 -0
  41. package/dist/agent/engines/claude/executor-shell-groups.js.map +1 -0
  42. package/dist/agent/engines/claude/session.d.ts +13 -4
  43. package/dist/agent/engines/claude/session.d.ts.map +1 -1
  44. package/dist/agent/engines/claude/session.js +165 -84
  45. package/dist/agent/engines/claude/session.js.map +1 -1
  46. package/dist/agent/engines/pi/shared/usage.d.ts +5 -0
  47. package/dist/agent/engines/pi/shared/usage.d.ts.map +1 -1
  48. package/dist/agent/engines/pi/shared/usage.js +22 -3
  49. package/dist/agent/engines/pi/shared/usage.js.map +1 -1
  50. package/dist/agent/engines/pi/tools.d.ts +3 -10
  51. package/dist/agent/engines/pi/tools.d.ts.map +1 -1
  52. package/dist/agent/engines/pi/tools.js +6 -17
  53. package/dist/agent/engines/pi/tools.js.map +1 -1
  54. package/dist/agent/engines/pi-coding/executor-shell.d.ts +4 -0
  55. package/dist/agent/engines/pi-coding/executor-shell.d.ts.map +1 -0
  56. package/dist/agent/engines/pi-coding/executor-shell.js +175 -0
  57. package/dist/agent/engines/pi-coding/executor-shell.js.map +1 -0
  58. package/dist/agent/engines/pi-coding/session.d.ts +4 -4
  59. package/dist/agent/engines/pi-coding/session.d.ts.map +1 -1
  60. package/dist/agent/engines/pi-coding/session.js +118 -66
  61. package/dist/agent/engines/pi-coding/session.js.map +1 -1
  62. package/dist/agent/engines/pi-coding/tools.d.ts +2 -5
  63. package/dist/agent/engines/pi-coding/tools.d.ts.map +1 -1
  64. package/dist/agent/engines/pi-coding/tools.js +7 -5
  65. package/dist/agent/engines/pi-coding/tools.js.map +1 -1
  66. package/dist/agent/engines/session-types.d.ts +8 -8
  67. package/dist/agent/engines/session-types.d.ts.map +1 -1
  68. package/dist/agent/external-context/interrupt.d.ts +0 -2
  69. package/dist/agent/external-context/interrupt.d.ts.map +1 -1
  70. package/dist/agent/external-context/interrupt.js +0 -1
  71. package/dist/agent/external-context/interrupt.js.map +1 -1
  72. package/dist/agent/external-context/registry.d.ts +0 -2
  73. package/dist/agent/external-context/registry.d.ts.map +1 -1
  74. package/dist/agent/external-context/registry.js +2 -4
  75. package/dist/agent/external-context/registry.js.map +1 -1
  76. package/dist/agent/external-context/runtime.d.ts.map +1 -1
  77. package/dist/agent/external-context/runtime.js +15 -14
  78. package/dist/agent/external-context/runtime.js.map +1 -1
  79. package/dist/agent/external-context/types.d.ts +0 -2
  80. package/dist/agent/external-context/types.d.ts.map +1 -1
  81. package/dist/agent/fast-responder.d.ts +4 -20
  82. package/dist/agent/fast-responder.d.ts.map +1 -1
  83. package/dist/agent/fast-responder.js +28 -42
  84. package/dist/agent/fast-responder.js.map +1 -1
  85. package/dist/agent/interrupt-handler.d.ts +0 -6
  86. package/dist/agent/interrupt-handler.d.ts.map +1 -1
  87. package/dist/agent/interrupt-handler.js +5 -47
  88. package/dist/agent/interrupt-handler.js.map +1 -1
  89. package/dist/agent/lab-run-system-prompt.d.ts.map +1 -1
  90. package/dist/agent/lab-run-system-prompt.js +4 -1
  91. package/dist/agent/lab-run-system-prompt.js.map +1 -1
  92. package/dist/agent/lifecycle-trace.d.ts.map +1 -1
  93. package/dist/agent/lifecycle-trace.js +6 -5
  94. package/dist/agent/lifecycle-trace.js.map +1 -1
  95. package/dist/agent/loop.d.ts +8 -2
  96. package/dist/agent/loop.d.ts.map +1 -1
  97. package/dist/agent/loop.js +291 -156
  98. package/dist/agent/loop.js.map +1 -1
  99. package/dist/agent/memory-protocol.d.ts +2 -2
  100. package/dist/agent/memory-protocol.d.ts.map +1 -1
  101. package/dist/agent/memory-protocol.js +3 -15
  102. package/dist/agent/memory-protocol.js.map +1 -1
  103. package/dist/agent/memory-store.d.ts +58 -0
  104. package/dist/agent/memory-store.d.ts.map +1 -0
  105. package/dist/agent/memory-store.js +152 -0
  106. package/dist/agent/memory-store.js.map +1 -0
  107. package/dist/agent/model-provider.d.ts +18 -5
  108. package/dist/agent/model-provider.d.ts.map +1 -1
  109. package/dist/agent/model-provider.js +58 -18
  110. package/dist/agent/model-provider.js.map +1 -1
  111. package/dist/agent/nightly-maintenance/dreaming-batch.d.ts +184 -0
  112. package/dist/agent/nightly-maintenance/dreaming-batch.d.ts.map +1 -0
  113. package/dist/agent/nightly-maintenance/dreaming-batch.js +192 -0
  114. package/dist/agent/nightly-maintenance/dreaming-batch.js.map +1 -0
  115. package/dist/agent/nightly-maintenance/dreaming-files.d.ts +48 -0
  116. package/dist/agent/nightly-maintenance/dreaming-files.d.ts.map +1 -0
  117. package/dist/agent/nightly-maintenance/dreaming-files.js +109 -0
  118. package/dist/agent/nightly-maintenance/dreaming-files.js.map +1 -0
  119. package/dist/agent/nightly-maintenance/dreaming-ledger.d.ts +62 -0
  120. package/dist/agent/nightly-maintenance/dreaming-ledger.d.ts.map +1 -0
  121. package/dist/agent/nightly-maintenance/dreaming-ledger.js +146 -0
  122. package/dist/agent/nightly-maintenance/dreaming-ledger.js.map +1 -0
  123. package/dist/agent/nightly-maintenance/dreaming-planner.d.ts +86 -0
  124. package/dist/agent/nightly-maintenance/dreaming-planner.d.ts.map +1 -0
  125. package/dist/agent/nightly-maintenance/dreaming-planner.js +304 -0
  126. package/dist/agent/nightly-maintenance/dreaming-planner.js.map +1 -0
  127. package/dist/agent/nightly-maintenance/dreaming-runner.d.ts +93 -0
  128. package/dist/agent/nightly-maintenance/dreaming-runner.d.ts.map +1 -0
  129. package/dist/agent/nightly-maintenance/dreaming-runner.js +156 -0
  130. package/dist/agent/nightly-maintenance/dreaming-runner.js.map +1 -0
  131. package/dist/agent/nightly-maintenance/dreaming-sources.d.ts +115 -0
  132. package/dist/agent/nightly-maintenance/dreaming-sources.d.ts.map +1 -0
  133. package/dist/agent/nightly-maintenance/dreaming-sources.js +270 -0
  134. package/dist/agent/nightly-maintenance/dreaming-sources.js.map +1 -0
  135. package/dist/agent/nightly-maintenance/index.d.ts +28 -8
  136. package/dist/agent/nightly-maintenance/index.d.ts.map +1 -1
  137. package/dist/agent/nightly-maintenance/index.js +42 -15
  138. package/dist/agent/nightly-maintenance/index.js.map +1 -1
  139. package/dist/agent/nightly-maintenance/skill-learning-gate.js +1 -1
  140. package/dist/agent/nightly-maintenance/skill-learning-gate.js.map +1 -1
  141. package/dist/agent/nightly-maintenance/vocabulary-processor.d.ts +1 -1
  142. package/dist/agent/nightly-maintenance/vocabulary-processor.d.ts.map +1 -1
  143. package/dist/agent/owner-channel-resolver.d.ts +2 -0
  144. package/dist/agent/owner-channel-resolver.d.ts.map +1 -1
  145. package/dist/agent/owner-channel-resolver.js +4 -0
  146. package/dist/agent/owner-channel-resolver.js.map +1 -1
  147. package/dist/agent/product-identity.d.ts +5 -4
  148. package/dist/agent/product-identity.d.ts.map +1 -1
  149. package/dist/agent/product-identity.js +7 -6
  150. package/dist/agent/product-identity.js.map +1 -1
  151. package/dist/agent/public-activity.js +1 -1
  152. package/dist/agent/public-activity.js.map +1 -1
  153. package/dist/agent/runtime-context.d.ts +27 -0
  154. package/dist/agent/runtime-context.d.ts.map +1 -0
  155. package/dist/agent/runtime-context.js +60 -0
  156. package/dist/agent/runtime-context.js.map +1 -0
  157. package/dist/agent/runtime-disclosure-policy.d.ts +6 -0
  158. package/dist/agent/runtime-disclosure-policy.d.ts.map +1 -0
  159. package/dist/agent/runtime-disclosure-policy.js +16 -0
  160. package/dist/agent/runtime-disclosure-policy.js.map +1 -0
  161. package/dist/agent/runtime-surface.d.ts +15 -4
  162. package/dist/agent/runtime-surface.d.ts.map +1 -1
  163. package/dist/agent/runtime-surface.js +0 -1
  164. package/dist/agent/runtime-surface.js.map +1 -1
  165. package/dist/agent/session-manager.d.ts +30 -126
  166. package/dist/agent/session-manager.d.ts.map +1 -1
  167. package/dist/agent/session-manager.js +60 -484
  168. package/dist/agent/session-manager.js.map +1 -1
  169. package/dist/agent/state.d.ts +42 -2
  170. package/dist/agent/state.d.ts.map +1 -1
  171. package/dist/agent/state.js +21 -11
  172. package/dist/agent/state.js.map +1 -1
  173. package/dist/agent/stream-handler.d.ts +6 -13
  174. package/dist/agent/stream-handler.d.ts.map +1 -1
  175. package/dist/agent/stream-handler.js +8 -62
  176. package/dist/agent/stream-handler.js.map +1 -1
  177. package/dist/agent/system-prompt.d.ts +2 -0
  178. package/dist/agent/system-prompt.d.ts.map +1 -1
  179. package/dist/agent/system-prompt.js +21 -20
  180. package/dist/agent/system-prompt.js.map +1 -1
  181. package/dist/agent/tool-usage.d.ts.map +1 -1
  182. package/dist/agent/tool-usage.js +0 -1
  183. package/dist/agent/tool-usage.js.map +1 -1
  184. package/dist/agent/transcript/transcript-backfill.js +3 -3
  185. package/dist/agent/transcript/transcript-backfill.js.map +1 -1
  186. package/dist/agent/transcript/transcript-indexer.d.ts +3 -31
  187. package/dist/agent/transcript/transcript-indexer.d.ts.map +1 -1
  188. package/dist/agent/transcript/transcript-indexer.js +58 -57
  189. package/dist/agent/transcript/transcript-indexer.js.map +1 -1
  190. package/dist/agent/transcript-parsers/trivial-tools.d.ts.map +1 -1
  191. package/dist/agent/transcript-parsers/trivial-tools.js +0 -2
  192. package/dist/agent/transcript-parsers/trivial-tools.js.map +1 -1
  193. package/dist/agent/transcript-parsers/types.d.ts +1 -1
  194. package/dist/agent/transcript-summarizer.d.ts +14 -0
  195. package/dist/agent/transcript-summarizer.d.ts.map +1 -1
  196. package/dist/agent/transcript-summarizer.js +69 -45
  197. package/dist/agent/transcript-summarizer.js.map +1 -1
  198. package/dist/agent/usage/usage-report-queue.d.ts.map +1 -1
  199. package/dist/agent/usage/usage-report-queue.js +53 -52
  200. package/dist/agent/usage/usage-report-queue.js.map +1 -1
  201. package/dist/agent/usage/usage-report-types.d.ts +1 -1
  202. package/dist/agent/usage/usage-report-types.d.ts.map +1 -1
  203. package/dist/agent/vocabulary-glossary.d.ts +3 -3
  204. package/dist/agent/wake-cycle-runner.d.ts +22 -17
  205. package/dist/agent/wake-cycle-runner.d.ts.map +1 -1
  206. package/dist/agent/wake-cycle-runner.js +190 -320
  207. package/dist/agent/wake-cycle-runner.js.map +1 -1
  208. package/dist/builtin-skills/owner-manual/SKILL.md +2 -2
  209. package/dist/calendar/occurrence-ownership.d.ts.map +1 -1
  210. package/dist/calendar/occurrence-ownership.js +6 -5
  211. package/dist/calendar/occurrence-ownership.js.map +1 -1
  212. package/dist/calendar/scheduler.d.ts.map +1 -1
  213. package/dist/calendar/scheduler.js +4 -3
  214. package/dist/calendar/scheduler.js.map +1 -1
  215. package/dist/channels/interface.d.ts +8 -2
  216. package/dist/channels/interface.d.ts.map +1 -1
  217. package/dist/channels/interface.js +8 -1
  218. package/dist/channels/interface.js.map +1 -1
  219. package/dist/channels/manager.d.ts +12 -0
  220. package/dist/channels/manager.d.ts.map +1 -1
  221. package/dist/channels/manager.js +97 -8
  222. package/dist/channels/manager.js.map +1 -1
  223. package/dist/channels/queue.d.ts.map +1 -1
  224. package/dist/channels/queue.js +8 -0
  225. package/dist/channels/queue.js.map +1 -1
  226. package/dist/channels/telegram.d.ts.map +1 -1
  227. package/dist/channels/telegram.js +28 -2
  228. package/dist/channels/telegram.js.map +1 -1
  229. package/dist/channels/tui.d.ts +14 -1
  230. package/dist/channels/tui.d.ts.map +1 -1
  231. package/dist/channels/tui.js +64 -2
  232. package/dist/channels/tui.js.map +1 -1
  233. package/dist/channels/unavailable-target.d.ts +20 -0
  234. package/dist/channels/unavailable-target.d.ts.map +1 -0
  235. package/dist/channels/unavailable-target.js +82 -0
  236. package/dist/channels/unavailable-target.js.map +1 -0
  237. package/dist/cli/index.d.ts +2 -2
  238. package/dist/cli/index.d.ts.map +1 -1
  239. package/dist/cli/index.js +22 -53
  240. package/dist/cli/index.js.map +1 -1
  241. package/dist/config/index.d.ts +13 -7
  242. package/dist/config/index.d.ts.map +1 -1
  243. package/dist/config/index.js +51 -64
  244. package/dist/config/index.js.map +1 -1
  245. package/dist/config/types.d.ts +28 -7
  246. package/dist/config/types.d.ts.map +1 -1
  247. package/dist/config/types.js +22 -20
  248. package/dist/config/types.js.map +1 -1
  249. package/dist/conversations/lazy-runtime.d.ts +5 -0
  250. package/dist/conversations/lazy-runtime.d.ts.map +1 -0
  251. package/dist/conversations/lazy-runtime.js +12 -0
  252. package/dist/conversations/lazy-runtime.js.map +1 -0
  253. package/dist/conversations/runtime.d.ts +17 -0
  254. package/dist/conversations/runtime.d.ts.map +1 -0
  255. package/dist/conversations/runtime.js +92 -0
  256. package/dist/conversations/runtime.js.map +1 -0
  257. package/dist/conversations/scheduler.d.ts +57 -0
  258. package/dist/conversations/scheduler.d.ts.map +1 -0
  259. package/dist/conversations/scheduler.js +175 -0
  260. package/dist/conversations/scheduler.js.map +1 -0
  261. package/dist/data-processing/pipeline.d.ts +0 -2
  262. package/dist/data-processing/pipeline.d.ts.map +1 -1
  263. package/dist/data-processing/pipeline.js +19 -24
  264. package/dist/data-processing/pipeline.js.map +1 -1
  265. package/dist/data-processing/restructure.d.ts +0 -2
  266. package/dist/data-processing/restructure.d.ts.map +1 -1
  267. package/dist/data-processing/restructure.js +6 -9
  268. package/dist/data-processing/restructure.js.map +1 -1
  269. package/dist/data-processing/types.d.ts +2 -9
  270. package/dist/data-processing/types.d.ts.map +1 -1
  271. package/dist/data-processing/types.js +2 -13
  272. package/dist/data-processing/types.js.map +1 -1
  273. package/dist/email/email-route-store.d.ts.map +1 -1
  274. package/dist/email/email-route-store.js +6 -5
  275. package/dist/email/email-route-store.js.map +1 -1
  276. package/dist/i18n/messages.d.ts +26 -2
  277. package/dist/i18n/messages.d.ts.map +1 -1
  278. package/dist/i18n/messages.js +30 -5
  279. package/dist/i18n/messages.js.map +1 -1
  280. package/dist/index.js.map +1 -1
  281. package/dist/logger.d.ts +11 -0
  282. package/dist/logger.d.ts.map +1 -1
  283. package/dist/logger.js +49 -1
  284. package/dist/logger.js.map +1 -1
  285. package/dist/obs/mini-app/status.d.ts.map +1 -1
  286. package/dist/obs/mini-app/status.js +0 -1
  287. package/dist/obs/mini-app/status.js.map +1 -1
  288. package/dist/onboarding/onboarding-service-client.d.ts +1 -0
  289. package/dist/onboarding/onboarding-service-client.d.ts.map +1 -1
  290. package/dist/onboarding/onboarding-service-client.js.map +1 -1
  291. package/dist/onboarding/remote-set-owner.d.ts.map +1 -1
  292. package/dist/onboarding/remote-set-owner.js +0 -1
  293. package/dist/onboarding/remote-set-owner.js.map +1 -1
  294. package/dist/onboarding/set-owner.d.ts +1 -1
  295. package/dist/onboarding/set-owner.d.ts.map +1 -1
  296. package/dist/onboarding/set-owner.js +3 -6
  297. package/dist/onboarding/set-owner.js.map +1 -1
  298. package/dist/reconfigure.d.ts.map +1 -1
  299. package/dist/reconfigure.js +1 -32
  300. package/dist/reconfigure.js.map +1 -1
  301. package/dist/reset.d.ts.map +1 -1
  302. package/dist/reset.js +3 -1
  303. package/dist/reset.js.map +1 -1
  304. package/dist/threads/active-threads-store.d.ts.map +1 -1
  305. package/dist/threads/active-threads-store.js +8 -27
  306. package/dist/threads/active-threads-store.js.map +1 -1
  307. package/dist/threads/dreaming-execution.d.ts +10 -0
  308. package/dist/threads/dreaming-execution.d.ts.map +1 -0
  309. package/dist/threads/dreaming-execution.js +78 -0
  310. package/dist/threads/dreaming-execution.js.map +1 -0
  311. package/dist/threads/execution-authority.d.ts +43 -0
  312. package/dist/threads/execution-authority.d.ts.map +1 -0
  313. package/dist/threads/execution-authority.js +75 -0
  314. package/dist/threads/execution-authority.js.map +1 -0
  315. package/dist/threads/execution-budget.d.ts +107 -0
  316. package/dist/threads/execution-budget.d.ts.map +1 -0
  317. package/dist/threads/execution-budget.js +257 -0
  318. package/dist/threads/execution-budget.js.map +1 -0
  319. package/dist/threads/execution-host.d.ts +17 -0
  320. package/dist/threads/execution-host.d.ts.map +1 -0
  321. package/dist/threads/execution-host.js +66 -0
  322. package/dist/threads/execution-host.js.map +1 -0
  323. package/dist/threads/execution-scheduler.d.ts +162 -0
  324. package/dist/threads/execution-scheduler.d.ts.map +1 -0
  325. package/dist/threads/execution-scheduler.js +413 -0
  326. package/dist/threads/execution-scheduler.js.map +1 -0
  327. package/dist/threads/execution-snapshot.d.ts +91 -0
  328. package/dist/threads/execution-snapshot.d.ts.map +1 -0
  329. package/dist/threads/execution-snapshot.js +146 -0
  330. package/dist/threads/execution-snapshot.js.map +1 -0
  331. package/dist/threads/execution-store.d.ts +374 -0
  332. package/dist/threads/execution-store.d.ts.map +1 -0
  333. package/dist/threads/execution-store.js +910 -0
  334. package/dist/threads/execution-store.js.map +1 -0
  335. package/dist/threads/execution-thread-error.d.ts +9 -0
  336. package/dist/threads/execution-thread-error.d.ts.map +1 -0
  337. package/dist/threads/execution-thread-error.js +12 -0
  338. package/dist/threads/execution-thread-error.js.map +1 -0
  339. package/dist/threads/executor-exit.d.ts +18 -0
  340. package/dist/threads/executor-exit.d.ts.map +1 -0
  341. package/dist/threads/executor-exit.js +21 -0
  342. package/dist/threads/executor-exit.js.map +1 -0
  343. package/dist/threads/foreground-task.d.ts +91 -0
  344. package/dist/threads/foreground-task.d.ts.map +1 -0
  345. package/dist/threads/foreground-task.js +191 -0
  346. package/dist/threads/foreground-task.js.map +1 -0
  347. package/dist/threads/foreman-business.d.ts +9 -0
  348. package/dist/threads/foreman-business.d.ts.map +1 -0
  349. package/dist/threads/foreman-business.js +117 -0
  350. package/dist/threads/foreman-business.js.map +1 -0
  351. package/dist/threads/foreman-client.d.ts +18 -0
  352. package/dist/threads/foreman-client.d.ts.map +1 -0
  353. package/dist/threads/foreman-client.js +51 -0
  354. package/dist/threads/foreman-client.js.map +1 -0
  355. package/dist/threads/foreman-delivery.d.ts +5 -0
  356. package/dist/threads/foreman-delivery.d.ts.map +1 -0
  357. package/dist/threads/foreman-delivery.js +21 -0
  358. package/dist/threads/foreman-delivery.js.map +1 -0
  359. package/dist/threads/foreman-execution.d.ts +32 -0
  360. package/dist/threads/foreman-execution.d.ts.map +1 -0
  361. package/dist/threads/foreman-execution.js +90 -0
  362. package/dist/threads/foreman-execution.js.map +1 -0
  363. package/dist/threads/foreman-host.d.ts +77 -0
  364. package/dist/threads/foreman-host.d.ts.map +1 -0
  365. package/dist/threads/foreman-host.js +891 -0
  366. package/dist/threads/foreman-host.js.map +1 -0
  367. package/dist/threads/foreman-protocol.d.ts +242 -0
  368. package/dist/threads/foreman-protocol.d.ts.map +1 -0
  369. package/dist/threads/foreman-protocol.js +116 -0
  370. package/dist/threads/foreman-protocol.js.map +1 -0
  371. package/dist/threads/foreman-store.d.ts +151 -0
  372. package/dist/threads/foreman-store.d.ts.map +1 -0
  373. package/dist/threads/foreman-store.js +299 -0
  374. package/dist/threads/foreman-store.js.map +1 -0
  375. package/dist/threads/generic-execution.d.ts +25 -0
  376. package/dist/threads/generic-execution.d.ts.map +1 -0
  377. package/dist/threads/generic-execution.js +86 -0
  378. package/dist/threads/generic-execution.js.map +1 -0
  379. package/dist/threads/init-thread-dir.d.ts +2 -2
  380. package/dist/threads/init-thread-dir.d.ts.map +1 -1
  381. package/dist/threads/init-thread-dir.js +6 -6
  382. package/dist/threads/init-thread-dir.js.map +1 -1
  383. package/dist/threads/ipc.d.ts +108 -2
  384. package/dist/threads/ipc.d.ts.map +1 -1
  385. package/dist/threads/ipc.js +14 -2
  386. package/dist/threads/ipc.js.map +1 -1
  387. package/dist/threads/lab-run-thread.d.ts +3 -5
  388. package/dist/threads/lab-run-thread.d.ts.map +1 -1
  389. package/dist/threads/lab-run-thread.js +3 -5
  390. package/dist/threads/lab-run-thread.js.map +1 -1
  391. package/dist/threads/lab-runtime-policy.d.ts +26 -21
  392. package/dist/threads/lab-runtime-policy.d.ts.map +1 -1
  393. package/dist/threads/lab-runtime-policy.js +31 -126
  394. package/dist/threads/lab-runtime-policy.js.map +1 -1
  395. package/dist/threads/process-group.d.ts +41 -0
  396. package/dist/threads/process-group.d.ts.map +1 -0
  397. package/dist/threads/process-group.js +161 -0
  398. package/dist/threads/process-group.js.map +1 -0
  399. package/dist/threads/relay-adapter.d.ts +8 -0
  400. package/dist/threads/relay-adapter.d.ts.map +1 -1
  401. package/dist/threads/relay-adapter.js +26 -1
  402. package/dist/threads/relay-adapter.js.map +1 -1
  403. package/dist/threads/supervisor.d.ts +191 -57
  404. package/dist/threads/supervisor.d.ts.map +1 -1
  405. package/dist/threads/supervisor.js +766 -427
  406. package/dist/threads/supervisor.js.map +1 -1
  407. package/dist/threads/task-workspace.d.ts +8 -0
  408. package/dist/threads/task-workspace.d.ts.map +1 -0
  409. package/dist/threads/task-workspace.js +52 -0
  410. package/dist/threads/task-workspace.js.map +1 -0
  411. package/dist/threads/worker-entry.d.ts.map +1 -1
  412. package/dist/threads/worker-entry.js +314 -34
  413. package/dist/threads/worker-entry.js.map +1 -1
  414. package/dist/threads/worker-execution-runtime.d.ts +75 -0
  415. package/dist/threads/worker-execution-runtime.d.ts.map +1 -0
  416. package/dist/threads/worker-execution-runtime.js +142 -0
  417. package/dist/threads/worker-execution-runtime.js.map +1 -0
  418. package/dist/threads/worker-execution.d.ts +35 -0
  419. package/dist/threads/worker-execution.d.ts.map +1 -0
  420. package/dist/threads/worker-execution.js +2 -0
  421. package/dist/threads/worker-execution.js.map +1 -0
  422. package/dist/threads/worker-runtime-policy.d.ts +42 -0
  423. package/dist/threads/worker-runtime-policy.d.ts.map +1 -0
  424. package/dist/threads/worker-runtime-policy.js +98 -0
  425. package/dist/threads/worker-runtime-policy.js.map +1 -0
  426. package/dist/tools/adapter-tool.d.ts +12 -0
  427. package/dist/tools/adapter-tool.d.ts.map +1 -0
  428. package/dist/tools/adapter-tool.js +2 -0
  429. package/dist/tools/adapter-tool.js.map +1 -0
  430. package/dist/tools/data-service.d.ts +2 -2
  431. package/dist/tools/delegation.d.ts +121 -0
  432. package/dist/tools/delegation.d.ts.map +1 -0
  433. package/dist/tools/delegation.js +106 -0
  434. package/dist/tools/delegation.js.map +1 -0
  435. package/dist/tools/dream-memory.d.ts +122 -0
  436. package/dist/tools/dream-memory.d.ts.map +1 -0
  437. package/dist/tools/dream-memory.js +513 -0
  438. package/dist/tools/dream-memory.js.map +1 -0
  439. package/dist/tools/email.d.ts +1 -1
  440. package/dist/tools/execution-control.d.ts +31 -0
  441. package/dist/tools/execution-control.d.ts.map +1 -0
  442. package/dist/tools/execution-control.js +71 -0
  443. package/dist/tools/execution-control.js.map +1 -0
  444. package/dist/tools/index.d.ts +5 -7
  445. package/dist/tools/index.d.ts.map +1 -1
  446. package/dist/tools/index.js +7 -13
  447. package/dist/tools/index.js.map +1 -1
  448. package/dist/tools/mcp-manager.d.ts +1 -1
  449. package/dist/tools/memory.d.ts +1 -1
  450. package/dist/tools/memory.d.ts.map +1 -1
  451. package/dist/tools/memory.js +69 -45
  452. package/dist/tools/memory.js.map +1 -1
  453. package/dist/tools/notify.d.ts +5 -0
  454. package/dist/tools/notify.d.ts.map +1 -1
  455. package/dist/tools/notify.js +45 -10
  456. package/dist/tools/notify.js.map +1 -1
  457. package/dist/tools/skill.d.ts +1 -1
  458. package/dist/tools/totp.d.ts +1 -1
  459. package/dist/tui/client.d.ts +1 -16
  460. package/dist/tui/client.d.ts.map +1 -1
  461. package/dist/tui/client.js +0 -4
  462. package/dist/tui/client.js.map +1 -1
  463. package/dist/tui/index.d.ts.map +1 -1
  464. package/dist/tui/index.js +0 -41
  465. package/dist/tui/index.js.map +1 -1
  466. package/dist/tui/protocol.d.ts +2 -1
  467. package/dist/tui/protocol.d.ts.map +1 -1
  468. package/dist/tui/protocol.js +2 -1
  469. package/dist/tui/protocol.js.map +1 -1
  470. package/dist/tui/renderer.d.ts.map +1 -1
  471. package/dist/tui/renderer.js +0 -5
  472. package/dist/tui/renderer.js.map +1 -1
  473. package/dist/tui/request-store.d.ts +1 -1
  474. package/dist/tui/request-store.d.ts.map +1 -1
  475. package/dist/tui/request-store.js +2 -2
  476. package/dist/tui/request-store.js.map +1 -1
  477. package/dist/tui/server.d.ts.map +1 -1
  478. package/dist/tui/server.js +137 -25
  479. package/dist/tui/server.js.map +1 -1
  480. package/dist/utils/claude-transcripts.d.ts +6 -0
  481. package/dist/utils/claude-transcripts.d.ts.map +1 -1
  482. package/dist/utils/claude-transcripts.js +8 -2
  483. package/dist/utils/claude-transcripts.js.map +1 -1
  484. package/dist/utils/restart.d.ts.map +1 -1
  485. package/dist/utils/restart.js +6 -0
  486. package/dist/utils/restart.js.map +1 -1
  487. package/dist-agent/bundle.cjs +2 -2
  488. package/package.json +1 -1
  489. package/dist/agent/mailbox.d.ts +0 -50
  490. package/dist/agent/mailbox.d.ts.map +0 -1
  491. package/dist/agent/mailbox.js +0 -124
  492. package/dist/agent/mailbox.js.map +0 -1
  493. package/dist/agent/nightly-maintenance/memory-dreaming-sweep.d.ts +0 -77
  494. package/dist/agent/nightly-maintenance/memory-dreaming-sweep.d.ts.map +0 -1
  495. package/dist/agent/nightly-maintenance/memory-dreaming-sweep.js +0 -158
  496. package/dist/agent/nightly-maintenance/memory-dreaming-sweep.js.map +0 -1
  497. package/dist/agent/nightly-maintenance/memory-dreaming.d.ts +0 -116
  498. package/dist/agent/nightly-maintenance/memory-dreaming.d.ts.map +0 -1
  499. package/dist/agent/nightly-maintenance/memory-dreaming.js +0 -458
  500. package/dist/agent/nightly-maintenance/memory-dreaming.js.map +0 -1
  501. package/dist/builtin-skills/catalog/phone-adb-automation/SKILL.md +0 -412
  502. package/dist/builtin-skills/catalog/phone-adb-automation/phone_input.sh +0 -132
  503. package/dist/builtin-skills/catalog/phone-adb-automation/phone_launch.sh +0 -166
  504. package/dist/builtin-skills/catalog/phone-adb-automation/phone_screenshot.sh +0 -87
  505. package/dist/builtin-skills/catalog/phone-adb-automation/phone_security_kbd.py +0 -174
  506. package/dist/builtin-skills/catalog/phone-adb-automation/phone_setup.sh +0 -274
  507. package/dist/builtin-skills/catalog/phone-adb-automation/phone_swipe.sh +0 -111
  508. package/dist/builtin-skills/catalog/phone-adb-automation/phone_tap.sh +0 -87
  509. package/dist/builtin-skills/catalog/phone-adb-automation/phone_ui_parse.py +0 -176
  510. package/dist/builtin-skills/catalog/phone-adb-automation/phone_wake_unlock.sh +0 -67
  511. package/dist/builtin-skills/macos-automation/SKILL.md +0 -132
  512. package/dist/builtin-skills/transcribe-audio/SKILL.md +0 -122
  513. package/dist/builtin-skills/visionclaw-manual/SKILL.md +0 -337
  514. package/dist/obs/rdp/icons/icons/app_windows.svg +0 -4
  515. package/dist/obs/rdp/icons/icons/clip_get.svg +0 -4
  516. package/dist/obs/rdp/icons/icons/clip_send.svg +0 -4
  517. package/dist/obs/rdp/icons/icons/clip_shared.svg +0 -4
  518. package/dist/obs/rdp/icons/icons/clipboard.svg +0 -4
  519. package/dist/obs/rdp/icons/icons/clipboard_shared.svg +0 -4
  520. package/dist/obs/rdp/icons/icons/control.svg +0 -4
  521. package/dist/obs/rdp/icons/icons/desktop.svg +0 -4
  522. package/dist/obs/rdp/icons/icons/display.svg +0 -4
  523. package/dist/obs/rdp/icons/icons/launchpad.svg +0 -4
  524. package/dist/obs/rdp/icons/icons/mission_control.svg +0 -4
  525. package/dist/obs/rdp/icons/icons/screenshot.svg +0 -4
  526. package/dist/obs/rdp/icons/icons/zoom_actual.svg +0 -4
  527. package/dist/obs/rdp/icons/icons/zoom_fit.svg +0 -4
  528. package/dist/obs/rdp/icons/icons/zoom_in.svg +0 -4
  529. package/dist/obs/rdp/icons/icons/zoom_out.svg +0 -4
  530. package/dist/realtime/assets/index.html +0 -1058
  531. package/dist/realtime/assets/samples/alloy.mp3 +0 -0
  532. package/dist/realtime/assets/samples/ash.mp3 +0 -0
  533. package/dist/realtime/assets/samples/ballad.mp3 +0 -0
  534. package/dist/realtime/assets/samples/cedar.mp3 +0 -0
  535. package/dist/realtime/assets/samples/coral.mp3 +0 -0
  536. package/dist/realtime/assets/samples/echo.mp3 +0 -0
  537. package/dist/realtime/assets/samples/marin.mp3 +0 -0
  538. package/dist/realtime/assets/samples/sage.mp3 +0 -0
  539. package/dist/realtime/assets/samples/shimmer.mp3 +0 -0
  540. package/dist/realtime/assets/samples/verse.mp3 +0 -0
  541. package/dist/threads/task-contracts.d.ts +0 -194
  542. package/dist/threads/task-contracts.d.ts.map +0 -1
  543. package/dist/threads/task-contracts.js +0 -82
  544. package/dist/threads/task-contracts.js.map +0 -1
  545. package/dist/threads/task-sidecar.d.ts +0 -143
  546. package/dist/threads/task-sidecar.d.ts.map +0 -1
  547. package/dist/threads/task-sidecar.js +0 -309
  548. package/dist/threads/task-sidecar.js.map +0 -1
  549. package/dist/threads/task-store.d.ts +0 -172
  550. package/dist/threads/task-store.d.ts.map +0 -1
  551. package/dist/threads/task-store.js +0 -594
  552. package/dist/threads/task-store.js.map +0 -1
  553. package/dist/threads/thread-task-context.d.ts +0 -40
  554. package/dist/threads/thread-task-context.d.ts.map +0 -1
  555. package/dist/threads/thread-task-context.js +0 -159
  556. package/dist/threads/thread-task-context.js.map +0 -1
  557. package/dist/threads/thread-task-controller.d.ts +0 -122
  558. package/dist/threads/thread-task-controller.d.ts.map +0 -1
  559. package/dist/threads/thread-task-controller.js +0 -276
  560. package/dist/threads/thread-task-controller.js.map +0 -1
  561. package/dist/threads/thread-task-runtime.d.ts +0 -320
  562. package/dist/threads/thread-task-runtime.d.ts.map +0 -1
  563. package/dist/threads/thread-task-runtime.js +0 -843
  564. package/dist/threads/thread-task-runtime.js.map +0 -1
  565. package/dist/tools/switch-session.d.ts +0 -15
  566. package/dist/tools/switch-session.d.ts.map +0 -1
  567. package/dist/tools/switch-session.js +0 -88
  568. package/dist/tools/switch-session.js.map +0 -1
  569. package/dist/tools/thread-tasks.d.ts +0 -10
  570. package/dist/tools/thread-tasks.d.ts.map +0 -1
  571. package/dist/tools/thread-tasks.js +0 -88
  572. package/dist/tools/thread-tasks.js.map +0 -1
  573. package/dist-agent/assets/index.html +0 -1058
  574. package/dist-agent/assets/samples/alloy.mp3 +0 -0
  575. package/dist-agent/assets/samples/ash.mp3 +0 -0
  576. package/dist-agent/assets/samples/ballad.mp3 +0 -0
  577. package/dist-agent/assets/samples/cedar.mp3 +0 -0
  578. package/dist-agent/assets/samples/coral.mp3 +0 -0
  579. package/dist-agent/assets/samples/echo.mp3 +0 -0
  580. package/dist-agent/assets/samples/marin.mp3 +0 -0
  581. package/dist-agent/assets/samples/sage.mp3 +0 -0
  582. package/dist-agent/assets/samples/shimmer.mp3 +0 -0
  583. package/dist-agent/assets/samples/verse.mp3 +0 -0
  584. package/dist-agent/playwriter-relay.cjs +0 -95
  585. package/dist-agent/realtime/assets/index.html +0 -1058
  586. package/dist-agent/realtime/assets/samples/alloy.mp3 +0 -0
  587. package/dist-agent/realtime/assets/samples/ash.mp3 +0 -0
  588. package/dist-agent/realtime/assets/samples/ballad.mp3 +0 -0
  589. package/dist-agent/realtime/assets/samples/cedar.mp3 +0 -0
  590. package/dist-agent/realtime/assets/samples/coral.mp3 +0 -0
  591. package/dist-agent/realtime/assets/samples/echo.mp3 +0 -0
  592. package/dist-agent/realtime/assets/samples/marin.mp3 +0 -0
  593. package/dist-agent/realtime/assets/samples/sage.mp3 +0 -0
  594. package/dist-agent/realtime/assets/samples/shimmer.mp3 +0 -0
  595. package/dist-agent/realtime/assets/samples/verse.mp3 +0 -0
@@ -6,20 +6,19 @@
6
6
  *
7
7
  * - HeartbeatManager: runtime heartbeat lifecycle
8
8
  * - ReplyWatchdog: fast-responder fallback timer
9
- * - WakeCycleRunner: session switch loop, stream processing, error retry,
9
+ * - WakeCycleRunner: wake loop, stream processing, error retry,
10
10
  * transcript indexing
11
11
  * - InterruptHandler: mid-turn message injection
12
- * - SessionManager: dual-session management
12
+ * - SessionManager: conversation session management
13
13
  * - ChannelManager: messaging channel adapters
14
14
  */
15
15
  import { createDefaultExternalContextRegistry, ExternalContextRegistry } from "./external-context/registry.js";
16
- import { randomUUID } from "node:crypto";
16
+ import { createHash, randomUUID } from "node:crypto";
17
17
  import { beginLifecycleRun, createLifecycleRunId, deriveShadowLifecycleState, endLifecycleRun, traceLifecycle, traceShadowLifecycle } from "./lifecycle-trace.js";
18
- import { endForegroundWake } from "./lifecycle-transitions.js";
19
- import { isProactiveWakeEnabled, isThreadTasksEnabled, isTunnelEnabled, isWorkspaceEnabled } from "../config/types.js";
20
- import { DEFAULT_THREAD_ID, resolveThreadId } from "../channels/interface.js";
18
+ import { closeHostEntry, endForegroundWake } from "./lifecycle-transitions.js";
19
+ import { isProactiveWakeEnabled, isTunnelEnabled, isWorkspaceEnabled } from "../config/types.js";
20
+ import { DEFAULT_THREAD_ID, normalizeChannelName, resolveThreadId } from "../channels/interface.js";
21
21
  import { buildSystemPrompt } from "./system-prompt.js";
22
- import { buildLabRunSystemPrompt } from "./lab-run-system-prompt.js";
23
22
  import { SessionManager } from "./session-manager.js";
24
23
  import { buildWakeContext } from "./context.js";
25
24
  import { MessageQueue } from "../channels/queue.js";
@@ -28,7 +27,7 @@ import { ActivityTracker } from "./activity-tracker.js";
28
27
  import { ThreadActivityController } from "../threads/thread-activity-controller.js";
29
28
  import { shouldNotifyUpdate } from "../utils/version-check.js";
30
29
  import { shouldRunProactiveUpgradeCheck } from "./update-reminder-policy.js";
31
- import { getConfigFile, loadOwnerConfig, consumePendingUpgrade, consumePendingRestart, writePendingRestart, getConfigDir, ownerConfigExists, saveOwnerConfig, deleteOnboardingSession, } from "../config/index.js";
30
+ import { loadOwnerConfig, consumePendingUpgrade, consumePendingRestart, writePendingRestart, getConfigDir, ownerConfigExists, saveOwnerConfig, deleteOnboardingSession, } from "../config/index.js";
32
31
  import { syncSystemTimezone } from "../utils/timezone.js";
33
32
  import { logger } from "../logger.js";
34
33
  import { cleanOldScreenshots } from "../tools/screenshot.js";
@@ -41,7 +40,7 @@ import { runOnboardingGate } from "./onboarding-gate.js";
41
40
  import { OnboardingServiceClient } from "../onboarding/onboarding-service-client.js";
42
41
  import { deliverPendingQqWelcome, sendWelcomeMessages } from "../onboarding/send-invite.js";
43
42
  import { resumePendingChannelBinding } from "../onboarding/resume-channel-binding.js";
44
- import { answerAndDrop, executionGateReply, persistedServiceStopped, runServiceGate, serviceGateMessage, shouldEnforceServiceGate } from "./service-gate.js";
43
+ import { answerAndDrop, executionGateReply, runServiceGate, serviceGateMessage, shouldEnforceServiceGate } from "./service-gate.js";
45
44
  import { InterruptHandler } from "./interrupt-handler.js";
46
45
  import { ownerTranscriptionContext } from "../transcription-context.js";
47
46
  import { transcribeVoiceMessages } from "../utils/transcribe.js";
@@ -56,13 +55,14 @@ import { t, resolveLocale } from "../i18n/index.js";
56
55
  import { formatMessageSummary, previewIncomingForConsole, buildIncomingLogData } from "./message-format.js";
57
56
  import { buildReplyMapKeyFromMessage, buildReplyTarget, groupActivityDeliveryTargetForMessage, resolveTaskReplyTarget } from "./reply-target.js";
58
57
  import { notifyOwnerViaResolvedChain } from "./owner-notify.js";
59
- import { hasUsableOwnerChannel } from "./owner-channel-resolver.js";
58
+ import { hasUsableOwnerChannel, listBoundOwnerChannels, resolveOwnerDefaultTarget } from "./owner-channel-resolver.js";
59
+ import { runForemanBusinessRead } from "../threads/foreman-business.js";
60
60
  import { buildRuntimeSurface, } from "./runtime-surface.js";
61
61
  import { getAgentEngine } from "./engines/engine-factory.js";
62
62
  import { prepareEngineSwitchBoundary } from "./engine-switch.js";
63
63
  import { getClaudeTranscriptDirForProfileDir } from "../utils/claude-transcripts.js";
64
- import { isLabRunThreadId } from "../threads/lab-run-thread.js";
65
- import { applyLabRuntimePolicyToSurface, loadWorkerLabRuntimePolicy } from "../threads/lab-runtime-policy.js";
64
+ import { applyWorkerRuntimePolicyToSurface, isolateWorkerConfig } from "../threads/worker-runtime-policy.js";
65
+ import { noteMessagesHandedToModel } from "../threads/worker-execution-runtime.js";
66
66
  import { closeTranscriptMemoryDb } from "./transcript/transcript-indexer.js";
67
67
  import { closeUsageReportQueue } from "./usage/usage-report-queue.js";
68
68
  import { maybeAutoBackfill, cancelAutoBackfill } from "./transcript/transcript-backfill.js";
@@ -83,17 +83,20 @@ import { normalizeAgentFeedback } from "./feedback.js";
83
83
  import { AgentFeedbackOutbox } from "./feedback-outbox.js";
84
84
  import { scheduleRestart, detectProcessManager, restartManagedProcess } from "../utils/restart.js";
85
85
  import { NightlyMaintenance, NIGHTLY_RESTART_MIN_UPTIME_MS } from "./nightly-maintenance/index.js";
86
- import { resolveDreamingTargets, runDreamingJob } from "./nightly-maintenance/memory-dreaming-sweep.js";
87
- import { readDeepNightDreamDay } from "./nightly-maintenance/memory-dreaming.js";
86
+ import { DreamingPlanner } from "./nightly-maintenance/dreaming-planner.js";
87
+ import { DreamingRunner } from "./nightly-maintenance/dreaming-runner.js";
88
88
  import { maintainGlossary } from "./vocabulary-glossary.js";
89
89
  import { isOwnerInitiatedMessage } from "./owner-initiated-eligibility.js";
90
90
  import { retireLegacyServices } from "../service/retired-services.js";
91
91
  import { backfillMissingThreadApplications, migrateLegacyThreadApplications, threadApplicationBackfillHealthEvent } from "../threads/application-migration.js";
92
- import { currentApplicationContext, inheritThreadApplication } from "../threads/application-context.js";
92
+ import { currentApplicationContext, inheritThreadApplication, threadApplication } from "../threads/application-context.js";
93
+ import { ForemanHost } from "../threads/foreman-host.js";
94
+ import { ForemanStore } from "../threads/foreman-store.js";
95
+ import { canDelegateTasks, foremanEventsOf, getForemanClient, installForemanClient, isForemanRuntime, supportsTaskRuntime } from "../threads/foreman-protocol.js";
96
+ import { ForegroundTaskTracker, installForegroundTaskTracker } from "../threads/foreground-task.js";
93
97
  import { ThreadApplicationConflict } from "../threads/thread-meta.js";
94
98
  import { assertRuntimeApplicationId } from "../config/application-config.js";
95
99
  import { migrateProfileToAgentsMd } from "../config/agents-md-migration.js";
96
- import { ThreadTaskRuntime, endWakeThreadTasks, isTaskRelevantMessage, isTaskResumeMessage, retireStaleResume, setThreadTaskRuntime, } from "../threads/thread-task-runtime.js";
97
100
  /**
98
101
  * Grace period before an idle cross-runtime engine recovery restarts.
99
102
  * Short on purpose: the gate only fires when nothing is in flight.
@@ -103,25 +106,38 @@ export { getAgentState } from "./state.js";
103
106
  // Track the current SIGUSR2 handler so we can swap it out without
104
107
  // removing listeners registered by other subsystems.
105
108
  let activeSigusr2Handler = null;
106
- /** Lab workers drain their local queue until it stays empty for this long. */
107
- const LAB_IDLE_GRACE_MS = 10_000;
109
+ /** Bounded workers drain their local queue until it stays empty for this long. */
110
+ const WORKER_EXECUTION_IDLE_GRACE_MS = 10_000;
108
111
  /**
109
112
  * Main agent loop. This is the entry point that runs forever.
110
113
  */
111
114
  export async function startAgentLoop(config, options) {
115
+ if (options?.signal?.aborted)
116
+ return;
112
117
  const workerMode = options?.workerMode ?? null;
113
- const labRuntimePolicy = workerMode && isLabRunThreadId(workerMode.threadId)
114
- ? loadWorkerLabRuntimePolicy(workerMode.threadId)
115
- : null;
118
+ const workerExecution = workerMode?.execution ?? null;
119
+ if (workerMode && workerExecution) {
120
+ // Enforce isolation at the shared entry point, before channels, context or
121
+ // model services are initialized. Callers need only supply the execution.
122
+ workerMode.relay.restrictToInternalExecution();
123
+ config = isolateWorkerConfig(config);
124
+ }
116
125
  // Thread supervisor (main process, multi-thread mode). Assigned during init
117
126
  // when enabled; used to refresh cross-thread awareness before each wake.
118
127
  let threadSupervisor = null;
128
+ // Foreman host, next to the supervisor in the main process (#2805).
129
+ let activeForemanHost = null;
130
+ // Set once agent state exists. Until then a background-task update is only
131
+ // queued; the loop's first iteration finds it.
132
+ let wakeGeneralLoop = null;
119
133
  // HeartbeatManager is constructed after the supervisor and several awaited
120
134
  // startup gates. Do not close over that later `const` — recovered workers
121
135
  // and live inbound messages can fire these callbacks while it is still in
122
136
  // the temporal dead zone.
123
137
  let heartbeatForSupervisor = null;
124
138
  let nightlyMaintenance = null;
139
+ // Dreaming batches run as maintenance executions on the thread supervisor.
140
+ let dreamingRunner = null;
125
141
  let maintenanceRequested = false;
126
142
  // =====================================================================
127
143
  // 1. Initialization
@@ -163,19 +179,6 @@ export async function startAgentLoop(config, options) {
163
179
  // orphaned worker can no longer commit claims owned by its successor.
164
180
  ...(workerMode ? { ownerId: workerMode.relay.workerInstanceId } : {}),
165
181
  });
166
- // Thread task store (#1996): opened by the same queue owner at the same
167
- // moment it recovers in-flight claims, and fenced by the same identity.
168
- // Lab runs are single-shot and keep no task list. Off unless the local
169
- // config opts in (`threadTasksEnabled: true`). Null means disabled for
170
- // this process; everything else behaves exactly as before.
171
- const threadTasks = labRuntimePolicy || !isThreadTasksEnabled(config)
172
- ? null
173
- : ThreadTaskRuntime.start({
174
- threadId: executionContext.threadId,
175
- writerId: workerMode ? workerMode.relay.workerInstanceId : randomUUID(),
176
- config,
177
- });
178
- setThreadTaskRuntime(threadTasks);
179
182
  const channelManager = new ChannelManager(config, messageQueue);
180
183
  const activityTracker = new ActivityTracker();
181
184
  const mainActivityController = workerMode
@@ -194,22 +197,93 @@ export async function startAgentLoop(config, options) {
194
197
  // --- Thread supervisor (multi-thread architecture) ---
195
198
  // Install before adapters start: connect/hello can immediately replay work.
196
199
  // Recover old queues after channels are available for replies.
197
- // Main process only. Spawns/routes worker processes for non-default threads
198
- // via the ChannelManager threadRouter hook. Disabled in worker mode (workers
199
- // never route to sub-workers) and when multiThread is turned off in config.
200
- if (!workerMode && config.multiThread.enabled) {
200
+ // The host routes chats to in-process conversations and admitted Tasks to
201
+ // the independent worker pool. Execution workers never spawn nested hosts.
202
+ if (!workerMode) {
201
203
  const { ThreadSupervisor } = await import("../threads/supervisor.js");
204
+ // Foreman (#2805): the host owns General's background tasks, their
205
+ // delivery obligations and fallback. Built before the supervisor so the
206
+ // supervisor can route workers' commands and `general` events to it.
207
+ let foremanHost = null;
208
+ let taskStore = null;
202
209
  const supervisor = new ThreadSupervisor({
203
210
  channelManager,
204
211
  messageQueue,
205
212
  deferRecovery: true,
206
- maxConcurrentThreads: config.multiThread.maxConcurrentThreads,
213
+ maxConcurrentThreads: config.workers?.maxConcurrent ?? config.multiThread.maxConcurrentThreads,
207
214
  idleTimeoutMs: config.multiThread.idleTtlMs,
208
215
  config,
209
216
  desktopRuntimeResolution: options?.desktopRuntimeResolution,
210
217
  browserRuntimeResolution: options?.browserRuntimeResolution,
211
218
  onFeedback: (feedback) => heartbeatForSupervisor?.enqueueFeedback(feedback),
212
219
  onBusyChange: () => heartbeatForSupervisor?.nudge(),
220
+ onMaintenanceInput: () => dreamingRunner?.preempt(),
221
+ deliverExecutionEvent: (event, caller) => {
222
+ // Maintenance reads its executions from the store when they end.
223
+ if (caller.kind === "nightly")
224
+ return Promise.resolve(true);
225
+ if (caller.kind === "general")
226
+ return foremanHost?.deliverEvent(event, caller) ?? Promise.resolve(false);
227
+ if (caller.kind !== "tui")
228
+ return Promise.resolve(false);
229
+ return Promise.resolve(channelManager.getAdapter("tui") !== undefined);
230
+ },
231
+ // Workers install a Foreman client only when Foreman is on; this answers
232
+ // for the worker the supervisor actually talks to.
233
+ handleForemanCommand: (threadId, command) => foremanHost?.handle(threadId, command)
234
+ ?? Promise.resolve({ ok: false, text: "Error: background tasks are not available in this conversation." }),
235
+ handleForemanBusinessRead: (executionId, command, workspace) => foremanHost?.readBusiness(executionId, command.tool, command.args, workspace)
236
+ ?? Promise.resolve({ ok: false, text: "Business reads are unavailable" }),
237
+ });
238
+ supervisor.onExecutionEvent((event, caller) => {
239
+ if (caller.kind !== "tui")
240
+ return;
241
+ channelManager.getAdapter("tui")?.publishExecutionEvent(event);
242
+ });
243
+ const foremanExecutions = supervisor.executionService();
244
+ if (foremanExecutions) {
245
+ const store = new ForemanStore();
246
+ taskStore = store;
247
+ foremanHost = new ForemanHost({
248
+ canReadBusiness: (_threadId, target) => isWorkspaceEnabled(config) && target !== null
249
+ && listBoundOwnerChannels(config, loadOwnerConfig()).some((owner) => owner.validationStatus === "verified"
250
+ && owner.kind === "dm" && normalizeChannelName(owner.channel) === normalizeChannelName(target.channel) && owner.to === target.to),
251
+ readBusiness: runForemanBusinessRead,
252
+ allowDelegation: () => isForemanRuntime(config),
253
+ executions: foremanExecutions,
254
+ store,
255
+ enqueueToGeneral: (threadId, message) => {
256
+ if (threadId === DEFAULT_THREAD_ID) {
257
+ messageQueue.enqueue(message);
258
+ wakeGeneralLoop?.();
259
+ return;
260
+ }
261
+ // The conversation's durable queue and application admission.
262
+ const app = threadApplication(threadId, config);
263
+ if (!supervisor.tryRouteMessage({ ...message, threadId, ...(app ? { app } : {}) }, threadId)) {
264
+ throw new Error(`Thread ${threadId} did not accept a background-task update`);
265
+ }
266
+ },
267
+ deliver: (target, text, threadId) => channelManager.tryDeliver(target, text, {
268
+ logContext: "background task delivery",
269
+ context: { kind: "task_update", ...(threadId === DEFAULT_THREAD_ID ? {} : { businessThreadId: threadId }) },
270
+ }),
271
+ ownerTarget: () => {
272
+ const owner = resolveOwnerDefaultTarget(config, loadOwnerConfig());
273
+ return owner ? { channel: owner.channel, to: owner.to } : null;
274
+ },
275
+ locale: () => resolveLocale(loadOwnerConfig().language),
276
+ });
277
+ const host = foremanHost;
278
+ installForemanClient(supportsTaskRuntime() ? { delegationEnabled: isForemanRuntime(config), request: (command) => host.handle(DEFAULT_THREAD_ID, command) } : null);
279
+ }
280
+ activeForemanHost = foremanHost;
281
+ // Keep the Task ledger and delivery adapters alive until conversations and
282
+ // workers settle. Their final receipts may still arrive during shutdown.
283
+ registerShutdownCallback(async () => {
284
+ foremanHost?.stop();
285
+ await supervisor.shutdownAll();
286
+ taskStore?.close();
213
287
  });
214
288
  channelManager.setThreadRouter((msg, threadId) => supervisor.routeMessage(msg, threadId));
215
289
  // Expose for the main-loop wake context to refresh its own awareness.
@@ -247,16 +321,14 @@ export async function startAgentLoop(config, options) {
247
321
  catch (err) {
248
322
  logger.warn(`Graceful shutdown did not complete cleanly: ${err instanceof Error ? err.message : String(err)}`);
249
323
  }
250
- // After the channels, so it never delays them. A short grace lets an
251
- // in-flight sidecar call commit; unconsumed events wait for the next start.
252
- await threadTasks?.close(2_000);
253
324
  messageQueue.close();
254
325
  logger.system("Graceful shutdown complete.");
255
326
  });
256
327
  // Runtime logs and active Claude/Pi transcripts share one provider-neutral
257
328
  // upload path. Each worker owns a thread-local spool, so worker crashes and
258
329
  // network outages cannot lose or corrupt the main process queue.
259
- const runtimeTelemetry = startRuntimeTelemetryShipper(config, {
330
+ // A private-content execution (Dreaming) never ships its transcripts or logs.
331
+ const runtimeTelemetry = workerExecution?.privateContent ? null : startRuntimeTelemetryShipper(config, {
260
332
  ...(workerMode ? { threadId: workerMode.threadId } : {}),
261
333
  });
262
334
  registerShutdownCallback(async () => {
@@ -264,11 +336,10 @@ export async function startAgentLoop(config, options) {
264
336
  });
265
337
  if (threadSupervisor) {
266
338
  threadSupervisor.recoverPendingThreads();
267
- const supervisor = threadSupervisor;
268
- registerShutdownCallback(async () => {
269
- logger.system("Graceful shutdown: stopping thread workers...");
270
- await supervisor.shutdownAll();
271
- });
339
+ // After channels start, so delivered results reach their adapters.
340
+ threadSupervisor.startExecutions();
341
+ // Its first sweep sends fallbacks a restart left overdue.
342
+ activeForemanHost?.start();
272
343
  }
273
344
  // --- Resume an interrupted channel binding ---
274
345
  // Runs BEFORE the onboarding gate on purpose. A binding whose completion tail
@@ -304,6 +375,10 @@ export async function startAgentLoop(config, options) {
304
375
  const justRestarted = workerMode ? null : consumePendingRestart();
305
376
  const ownerConfig = loadOwnerConfig();
306
377
  if (!workerMode) {
378
+ channelManager.setOwnerDefaultTargetResolver(() => {
379
+ const owner = resolveOwnerDefaultTarget(config, loadOwnerConfig());
380
+ return owner ? { channel: owner.channel, to: owner.to } : undefined;
381
+ });
307
382
  await syncSystemTimezone(ownerConfig.timezone, config.systemPassword);
308
383
  }
309
384
  // Runtime config changes need to re-arm the current sleep without turning
@@ -317,8 +392,8 @@ export async function startAgentLoop(config, options) {
317
392
  wakeResolver = null;
318
393
  }
319
394
  }
320
- /** Wait for LabRun queue work or for the worker's idle grace period to elapse. */
321
- function waitForLabQueueOrIdle() {
395
+ /** Wait for execution queue work or for the worker's idle grace period to elapse. */
396
+ function waitForExecutionQueueOrIdle() {
322
397
  if (!messageQueue.isEmpty())
323
398
  return Promise.resolve(true);
324
399
  return new Promise((resolve) => {
@@ -341,7 +416,7 @@ export async function startAgentLoop(config, options) {
341
416
  finish();
342
417
  return;
343
418
  }
344
- timer = setTimeout(finish, LAB_IDLE_GRACE_MS);
419
+ timer = setTimeout(finish, WORKER_EXECUTION_IDLE_GRACE_MS);
345
420
  });
346
421
  }
347
422
  // --- Heartbeat manager ---
@@ -441,7 +516,6 @@ export async function startAgentLoop(config, options) {
441
516
  hasRepliedInCycle: false,
442
517
  notifiedUserThisWake: false,
443
518
  liveAssistantTexts: new Set(),
444
- codingCompletionTaskStartedAt: undefined,
445
519
  restartTunnel: options?.restartTunnel,
446
520
  commandDispatcher: heartbeat.commandDispatcher,
447
521
  compacting: false,
@@ -463,9 +537,18 @@ export async function startAgentLoop(config, options) {
463
537
  getActiveThreads: activeThreadSupervisor
464
538
  ? () => activeThreadSupervisor.getThreadsOverview()
465
539
  : undefined,
540
+ executions: activeThreadSupervisor?.executionService() ?? undefined,
466
541
  };
467
542
  initAgentState(agentState);
468
543
  const executionOwner = new ExecutionOwner(agentState);
544
+ wakeGeneralLoop = wakeMainLoop;
545
+ // Foreman's foreground limit, for conversational sessions that can delegate.
546
+ // Thread-local: getConfigDir() is the thread's own directory in a worker.
547
+ // Skill Learning drives this same session and is exempt.
548
+ const foregroundTasks = !workerExecution && canDelegateTasks()
549
+ ? new ForegroundTaskTracker(getConfigDir(), () => new Date(), () => agentState.learning)
550
+ : null;
551
+ installForegroundTaskTracker(foregroundTasks);
469
552
  // Arm the always-on runtime heartbeat loop now that `agentState` is
470
553
  // wired. Workers deliberately skip runtime heartbeat; `heartbeat.nudge()`
471
554
  // remains safe because it no-ops until startRuntime() is called.
@@ -526,8 +609,13 @@ export async function startAgentLoop(config, options) {
526
609
  }
527
610
  const builtRuntime = await buildRuntimeSurface(config, options?.desktopRuntimeResolution, options?.browserRuntimeResolution);
528
611
  const startupDynamicMcpServerCount = builtRuntime.startupDynamicMcpServerCount;
529
- const runtimeSurface = labRuntimePolicy
530
- ? applyLabRuntimePolicyToSurface(builtRuntime.runtimeSurface, labRuntimePolicy)
612
+ // The host applies the restriction last; an adapter supplies only its tool
613
+ // registrations, and the host-owned budget is attached after everything else.
614
+ const runtimeSurface = workerExecution
615
+ ? {
616
+ ...applyWorkerRuntimePolicyToSurface(builtRuntime.runtimeSurface, workerExecution.policy, workerExecution.adapterTools),
617
+ executionBudget: workerExecution.budget,
618
+ }
531
619
  : builtRuntime.runtimeSurface;
532
620
  const finAppCapabilityChangedDuringBuild = finAppCapabilityState.active !== null &&
533
621
  finAppCapabilityState.active !== runtimeSurface.credentialBacked.finApp;
@@ -564,11 +652,10 @@ export async function startAgentLoop(config, options) {
564
652
  logger.system(`Loaded ${startupDynamicMcpServerCount} dynamic MCP server(s) from disk`);
565
653
  }
566
654
  // --- Engine switch boundary -----------------------------------------
567
- // If any prior transcript was written by a different engine than
568
- // `config.json` currently selects, collapse general + coding into a
569
- // single fresh general session with a combined summary. This must
570
- // run BEFORE constructing SessionManager so the manager sees the
571
- // post-collapse mailbox (no coding session to resume).
655
+ // If the prior transcript was written by a different engine than
656
+ // `config.json` currently selects, retire it into a fresh session with a
657
+ // summary. This must run BEFORE constructing SessionManager so the
658
+ // manager does not resume the retired session id.
572
659
  const currentEngine = getAgentEngine(config);
573
660
  let engineSwitchBoundary = null;
574
661
  try {
@@ -578,32 +665,42 @@ export async function startAgentLoop(config, options) {
578
665
  logger.warn(`[engine-switch] boundary handling failed; continuing with fresh sessions: ${err instanceof Error ? err.message : String(err)}`);
579
666
  }
580
667
  // One registry per agent process, shared by wake collection and both prompt paths.
581
- const externalContextRegistry = labRuntimePolicy
668
+ const externalContextRegistry = workerExecution
582
669
  ? new ExternalContextRegistry([])
583
670
  : createDefaultExternalContextRegistry(config);
584
671
  const session = new SessionManager(config, () => {
585
- if (runtimeSurface.labRuntimePolicy) {
586
- return buildLabRunSystemPrompt(config, runtimeSurface.labRuntimePolicy);
587
- }
672
+ if (workerExecution)
673
+ return workerExecution.buildSystemPrompt(config);
588
674
  return buildSystemPrompt(config, ownerConfig, externalContextRegistry, {
589
675
  hostCapabilities: runtimeSurface.hostCapabilities,
590
676
  desktopAvailable: runtimeSurface.desktop.available,
591
677
  browserSelection: runtimeSurface.browserSelection,
592
678
  credentialBacked: runtimeSurface.credentialBacked,
593
679
  conversation: { threadId: workerMode?.threadId },
680
+ foreman: canDelegateTasks(),
594
681
  });
595
- }, runtimeSurface, {
596
- dualSessionEnabled: ownerConfig.dualSessionEnabled,
597
- ...(options?.workspaceCwd ? { workspaceCwd: options.workspaceCwd } : {}),
598
- });
599
- // Hand the combined engine-switch summary to the freshly created
600
- // general session (rotation + mailbox clearing already happened
601
- // before SessionManager construction).
682
+ }, runtimeSurface, options?.workspaceCwd ? { workspaceCwd: options.workspaceCwd } : {});
683
+ // Hand the engine-switch summary to the freshly created session (rotation
684
+ // already happened before SessionManager construction).
602
685
  if (engineSwitchBoundary) {
603
- session.injectSummary("general", engineSwitchBoundary.combinedSummary);
686
+ session.injectSummary(engineSwitchBoundary.combinedSummary);
604
687
  }
605
- logger.system(`Dual session: ${ownerConfig.dualSessionEnabled ? "enabled" : "disabled"}`);
606
688
  agentState.sessionManager = session;
689
+ if (workerExecution) {
690
+ // Exhausting the budget asks the active session to stop; the execution's
691
+ // usage, including the time already spent, survives this process.
692
+ const budget = workerExecution.budget;
693
+ budget.onStop((reason) => {
694
+ logger.warn(`[execution-budget] ${reason}; stopping run=${workerExecution.id}`);
695
+ session.requestStop();
696
+ });
697
+ const disarmDeadline = budget.armDeadline();
698
+ registerShutdownCallback(() => {
699
+ disarmDeadline();
700
+ budget.close();
701
+ return Promise.resolve();
702
+ });
703
+ }
607
704
  registerShutdownCallback(async () => {
608
705
  // Bound the whole release so it fits the supervisor budgets together with
609
706
  // the earlier callbacks (pm2 kill_timeout 30s); a child still closing
@@ -630,26 +727,6 @@ export async function startAgentLoop(config, options) {
630
727
  // Expose the wake function so out-of-loop components can trigger an
631
728
  // immediate wake without threading the closure through every call site.
632
729
  agentState.wakeMainLoop = wakeMainLoop;
633
- // Thread task resumes (#1996 PR 5): after a wake the runtime queues the
634
- // next runnable task as a system row and wakes the loop, so queued work
635
- // continues without a new owner message, with proactive wakes off and in
636
- // workers. It never queues while a wake runs or execution is gated; the
637
- // row is still checked against the task when it is dequeued.
638
- // TODO: a resume queued just before the service gate engages is discarded
639
- // with the gated queue (main) or still runs (workers, which have no gate
640
- // pass and whose system rows skip the gate reply). The window is tiny.
641
- threadTasks?.enableResumes({
642
- queue: messageQueue,
643
- isBusy: () => agentState.busy || !messageQueue.isEmpty(),
644
- isGated: () => readFundLeagueHold() !== null
645
- // A worker's heartbeat holds the status from its start; the main
646
- // process persists every change, so read that instead.
647
- || (workerMode ? persistedServiceStopped(getConfigFile()) : shouldEnforceServiceGate(heartbeat.lastServiceStatus)),
648
- wake: wakeMainLoop,
649
- });
650
- // Startup: work that was queued, or resumed and interrupted, before the
651
- // previous process stopped continues now.
652
- void threadTasks?.requestResume();
653
730
  const interruptHandler = new InterruptHandler({
654
731
  externalContextRegistry,
655
732
  session: session.activeSession,
@@ -672,6 +749,10 @@ export async function startAgentLoop(config, options) {
672
749
  // Maintenance owns the session until the current skill/transcript settles.
673
750
  // Inbound messages are already durable; process them at the next boundary.
674
751
  if (nightlyMaintenance?.isRunning) {
752
+ // Owner input preempts a Dreaming batch; the step still ends only after
753
+ // its executor is confirmed stopped.
754
+ if (isOwnerInitiatedMessage(msg))
755
+ dreamingRunner?.preempt();
675
756
  void interruptHandler.acknowledgeMaintenance(msg);
676
757
  return;
677
758
  }
@@ -802,6 +883,7 @@ export async function startAgentLoop(config, options) {
802
883
  else {
803
884
  registerShutdownCallback(() => {
804
885
  closeTranscriptMemoryDb();
886
+ closeUsageReportQueue();
805
887
  return Promise.resolve();
806
888
  });
807
889
  }
@@ -819,9 +901,19 @@ export async function startAgentLoop(config, options) {
819
901
  messageQueue,
820
902
  engineFallback,
821
903
  agentState,
822
- singleShot: labRuntimePolicy !== null,
904
+ singleShot: workerExecution !== null,
823
905
  });
824
906
  if (!workerMode) {
907
+ const supervisorForDreaming = threadSupervisor;
908
+ dreamingRunner = supervisorForDreaming
909
+ ? new DreamingRunner(new DreamingPlanner({
910
+ threadIds: () => supervisorForDreaming.getPersistedThreadIds(),
911
+ vocabularyLearning: () => config.vocabularyLearningEnabled !== false,
912
+ ownerPublicId: () => ownerConfig.ownerPublicId,
913
+ }), supervisorForDreaming)
914
+ : null;
915
+ if (!dreamingRunner)
916
+ logger.system("[nightly-maintenance] Dreaming needs the thread supervisor (multiThread); skipped on this profile");
825
917
  nightlyMaintenance = new NightlyMaintenance({
826
918
  tryAcquire: () => {
827
919
  if (agentState.busy || agentState.learning || agentState.compacting || agentState.gated
@@ -832,12 +924,20 @@ export async function startAgentLoop(config, options) {
832
924
  if (threadSupervisor && !resumeWorkers)
833
925
  return null;
834
926
  executionOwner.setBusy(true, "maintenance");
927
+ dreamingRunner?.beginStep();
835
928
  heartbeat.nudge();
836
929
  return () => {
837
- agentState.learning = false;
838
- executionOwner.setBusy(false, "maintenance_release");
839
- resumeWorkers?.();
840
- heartbeat.nudge();
930
+ // Maintenance holds the slot the way a foreground wake does. Release
931
+ // it through Stopping so workers resume only after the slot is free.
932
+ endForegroundWake({
933
+ from: "Running",
934
+ cleanup: () => { agentState.learning = false; },
935
+ release: () => {
936
+ executionOwner.setBusy(false, "maintenance_release");
937
+ resumeWorkers?.();
938
+ heartbeat.nudge();
939
+ },
940
+ });
841
941
  };
842
942
  },
843
943
  hasPendingSkills: hasPendingSkillLearning,
@@ -855,18 +955,18 @@ export async function startAgentLoop(config, options) {
855
955
  watchdog.cancel();
856
956
  }
857
957
  },
858
- dreamingTargets: () => {
958
+ startDreaming: () => {
859
959
  if (config.vocabularyLearningEnabled !== false && ownerConfig.ownerPublicId) {
860
960
  maintainGlossary(ownerConfig.ownerPublicId);
861
961
  }
862
- return threadSupervisor?.getDreamingTargets() ?? resolveDreamingTargets([]);
962
+ dreamingRunner?.startNight();
863
963
  },
864
- dream: async (target) => {
865
- await runDreamingJob(target.threadId, target.transcriptPath, config, {
866
- vocabularyLearningEnabled: config.vocabularyLearningEnabled,
867
- });
964
+ dreamBatch: async (localDay) => {
965
+ if (!dreamingRunner)
966
+ return "idle";
967
+ const step = await dreamingRunner.runBatch(localDay);
968
+ return step.kind;
868
969
  },
869
- lastDreamedDay: readDeepNightDreamDay,
870
970
  canRestart: () => config.nightlyIdleRestartEnabled !== false
871
971
  && process.uptime() * 1000 >= NIGHTLY_RESTART_MIN_UPTIME_MS
872
972
  && detectProcessManager() !== null,
@@ -881,8 +981,14 @@ export async function startAgentLoop(config, options) {
881
981
  if (options?.onReady) {
882
982
  options.onReady({ agentState, sessionManager: session, messageQueue, ownerConfig });
883
983
  }
884
- logger.system(labRuntimePolicy
885
- ? "Single-shot LabRun loop started. Waiting for its execution dispatch..."
984
+ const wakeOnShutdown = () => { session.requestStop(); wakeMainLoop(); };
985
+ options?.signal?.addEventListener("abort", wakeOnShutdown, { once: true });
986
+ registerShutdownCallback(() => {
987
+ options?.signal?.removeEventListener("abort", wakeOnShutdown);
988
+ return Promise.resolve();
989
+ });
990
+ logger.system(workerExecution
991
+ ? "Single-shot worker loop started. Waiting for its execution dispatch..."
886
992
  : "Agent loop started. Waiting for messages or heartbeat...");
887
993
  // =====================================================================
888
994
  // 2. Main loop
@@ -900,16 +1006,29 @@ export async function startAgentLoop(config, options) {
900
1006
  let lastWakeScreenshotMs = 0;
901
1007
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- intentional infinite loop
902
1008
  while (true) {
1009
+ if (options?.signal?.aborted)
1010
+ break;
903
1011
  const leagueHold = readFundLeagueHold();
904
1012
  if (leagueHold) {
905
- executionOwner.setBusy(false, "league_hold");
906
- agentState.gated = true;
1013
+ // The durable marker already blocks the next wake. A slot that is still
1014
+ // held stops first; an idle loop closes the entry directly. Neither
1015
+ // confirms an engine barrier.
1016
+ closeHostEntry({
1017
+ busy: agentState.busy,
1018
+ requestStop: () => { agentState.requestStop(); },
1019
+ markClosed: () => {
1020
+ executionOwner.setBusy(false, "league_hold");
1021
+ agentState.gated = true;
1022
+ },
1023
+ });
907
1024
  await new Promise((resolve) => { wakeResolver = resolve; });
908
1025
  wakeResolver = null;
909
1026
  continue;
910
1027
  }
911
1028
  // --- Reset per-cycle state ---
912
1029
  messageQueue.beginWakeCycle();
1030
+ // A task handed off in an earlier wake no longer blocks new foreground work.
1031
+ foregroundTasks?.beginWake();
913
1032
  executionOwner.setBusy(false, "wake_reset");
914
1033
  agentState.gated = false;
915
1034
  agentState.stopRequested = false;
@@ -918,7 +1037,6 @@ export async function startAgentLoop(config, options) {
918
1037
  agentState.notifiedUserThisWake = false;
919
1038
  agentState.ownerEscalationsThisWake = 0;
920
1039
  agentState.liveAssistantTexts = new Set();
921
- agentState.codingCompletionTaskStartedAt = undefined;
922
1040
  agentState.learning = false;
923
1041
  agentState.replyMap.clear();
924
1042
  session.clearStop();
@@ -950,11 +1068,6 @@ export async function startAgentLoop(config, options) {
950
1068
  });
951
1069
  nextProactiveWakeAt = sleepMs === null ? null : nextProactiveWakeAt ?? Date.now() + sleepMs;
952
1070
  const isFirstWake = firstIteration;
953
- // Worker: report idle status before sleeping so the supervisor's
954
- // cross-thread awareness snapshot reflects this thread as idle.
955
- if (workerMode && !isFirstWake) {
956
- workerMode.relay.relayStatus(false, "idle");
957
- }
958
1071
  // We are about to go idle, which is the only safe moment to move back
959
1072
  // across a runtime boundary: that costs a restart and collapses the
960
1073
  // session into a summary, so doing it mid-conversation would cut a live
@@ -1003,6 +1116,8 @@ export async function startAgentLoop(config, options) {
1003
1116
  resolve();
1004
1117
  }
1005
1118
  });
1119
+ if (options?.signal?.aborted)
1120
+ break;
1006
1121
  if (proactiveWakeSchedule.changed && messageQueue.isEmpty()) {
1007
1122
  proactiveWakeSchedule.changed = false;
1008
1123
  nextProactiveWakeAt = null;
@@ -1112,21 +1227,23 @@ export async function startAgentLoop(config, options) {
1112
1227
  stopRequested: agentState.stopRequested,
1113
1228
  busy: agentState.busy,
1114
1229
  recovering,
1115
- // No engine has a confirmed execution barrier yet. Pi settlement
1116
- // only prevents a send collision; it does not prove the engine stopped.
1117
- barrierConfirmed: false,
1230
+ // Pi confirms this with `agent_settled`. An abort is not a receipt,
1231
+ // so an engine that cannot prove it stopped stays unconfirmed.
1232
+ barrierConfirmed: session.executionBarrierConfirmed(),
1118
1233
  }),
1119
1234
  legacy: {
1120
1235
  busy: agentState.busy,
1121
1236
  gated: agentState.gated,
1122
1237
  stopRequested: agentState.stopRequested,
1123
1238
  },
1124
- barrierConfirmed: false,
1239
+ barrierConfirmed: session.executionBarrierConfirmed(),
1125
1240
  });
1126
1241
  };
1127
1242
  const releaseLifecycleRun = (reason) => {
1128
1243
  // Stopping is one beat when nothing is still in flight. The slot stays
1129
1244
  // busy until cleanup finishes, so busy=false is not what ends the wake.
1245
+ // A worker thread is the same loop: its busy flag lives on the
1246
+ // supervisor, and it is cleared only after this cleanup.
1130
1247
  endForegroundWake({
1131
1248
  // A failed compaction is still this same foreground run. Phase 3 is
1132
1249
  // what moves that path into Recovering before the wake ends.
@@ -1147,6 +1264,10 @@ export async function startAgentLoop(config, options) {
1147
1264
  endLifecycleRun(lifecycleRunId);
1148
1265
  },
1149
1266
  release: () => {
1267
+ // The supervisor learns a worker is idle here, after cleanup, not
1268
+ // at the next sleep. The local slot is released for both loops.
1269
+ if (workerMode)
1270
+ workerMode.relay.relayStatus(false, "idle");
1150
1271
  executionOwner.setBusy(false, reason, lifecycleRunId);
1151
1272
  },
1152
1273
  });
@@ -1187,10 +1308,6 @@ export async function startAgentLoop(config, options) {
1187
1308
  continue;
1188
1309
  }
1189
1310
  }
1190
- // Re-check a queued task resume against the task itself: a cancel,
1191
- // change, wait or block since it was queued retires it unexecuted.
1192
- if (retireStaleResume(messageQueue, threadTasks, msg))
1193
- continue;
1194
1311
  const gateReply = msg.channel === "system" ? null : executionGateReply(heartbeat, resolveLocale(ownerConfig.language));
1195
1312
  if (gateReply !== null) {
1196
1313
  await answerAndDrop(channelManager, messageQueue, msg, gateReply, tuiAdapter);
@@ -1203,9 +1320,6 @@ export async function startAgentLoop(config, options) {
1203
1320
  if (trigger === "message" && messages.length === 0) {
1204
1321
  releaseLifecycleRun("empty_message_batch");
1205
1322
  heartbeat.nudge();
1206
- // A retired stale resume ends here without a wake end; queue the next
1207
- // runnable task (or the same one at its new version) instead.
1208
- void threadTasks?.requestResume();
1209
1323
  continue;
1210
1324
  }
1211
1325
  const correlatedTuiMessage = messages.find((message) => typeof message.meta?.tuiRequestId === "string");
@@ -1219,18 +1333,12 @@ export async function startAgentLoop(config, options) {
1219
1333
  // batch. Telegram and fin-app may already have enriched their messages at
1220
1334
  // ingress; the shared helper skips those, while QQ, Discord, and
1221
1335
  // other channels get the same cloud/local pipeline.
1222
- if (trigger === "message" && !labRuntimePolicy) {
1336
+ if (trigger === "message" && !workerExecution) {
1223
1337
  for (const msg of messages) {
1224
- // A task resume is internal: no "typing…" for the owner.
1225
- if (isTaskResumeMessage(msg))
1226
- continue;
1227
1338
  sendTypingToMessage(channelManager, msg).catch(() => { });
1228
1339
  }
1229
1340
  }
1230
1341
  await transcribeVoiceMessages(messages, ownerTranscriptionContext(ownerConfig));
1231
- // Event first, sidecar second (#1996): after transcription so a voice
1232
- // request is stored with its text. Idempotent and fail-safe.
1233
- threadTasks?.recordMessages(messages.filter(isTaskRelevantMessage));
1234
1342
  for (const msg of messages) {
1235
1343
  agentState.replyMap.set(buildReplyMapKeyFromMessage(msg), buildReplyTarget(msg));
1236
1344
  }
@@ -1264,9 +1372,6 @@ export async function startAgentLoop(config, options) {
1264
1372
  activityTracker.recordUserMessage(formatMessageSummary(msg));
1265
1373
  }
1266
1374
  logger.wake(trigger, messages.length);
1267
- if (session.dualSessionEnabled) {
1268
- logger.system(`Active session: ${session.activeMode}`);
1269
- }
1270
1375
  if (trigger === "heartbeat") {
1271
1376
  try {
1272
1377
  await session.activeSession.maybeCompact();
@@ -1320,7 +1425,7 @@ export async function startAgentLoop(config, options) {
1320
1425
  logger.debug(`Pre-warm kick-off failed: ${err instanceof Error ? err.message : String(err)}`);
1321
1426
  });
1322
1427
  // --- Gather context ---
1323
- const doVersionCheck = !labRuntimePolicy
1428
+ const doVersionCheck = !workerExecution
1324
1429
  && shouldRunProactiveUpgradeCheck(config, trigger)
1325
1430
  && shouldNotifyUpdate();
1326
1431
  // Throttle the wake screenshot: skip on errors, and skip if one was
@@ -1334,7 +1439,7 @@ export async function startAgentLoop(config, options) {
1334
1439
  if (screenshotThrottled) {
1335
1440
  logger.debug(`Skipping wake screenshot (captured ${Math.round((nowMs - lastWakeScreenshotMs) / 1000)}s ago, throttle ${WAKE_SCREENSHOT_MIN_INTERVAL_MS / 1000}s)`);
1336
1441
  }
1337
- const gathered = labRuntimePolicy
1442
+ const gathered = workerExecution
1338
1443
  ? { calendarSummary: "" }
1339
1444
  : await gatherWakeContext(config, doVersionCheck, skipScreenshot, ownerConfig.heartbeatIntervalMs);
1340
1445
  const { screenshot, calendarSummary, versionUpdate } = gathered;
@@ -1344,25 +1449,26 @@ export async function startAgentLoop(config, options) {
1344
1449
  // Refresh cross-thread awareness so the default thread's wake context lists
1345
1450
  // concurrently-running worker threads. No-op when multiThread is disabled.
1346
1451
  threadSupervisor?.refreshMainProcessAwareness();
1347
- const contentBlocks = labRuntimePolicy
1452
+ // Foreman: this conversation's open background tasks, from the host's records.
1453
+ const foremanClient = workerExecution ? null : getForemanClient();
1454
+ const backgroundTasks = foremanClient ? await foremanClient.request({ type: "summary" }) : null;
1455
+ const contentBlocks = workerExecution
1348
1456
  ? [{ type: "text", text: messages.map((message) => message.text).join("\n\n") }]
1349
1457
  : await buildWakeContext({
1458
+ ...(backgroundTasks?.ok && backgroundTasks.text ? { backgroundTasksBlock: backgroundTasks.text } : {}),
1350
1459
  config,
1351
1460
  trigger,
1352
1461
  messages,
1353
1462
  calendarSummary,
1354
1463
  screenshot,
1355
1464
  versionUpdate,
1356
- activeSession: session.dualSessionEnabled ? session.activeMode : undefined,
1357
- sessionMemos: session.consumeMemosForActive(),
1358
- codingSessionStatus: session.getCodingSessionStatus(),
1359
1465
  justUpgraded: isFirstWake ? justUpgraded : null,
1360
1466
  justRestarted: isFirstWake ? justRestarted : null,
1361
1467
  ownerReachable: hasUsableOwnerChannel(config, ownerConfig),
1362
1468
  });
1363
1469
  logger.sendMultimodal(contentBlocks);
1364
1470
  // --- Arm watchdog + run cycle ---
1365
- if (!labRuntimePolicy)
1471
+ if (!workerExecution)
1366
1472
  watchdog.arm(trigger, messages);
1367
1473
  let tuiTerminalOutcome = {
1368
1474
  state: "failed",
@@ -1379,8 +1485,20 @@ export async function startAgentLoop(config, options) {
1379
1485
  operation: "query",
1380
1486
  outcome: "started",
1381
1487
  });
1488
+ let releaseConversationTurn;
1489
+ agentState.currentDispatchId = createHash("sha256").update(JSON.stringify(messages.map((message) => message.id))).digest("hex");
1382
1490
  try {
1383
- const result = await cycleRunner.run(contentBlocks, trigger, messages, calendarSummary, consecutiveErrors);
1491
+ if (!workerExecution) {
1492
+ releaseConversationTurn = await (options?.acquireConversationTurn?.(options.signal)
1493
+ ?? threadSupervisor?.acquireConversationTurn(options?.signal));
1494
+ }
1495
+ if (options?.signal?.aborted) {
1496
+ messageQueue.requeueOwnedClaims();
1497
+ break;
1498
+ }
1499
+ // Accepted inputs are also replayed from the ledger on executor recovery.
1500
+ noteMessagesHandedToModel(messages);
1501
+ const result = await cycleRunner.run(contentBlocks, trigger, messages, consecutiveErrors);
1384
1502
  traceLifecycle({
1385
1503
  runId: lifecycleRunId,
1386
1504
  stage: "model",
@@ -1389,6 +1507,10 @@ export async function startAgentLoop(config, options) {
1389
1507
  evidence: { terminalState: result.terminalState },
1390
1508
  });
1391
1509
  consecutiveErrors = result.consecutiveErrors;
1510
+ if (options?.signal?.aborted) {
1511
+ messageQueue.requeueOwnedClaims();
1512
+ break;
1513
+ }
1392
1514
  // A queue claim is not terminal until the complete wake cycle returns.
1393
1515
  // If the worker dies during model/tool execution, the in-flight rows
1394
1516
  // remain durable and are replayed by the next queue owner.
@@ -1396,9 +1518,24 @@ export async function startAgentLoop(config, options) {
1396
1518
  // done its work: leave the claims in flight so the replacement process
1397
1519
  // replays them on the new engine (issue #2519).
1398
1520
  failoverRestartPending = !restartArmedBeforeWake && engineFallback.isRestartPending();
1399
- // Claims become handled only once each message is a durable task event,
1400
- // so their follow-up survives the queue row (#1996). handled ≠ completed.
1401
- endWakeThreadTasks(messageQueue, threadTasks, { failoverRestartPending });
1521
+ // Foreman: the background-task updates this turn handled, read before
1522
+ // their claims are released (mid-turn interrupts included).
1523
+ const handledForemanEvents = failoverRestartPending ? [] : foremanEventsOf(messageQueue.currentCycleClaims());
1524
+ // A completed foreground wake acknowledges its claims. Accepted background
1525
+ // work already belongs to the canonical Task ledger.
1526
+ if (!failoverRestartPending)
1527
+ messageQueue.markAllInFlightHandled();
1528
+ if (!failoverRestartPending) {
1529
+ // An accepted finish that is not waiting for the user ends the
1530
+ // foreground task; the next one starts from zero. A wake that only
1531
+ // ran out of recovery attempts or timed out keeps the count.
1532
+ if (result.finished === true && result.terminalState === "completed")
1533
+ foregroundTasks?.reset();
1534
+ // Whatever the turn did not deliver to the user is due for the fallback now.
1535
+ if (handledForemanEvents.length > 0) {
1536
+ void getForemanClient()?.request({ type: "turn_ended", events: handledForemanEvents });
1537
+ }
1538
+ }
1402
1539
  if (workerMode) {
1403
1540
  workerMode.relay.finishActivityRun(result.terminalState);
1404
1541
  }
@@ -1412,9 +1549,6 @@ export async function startAgentLoop(config, options) {
1412
1549
  // terminal boundary. A later wake must not inherit this turn's claims
1413
1550
  // and accidentally confirm them together with unrelated work.
1414
1551
  try {
1415
- // Released before the requeue: a replayed resume for an interrupted
1416
- // task must run when it comes back (#2664 review P1-B).
1417
- threadTasks?.releaseResume(messageQueue.currentCycleClaims());
1418
1552
  messageQueue.requeueOwnedClaims();
1419
1553
  }
1420
1554
  catch (requeueErr) {
@@ -1436,6 +1570,7 @@ export async function startAgentLoop(config, options) {
1436
1570
  throw err;
1437
1571
  }
1438
1572
  finally {
1573
+ releaseConversationTurn?.();
1439
1574
  // Cleanup must always run, even if the extracted cycle runner throws
1440
1575
  // unexpectedly, otherwise the reply watchdog timer can leak across
1441
1576
  // wake cycles. The runtime heartbeat loop runs independently and
@@ -1467,21 +1602,21 @@ export async function startAgentLoop(config, options) {
1467
1602
  // in the shared memories/ tree, so it runs only on the deep-night sweep
1468
1603
  // (`nightly-maintenance.ts`) — once a day, while the agent is idle —
1469
1604
  // rather than after every wake cycle.
1470
- if (workerMode && !labRuntimePolicy) {
1605
+ if (workerMode && !workerExecution) {
1471
1606
  workerMode.relay.relayTurnComplete();
1472
1607
  }
1473
1608
  }
1474
- if (labRuntimePolicy) {
1609
+ if (workerExecution) {
1475
1610
  if (!messageQueue.isEmpty()) {
1476
- logger.system(`LabRun turn ended with queued work; continuing run=${labRuntimePolicy.policy.runId}`);
1611
+ logger.system(`Worker execution turn ended with queued work; continuing run=${workerExecution.id}`);
1477
1612
  continue;
1478
1613
  }
1479
- logger.system(`Single-shot LabRun turn ended; waiting ${LAB_IDLE_GRACE_MS / 1000}s for more messages: run=${labRuntimePolicy.policy.runId}`);
1480
- if (await waitForLabQueueOrIdle()) {
1481
- logger.system(`LabRun received more work during idle grace; continuing run=${labRuntimePolicy.policy.runId}`);
1614
+ logger.system(`Single-shot worker turn ended; waiting ${WORKER_EXECUTION_IDLE_GRACE_MS / 1000}s for more messages: run=${workerExecution.id}`);
1615
+ if (await waitForExecutionQueueOrIdle()) {
1616
+ logger.system(`Worker execution received more work during idle grace; continuing run=${workerExecution.id}`);
1482
1617
  continue;
1483
1618
  }
1484
- logger.system(`LabRun queue idle for ${LAB_IDLE_GRACE_MS / 1000}s; ending worker run=${labRuntimePolicy.policy.runId}`);
1619
+ logger.system(`Worker execution queue idle for ${WORKER_EXECUTION_IDLE_GRACE_MS / 1000}s; ending worker run=${workerExecution.id}`);
1485
1620
  break;
1486
1621
  }
1487
1622
  }