@xopcai/xopc 0.0.244 → 0.0.245

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 (239) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-CAah-_8h.js → activity-store-BlxqErph.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BhXGsupm.js → agent-avatar-dicebear-DRQnogaU.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-Blzn2H6t.js → agent-defaults-settings-panel-CpOxGbMD.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-Cmp-z8Y_.js → agents-flnXZLaT.js} +1 -1
  7. package/dist/gateway/static/root/assets/{api-B2tKxbcz.js → api-BbXzyQMj.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-CezjAP1K.js → app-management-settings-panel-CZl6n2xi.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-C-CfS05x.js → appearance-settings-Bglp-pn6.js} +1 -1
  10. package/dist/gateway/static/root/assets/{apps-page-7Y13_bqZ.js → apps-page-CmsWarVB.js} +1 -1
  11. package/dist/gateway/static/root/assets/{archive-plugin-BmSx7wzY.js → archive-plugin-DD2SweEH.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-DI4CoIga.js → attachment-load-G0HenUmG.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-D04Xceck.js → automations-page-B78bFjH2.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automations-workspace-wEO1OWk0.js → automations-workspace-BMQGmn50.js} +1 -1
  15. package/dist/gateway/static/root/assets/{binary-plugins-BJQe8TRu.js → binary-plugins-BbSQmXqn.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-BSzGjJC6.js → block-editor-DutTIH81.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-settings-page-DjAZ_LF2.js → browser-settings-page-CALiFKm4.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-CRnkgZHI.js → browser-workflow-inputs-BAAc151l.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-CwbxA3B7.js → browser-workflows-page-DE5HPrHZ.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capabilities-settings-panel-jt9bqUMK.js → capabilities-settings-panel-Dts7XtP3.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channels-settings-Cz_TWY3a.js → channels-settings-CWEd3wzh.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channels-status-swr-DuY4MGxe.js → channels-status-swr-CCBCtLDg.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-D3gj2D3U.js → chat-terminal-dock-Bp1fXQm1.js} +1 -1
  24. package/dist/gateway/static/root/assets/{connectors-page-Shs5vbzx.js → connectors-page-CQ6wVNLm.js} +1 -1
  25. package/dist/gateway/static/root/assets/{cron-expression-DgWHw0jX.js → cron-expression-B8HA5IRb.js} +1 -1
  26. package/dist/gateway/static/root/assets/{date-picker-CKg-RPbs.js → date-picker-DD8b7oad.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-CVYkw-NN.js → dependency-picker-BC9zwIyH.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-Bf46oXTY.js → desktop-pet-DsrsPZTW.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-BJO_klc7.js → desktop-pet-settings-D7gp_HNA.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-debug-page-T2PmFFOW.js → extension-debug-page-BoKbOX7x.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-2wAE2RCe.js → extension-page-BegL4FW8.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-settings-page-Y9ZiCJ21.js → extension-settings-page-CjPqq57s.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-api-DaYY1Gkn.js → gateway-config-api-DaG57o4X.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-swr-BC3pgb_P.js → gateway-config-swr-826dipyU.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-eO3IzW_J.js → gateway-settings-DkJGpgm6.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-uMcSfLru.js → gateway-startup-retry-DyvcAIMm.js} +1 -1
  37. package/dist/gateway/static/root/assets/{heartbeat-settings-BAgrkyHc.js → heartbeat-settings-BLZ48kSU.js} +1 -1
  38. package/dist/gateway/static/root/assets/{home-page-GTjKH7LK.js → home-page-Dtw7Ipt1.js} +1 -1
  39. package/dist/gateway/static/root/assets/{image-generation-api-D1qlQA-A.js → image-generation-api-D7cyfks6.js} +1 -1
  40. package/dist/gateway/static/root/assets/{index-DUz0O54y.js → index-DG5CfYat.js} +10 -10
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CWGqL6o5.js → keyboard-shortcuts-settings-D2Has7-N.js} +1 -1
  42. package/dist/gateway/static/root/assets/{local-app-workbench-page-DKJ-rks0.js → local-app-workbench-page-BWidWY93.js} +1 -1
  43. package/dist/gateway/static/root/assets/{local-apps-page-Bfidv29d.js → local-apps-page-Bkekjoxf.js} +1 -1
  44. package/dist/gateway/static/root/assets/{locale-store-CMZljTJx.js → locale-store-CBoCuIMx.js} +1 -1
  45. package/dist/gateway/static/root/assets/{logs-page-DwAHrPbF.js → logs-page-C5zSSgvA.js} +1 -1
  46. package/dist/gateway/static/root/assets/{management-settings-BG7j1I9f.js → management-settings-B8c62vRS.js} +1 -1
  47. package/dist/gateway/static/root/assets/{markdown-split-AnmmpLs6.js → markdown-split-3kxTTGO7.js} +1 -1
  48. package/dist/gateway/static/root/assets/{markdown-view-PPCLt7fu.js → markdown-view-BXsHghJd.js} +1 -1
  49. package/dist/gateway/static/root/assets/{media-plugins-CGS-05cE.js → media-plugins-BW8J1nCG.js} +1 -1
  50. package/dist/gateway/static/root/assets/messages-BbdwoxVo.js +3 -0
  51. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-DoKK5GfV.js → mobile-pairing-wizard-nwQ8iUcd.js} +1 -1
  52. package/dist/gateway/static/root/assets/models-hub-cache-88f4fzYS.js +1 -0
  53. package/dist/gateway/static/root/assets/{notes-page-Lr8rsFAR.js → notes-page-DdybD0QM.js} +1 -1
  54. package/dist/gateway/static/root/assets/{notes-workbench-ISWnKLxO.js → notes-workbench-IYfpy2Jx.js} +2 -2
  55. package/dist/gateway/static/root/assets/{oauth-api-4VeMbkTJ.js → oauth-api-BjSUDIgq.js} +1 -1
  56. package/dist/gateway/static/root/assets/{product-open-page-BU0HiZtv.js → product-open-page-CAJeUXeU.js} +1 -1
  57. package/dist/gateway/static/root/assets/{project-detail-page-BZqr4yam.js → project-detail-page-4wjw-b7h.js} +1 -1
  58. package/dist/gateway/static/root/assets/{projects-page-Dau8733A.js → projects-page-CCMj9PeL.js} +1 -1
  59. package/dist/gateway/static/root/assets/{registry-api-CWOtPFrE.js → registry-api-BhGKnvLP.js} +1 -1
  60. package/dist/gateway/static/root/assets/{remote-access-hub-DdChlvGP.js → remote-access-hub-DsBJqWIk.js} +1 -1
  61. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CmZTNv1W.js → runtime-tools-settings-panel-B4IDcqx0.js} +1 -1
  62. package/dist/gateway/static/root/assets/{schema-form-XlVPyiVQ.js → schema-form-DiGUUjO6.js} +1 -1
  63. package/dist/gateway/static/root/assets/{sessions-page-C3kADsd4.js → sessions-page-BwGj0t-2.js} +1 -1
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-BJCfUghk.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-page-DblUeM3V.js → settings-page-CVQUsAhd.js} +1 -1
  66. package/dist/gateway/static/root/assets/{setup-status-panel-bDfRfSnq.js → setup-status-panel-CQACRh1i.js} +1 -1
  67. package/dist/gateway/static/root/assets/{share-preview-page-DBMWFMN-.js → share-preview-page-DTP1dtuS.js} +1 -1
  68. package/dist/gateway/static/root/assets/{shares-settings-Bu6lIStj.js → shares-settings-D_YPh6Rw.js} +1 -1
  69. package/dist/gateway/static/root/assets/skill-reload-api-B43xlJlX.js +1 -0
  70. package/dist/gateway/static/root/assets/{skills-page-CSOseeQe.js → skills-page-Czpn7Y28.js} +1 -1
  71. package/dist/gateway/static/root/assets/{skills-page.utils-CniRGhkJ.js → skills-page.utils-d39rm3hb.js} +1 -1
  72. package/dist/gateway/static/root/assets/{system-settings-panel-D0GqNpKy.js → system-settings-panel-CXXySCSp.js} +1 -1
  73. package/dist/gateway/static/root/assets/{task-detail-page-BRCq-nR7.js → task-detail-page-DHiOqQMx.js} +1 -1
  74. package/dist/gateway/static/root/assets/{theme-store-uxUwr10D.js → theme-store-hybK3oC9.js} +1 -1
  75. package/dist/gateway/static/root/assets/{tunnel-api-BtjS2nrM.js → tunnel-api-BiBGK7O2.js} +1 -1
  76. package/dist/gateway/static/root/assets/{use-autosave-TwuAycG8.js → use-autosave-DjpzpeIm.js} +1 -1
  77. package/dist/gateway/static/root/assets/{user-context-page-CbqPu8xZ.js → user-context-page-1XBRV5gX.js} +1 -1
  78. package/dist/gateway/static/root/assets/{voice-api-key-field-CzwG5plu.js → voice-api-key-field-CUIPNmOc.js} +1 -1
  79. package/dist/gateway/static/root/assets/{voice-config-api-MqyI6cgq.js → voice-config-api-CBbiF1T3.js} +1 -1
  80. package/dist/gateway/static/root/assets/{work-discovery-overlay-DS15FzQA.js → work-discovery-overlay-DVNxhb1x.js} +1 -1
  81. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C_boCemi.js → workflow-run-setup-panel-HxxFQFY7.js} +1 -1
  82. package/dist/gateway/static/root/assets/{workflows-page-CaI2ruyy.js → workflows-page-BCgL7PRm.js} +1 -1
  83. package/dist/gateway/static/root/index.html +11 -11
  84. package/dist/package.js +1 -1
  85. package/dist/packages/gateway-contract/src/turn-outcome.js +3 -1
  86. package/dist/src/agent/agent-instance-gateway.d.ts +3 -1
  87. package/dist/src/agent/agent-manager.d.ts +2 -4
  88. package/dist/src/agent/agent-manager.js +28 -32
  89. package/dist/src/agent/background-review/coordinator.js +1 -1
  90. package/dist/src/agent/background-review/run-background-review.js +2 -2
  91. package/dist/src/agent/child-agent-factory.d.ts +10 -7
  92. package/dist/src/agent/child-agent-factory.js +112 -158
  93. package/dist/src/agent/coding/index.d.ts +1 -1
  94. package/dist/src/agent/coding/index.js +2 -2
  95. package/dist/src/agent/coding/repository-instructions.d.ts +12 -0
  96. package/dist/src/agent/coding/repository-instructions.js +76 -0
  97. package/dist/src/agent/coding/run-verification.d.ts +34 -0
  98. package/dist/src/agent/coding/run-verification.js +134 -0
  99. package/dist/src/agent/coding/verification-command.d.ts +3 -0
  100. package/dist/src/agent/coding/verification-command.js +50 -0
  101. package/dist/src/agent/coding/workspace-revision.d.ts +2 -0
  102. package/dist/src/agent/coding/workspace-revision.js +77 -0
  103. package/dist/src/agent/commands/command-isolation.d.ts +21 -0
  104. package/dist/src/agent/commands/command-isolation.js +71 -0
  105. package/dist/src/agent/commands/command-registry.d.ts +56 -0
  106. package/dist/src/agent/commands/command-registry.js +259 -0
  107. package/dist/src/agent/embedded/index.js +1 -1
  108. package/dist/src/agent/embedded/model-runtime.js +1 -1
  109. package/dist/src/agent/embedded/run-for-session.js +3 -2
  110. package/dist/src/agent/embedded/run-turn.js +88 -25
  111. package/dist/src/agent/embedded/session-tool-result-guard.js +2 -2
  112. package/dist/src/agent/embedded/subscribe-session.d.ts +2 -1
  113. package/dist/src/agent/embedded/subscribe-session.js +2 -1
  114. package/dist/src/agent/embedded/types.d.ts +3 -1
  115. package/dist/src/agent/embedded/xopc-tools-bridge.js +4 -1
  116. package/dist/src/agent/image/index.js +1 -1
  117. package/dist/src/agent/image/tool-model-config.js +1 -1
  118. package/dist/src/agent/index.js +3 -3
  119. package/dist/src/agent/ipc/inbox.js +1 -1
  120. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  121. package/dist/src/agent/memory/user-context-coordinator.js +1 -1
  122. package/dist/src/agent/middleware/index.d.ts +0 -5
  123. package/dist/src/agent/middleware/index.js +1 -2
  124. package/dist/src/agent/orchestration/agent-event-handler.d.ts +0 -5
  125. package/dist/src/agent/orchestration/agent-event-handler.js +1 -96
  126. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
  127. package/dist/src/agent/orchestration/agent-turn-policy.js +5 -5
  128. package/dist/src/agent/orchestration/index.d.ts +1 -1
  129. package/dist/src/agent/orchestration/index.js +2 -2
  130. package/dist/src/agent/orchestration/loop-guard.d.ts +4 -31
  131. package/dist/src/agent/orchestration/loop-guard.js +14 -99
  132. package/dist/src/agent/prompt/sections/tooling.js +2 -4
  133. package/dist/src/agent/sandbox/types.d.ts +2 -2
  134. package/dist/src/agent/sandbox/types.js +1 -1
  135. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  136. package/dist/src/agent/service/process-direct-streaming.js +1 -1
  137. package/dist/src/agent/service.d.ts +0 -2
  138. package/dist/src/agent/service.js +8 -25
  139. package/dist/src/agent/session/session-inspector.js +1 -1
  140. package/dist/src/agent/skills/hub-lock.js +1 -1
  141. package/dist/src/agent/tasks/task-judge-service.d.ts +7 -0
  142. package/dist/src/agent/tasks/task-judge-service.js +27 -5
  143. package/dist/src/agent/tools/delegate-tool.d.ts +2 -1
  144. package/dist/src/agent/tools/delegate-tool.js +102 -124
  145. package/dist/src/agent/tools/exec-command.d.ts +8 -1
  146. package/dist/src/agent/tools/exec-command.js +77 -169
  147. package/dist/src/agent/tools/executor.js +9 -2
  148. package/dist/src/agent/tools/factory.js +50 -5
  149. package/dist/src/agent/tools/find.d.ts +10 -13
  150. package/dist/src/agent/tools/find.js +33 -80
  151. package/dist/src/agent/tools/grep.d.ts +14 -18
  152. package/dist/src/agent/tools/grep.js +56 -144
  153. package/dist/src/agent/tools/index.d.ts +0 -1
  154. package/dist/src/agent/tools/index.js +2 -3
  155. package/dist/src/agent/tools/language-diagnostics.d.ts +11 -0
  156. package/dist/src/agent/tools/language-diagnostics.js +62 -0
  157. package/dist/src/agent/tools/managed-job-tool.d.ts +2 -1
  158. package/dist/src/agent/tools/managed-job-tool.js +58 -118
  159. package/dist/src/agent/tools/read.js +24 -7
  160. package/dist/src/agent/tools/repository-search.d.ts +5 -0
  161. package/dist/src/agent/tools/repository-search.js +56 -0
  162. package/dist/src/agent/tools/review-workspace.d.ts +2 -0
  163. package/dist/src/agent/tools/review-workspace.js +103 -0
  164. package/dist/src/agent/tools/write.js +4 -4
  165. package/dist/src/agent/transcript/index.js +2 -2
  166. package/dist/src/agent/transcript/transcript-hygiene.js +2 -2
  167. package/dist/src/agent/workflow/subagent-runner.d.ts +0 -2
  168. package/dist/src/agent/workflow/subagent-runner.js +12 -31
  169. package/dist/src/agent-config/schema.d.ts +42 -0
  170. package/dist/src/agent-config/schema.js +5 -0
  171. package/dist/src/ai-assist/text-assist.js +1 -1
  172. package/dist/src/auth/credentials.js +2 -2
  173. package/dist/src/auth/profiles/store.js +1 -1
  174. package/dist/src/auth/sync-provider-auth.js +2 -2
  175. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  176. package/dist/src/cli/commands/agent.js +2 -2
  177. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  178. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  179. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  180. package/dist/src/cli/commands/models.js +2 -2
  181. package/dist/src/cli/commands/onboard.js +1 -1
  182. package/dist/src/cli/commands/profile.js +1 -1
  183. package/dist/src/cli/commands/tunnel.js +1 -1
  184. package/dist/src/cli/commands/update.js +1 -1
  185. package/dist/src/cli/extension-cli-register.js +1 -1
  186. package/dist/src/config/index.js +5 -5
  187. package/dist/src/config/loader.js +1 -1
  188. package/dist/src/config/models-json.js +1 -1
  189. package/dist/src/config/schema.d.ts +28 -0
  190. package/dist/src/execution-environments/local-worktree-manager.d.ts +3 -1
  191. package/dist/src/execution-environments/local-worktree-manager.js +8 -3
  192. package/dist/src/execution-environments/session-environment-service.js +5 -3
  193. package/dist/src/extensions/lockfile.js +1 -1
  194. package/dist/src/extensions/update.js +1 -1
  195. package/dist/src/gateway/agents-admin.js +1 -1
  196. package/dist/src/gateway/file-path-classifier.js +1 -1
  197. package/dist/src/gateway/heartbeat/service.js +1 -1
  198. package/dist/src/gateway/hono/lib/config-payload.d.ts +7 -0
  199. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  200. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  201. package/dist/src/gateway/hono/routes/models.js +1 -1
  202. package/dist/src/gateway/hono/routes/sessions.js +1 -1
  203. package/dist/src/gateway/media-access.js +1 -1
  204. package/dist/src/gateway/run-loop.js +1 -1
  205. package/dist/src/gateway/service/config-coordinator.js +2 -2
  206. package/dist/src/gateway/service/run-gateway-agent.js +4 -1
  207. package/dist/src/gateway/service.js +7 -7
  208. package/dist/src/gateway/session-reset-service.js +1 -1
  209. package/dist/src/gateway/workspace-ripgrep.d.ts +0 -6
  210. package/dist/src/gateway/workspace-ripgrep.js +2 -40
  211. package/dist/src/heartbeat/index.js +1 -1
  212. package/dist/src/infra/ripgrep.d.ts +13 -0
  213. package/dist/src/infra/ripgrep.js +46 -0
  214. package/dist/src/infra/update-runner.js +1 -1
  215. package/dist/src/proactive/execution/agent-executor.js +1 -1
  216. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  217. package/dist/src/providers/index.js +2 -2
  218. package/dist/src/providers/model-registry.js +1 -1
  219. package/dist/src/providers/register-runtime-providers.js +1 -1
  220. package/dist/src/session/store.js +1 -1
  221. package/dist/src/session/turn-outcome-projector.js +26 -6
  222. package/dist/src/share/hosted-session-share.js +1 -1
  223. package/dist/src/tasks/task-run-coordinator.d.ts +2 -2
  224. package/dist/src/tasks/task-run-coordinator.js +14 -12
  225. package/dist/src/tui/backends/embedded-backend.js +1 -1
  226. package/dist/src/tui/tui-startup-resources.js +1 -1
  227. package/dist/src/tui/tui.js +1 -1
  228. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  229. package/package.json +1 -1
  230. package/dist/gateway/static/root/assets/messages-CTSgFlE4.js +0 -3
  231. package/dist/gateway/static/root/assets/models-hub-cache-ZrbGRiGY.js +0 -1
  232. package/dist/gateway/static/root/assets/settings-advanced-gate-CSYy6SUa.js +0 -1
  233. package/dist/gateway/static/root/assets/skill-reload-api-BNMc4l04.js +0 -1
  234. package/dist/src/agent/coding/turn-diff-tracker.d.ts +0 -67
  235. package/dist/src/agent/coding/turn-diff-tracker.js +0 -231
  236. package/dist/src/agent/middleware/self-verify.d.ts +0 -136
  237. package/dist/src/agent/middleware/self-verify.js +0 -380
  238. package/dist/src/agent/tools/execute-code-tool.d.ts +0 -11
  239. package/dist/src/agent/tools/execute-code-tool.js +0 -208
@@ -1,106 +1,12 @@
1
- import { resolveGlobalSingleton } from "../../utils/global-singleton.js";
1
+ import { commandRegistry, commandTimeout } from "../commands/command-registry.js";
2
2
  import { evaluateExecPolicy } from "../sandbox/exec-policy.js";
3
3
  import { resolve } from "node:path";
4
- import { spawn } from "node:child_process";
5
- import { randomUUID } from "node:crypto";
6
4
  import { Type } from "@sinclair/typebox";
7
5
  //#region src/agent/tools/managed-job-tool.ts
8
- const MANAGED_JOB_REGISTRY_KEY = Symbol.for("xopc.managedJobRegistry");
9
- const DEFAULT_MAX_RUNTIME_MS = 60 * 6e4;
10
- const MAX_RUNTIME_MS = 1440 * 6e4;
11
- const MAX_CAPTURE_CHARS = 2e5;
12
- var ManagedJobRegistry = class {
13
- jobs = /* @__PURE__ */ new Map();
14
- start(owner, command, cwd, env, maxRuntimeMs) {
15
- this.prune();
16
- const id = randomUUID();
17
- const child = spawn(command, [], {
18
- shell: true,
19
- cwd,
20
- env,
21
- detached: process.platform !== "win32"
22
- });
23
- const job = {
24
- id,
25
- owner,
26
- command,
27
- cwd,
28
- status: "running",
29
- process: child,
30
- pid: child.pid,
31
- createdAtMs: Date.now(),
32
- stdout: "",
33
- stderr: "",
34
- timeout: setTimeout(() => this.stop(job, "timed_out"), maxRuntimeMs)
35
- };
36
- job.timeout.unref?.();
37
- const append = (stream, value) => {
38
- const next = `${job[stream]}${String(value)}`;
39
- job[stream] = next.length > MAX_CAPTURE_CHARS ? next.slice(-MAX_CAPTURE_CHARS) : next;
40
- };
41
- child.stdout?.on("data", (value) => append("stdout", value));
42
- child.stderr?.on("data", (value) => append("stderr", value));
43
- child.on("error", (error) => append("stderr", `\n${error.message}`));
44
- child.on("close", (exitCode) => {
45
- if (job.status === "running") job.status = exitCode === 0 ? "succeeded" : "failed";
46
- job.exitCode = exitCode;
47
- job.endedAtMs = Date.now();
48
- clearTimeout(job.timeout);
49
- });
50
- this.jobs.set(id, job);
51
- return this.view(job);
52
- }
53
- get(owner, id) {
54
- const job = this.jobs.get(id);
55
- return job?.owner === owner ? this.view(job) : void 0;
56
- }
57
- list(owner) {
58
- return [...this.jobs.values()].filter((job) => job.owner === owner).toSorted((a, b) => b.createdAtMs - a.createdAtMs).slice(0, 50).map((job) => this.view(job));
59
- }
60
- cancel(owner, id) {
61
- const job = this.jobs.get(id);
62
- if (!job || job.owner !== owner) return void 0;
63
- if (job.status === "running") this.stop(job, "cancelled");
64
- return this.view(job);
65
- }
66
- stop(job, status) {
67
- if (job.status !== "running") return;
68
- job.status = status;
69
- job.endedAtMs = Date.now();
70
- clearTimeout(job.timeout);
71
- if (job.pid && process.platform !== "win32") try {
72
- process.kill(-job.pid, "SIGTERM");
73
- return;
74
- } catch {}
75
- job.process.kill("SIGTERM");
76
- }
77
- view(job) {
78
- const outputLength = job.stdout.length + job.stderr.length;
79
- return {
80
- id: job.id,
81
- command: job.command,
82
- cwd: job.cwd,
83
- status: job.status,
84
- pid: job.pid,
85
- createdAtMs: job.createdAtMs,
86
- endedAtMs: job.endedAtMs,
87
- exitCode: job.exitCode,
88
- stdout: job.stdout,
89
- stderr: job.stderr,
90
- durationMs: (job.endedAtMs ?? Date.now()) - job.createdAtMs,
91
- outputTruncated: outputLength >= MAX_CAPTURE_CHARS
92
- };
93
- }
94
- prune() {
95
- if (this.jobs.size < 500) return;
96
- const removable = [...this.jobs.values()].filter((job) => job.status !== "running").toSorted((a, b) => a.createdAtMs - b.createdAtMs).slice(0, Math.max(1, this.jobs.size - 400));
97
- for (const job of removable) this.jobs.delete(job.id);
98
- }
99
- };
100
6
  const ManagedJobSchema = Type.Union([
101
7
  Type.Object({
102
8
  action: Type.Literal("start"),
103
- command: Type.String(),
9
+ command: Type.String({ minLength: 1 }),
104
10
  cwd: Type.Optional(Type.String()),
105
11
  maxRuntimeMs: Type.Optional(Type.Number())
106
12
  }),
@@ -108,52 +14,86 @@ const ManagedJobSchema = Type.Union([
108
14
  action: Type.Literal("status"),
109
15
  jobId: Type.String()
110
16
  }),
17
+ Type.Object({
18
+ action: Type.Literal("wait"),
19
+ jobId: Type.String(),
20
+ waitMs: Type.Optional(Type.Number({
21
+ minimum: 0,
22
+ maximum: 6e4
23
+ }))
24
+ }),
25
+ Type.Object({
26
+ action: Type.Literal("stdin"),
27
+ jobId: Type.String(),
28
+ chars: Type.String({ maxLength: 65536 }),
29
+ end: Type.Optional(Type.Boolean())
30
+ }),
111
31
  Type.Object({ action: Type.Literal("list") }),
112
32
  Type.Object({
113
33
  action: Type.Literal("cancel"),
114
34
  jobId: Type.String()
115
35
  })
116
36
  ], { type: "object" });
117
- function registry() {
118
- return resolveGlobalSingleton(MANAGED_JOB_REGISTRY_KEY, () => new ManagedJobRegistry());
119
- }
120
37
  function result(value) {
121
38
  return {
122
39
  content: [{
123
40
  type: "text",
124
41
  text: JSON.stringify(value, null, 2)
125
42
  }],
126
- details: {}
43
+ details: Array.isArray(value) ? { jobs: value } : value
127
44
  };
128
45
  }
129
- function createManagedJobTool(workspace, getSessionKey, getSkillPassthroughEnvVarNames, prepareEnv) {
46
+ function createManagedJobTool(workspace, getSessionKey, getSkillPassthroughEnvVarNames, prepareEnv, getCommandIsolation) {
130
47
  return {
131
48
  name: "managed_job",
132
49
  label: "Managed Job",
133
- description: "Start and manage commands expected to outlive a single tool call. Start returns a jobId immediately; use status/list/cancel to observe or stop it.",
50
+ description: "Manage shell jobs, including jobs yielded by exec_command. Start returns an id; wait returns on completion or after at most 60s; stdin writes pipe input (not a terminal); status/list/cancel inspect or stop jobs. Completed output and logs survive restart. Interrupted jobs require inspection before restart.",
134
51
  parameters: ManagedJobSchema,
135
52
  supportsParallel: true,
136
53
  idempotent: false,
137
- async execute(_toolCallId, input) {
138
- const owner = getSessionKey() ?? "default";
139
- if (input.action === "list") return result(registry().list(owner));
140
- if (input.action === "status") return result(registry().get(owner, input.jobId) ?? { error: "Managed job not found" });
141
- if (input.action === "cancel") return result(registry().cancel(owner, input.jobId) ?? { error: "Managed job not found" });
142
- const command = String(input.command ?? "").trim();
143
- if (!command) return result({ error: "command is required" });
54
+ async execute(_toolCallId, input, signal) {
55
+ const owner = getSessionKey() ?? workspace;
56
+ const registry = commandRegistry();
57
+ if (input.action === "list") return result(registry.list(owner));
58
+ if (input.action !== "start") {
59
+ if (input.action === "stdin" && !registry.write(owner, input.jobId, input.chars, input.end)) return result({
60
+ status: "failed",
61
+ error: "Job is unavailable or stdin is closed"
62
+ });
63
+ return result((input.action === "wait" ? await registry.wait(owner, input.jobId, input.waitMs, signal) : input.action === "cancel" ? await registry.cancel(owner, input.jobId) : registry.get(owner, input.jobId)) ?? {
64
+ status: "failed",
65
+ error: "Managed job not found"
66
+ });
67
+ }
68
+ const command = input.command.trim();
69
+ if (!command) return result({
70
+ status: "failed",
71
+ error: "command is required"
72
+ });
144
73
  const policy = evaluateExecPolicy({
145
74
  command,
146
- cwd: input.cwd?.trim() ? resolve(workspace, input.cwd.trim()) : workspace,
75
+ cwd: resolve(workspace, input.cwd?.trim() || "."),
147
76
  allowedEnvVars: getSkillPassthroughEnvVarNames?.() ?? []
148
77
  });
149
- if (!policy.allowed) return result({ error: `Sandbox blocked command: ${policy.reason}` });
150
- const rawMax = Number(input.maxRuntimeMs ?? DEFAULT_MAX_RUNTIME_MS);
151
- const maxRuntimeMs = Math.min(MAX_RUNTIME_MS, Math.max(1e3, Number.isFinite(rawMax) ? rawMax : DEFAULT_MAX_RUNTIME_MS));
152
- const runtimeEnv = prepareEnv ? await prepareEnv(policy.sanitizedEnv, policy.effectiveCwd) : policy.sanitizedEnv;
153
- return result(registry().start(owner, command, policy.effectiveCwd, {
154
- ...runtimeEnv,
155
- COLUMNS: "200"
156
- }, maxRuntimeMs));
78
+ if (!policy.allowed) return result({
79
+ status: "blocked",
80
+ error: `Command blocked: ${policy.reason}`
81
+ });
82
+ const env = prepareEnv ? await prepareEnv(policy.sanitizedEnv, policy.effectiveCwd) : policy.sanitizedEnv;
83
+ return result(await registry.start({
84
+ owner,
85
+ command,
86
+ cwd: policy.effectiveCwd,
87
+ env: {
88
+ ...env,
89
+ COLUMNS: "200"
90
+ },
91
+ workspace,
92
+ isolation: getCommandIsolation?.(),
93
+ timeoutMs: commandTimeout(input.maxRuntimeMs, policy.timeoutMs),
94
+ snapshot: true,
95
+ signal
96
+ }));
157
97
  }
158
98
  };
159
99
  }
@@ -8,7 +8,15 @@ const MAX_FILE_SIZE = 10 * 1024 * 1024;
8
8
  const DEFAULT_MAX_LINES = 500;
9
9
  const ReadFileSchema = Type.Object({
10
10
  path: Type.String({ description: "File path to read" }),
11
- limit: Type.Optional(Type.Number({ description: "Max lines (default: 500)" }))
11
+ offset: Type.Optional(Type.Integer({
12
+ minimum: 1,
13
+ description: "First line to read, one-based (default: 1)"
14
+ })),
15
+ limit: Type.Optional(Type.Integer({
16
+ minimum: 1,
17
+ maximum: 2e3,
18
+ description: "Max lines (default: 500)"
19
+ }))
12
20
  });
13
21
  function createReadFileTool(workspace, options) {
14
22
  return {
@@ -31,7 +39,7 @@ async function executeReadFile(workspace, profileMarkdownRoot, params) {
31
39
  type: "text",
32
40
  text: `🚫 ${safety.message}`
33
41
  }],
34
- details: {}
42
+ details: { status: "failed" }
35
43
  };
36
44
  let normalized = resolvePathUnderWorkspace(params.path, workspace);
37
45
  let stats;
@@ -53,21 +61,30 @@ async function executeReadFile(workspace, profileMarkdownRoot, params) {
53
61
  type: "text",
54
62
  text: `🚫 File too large: ${formatSize(stats.size)}`
55
63
  }],
56
- details: {}
64
+ details: { status: "failed" }
57
65
  };
58
- const truncation = truncateHead(await readFile(normalized, "utf-8"), {
66
+ const content = await readFile(normalized, "utf-8");
67
+ const offset = Math.max(1, params.offset ?? 1);
68
+ const lines = content.split("\n");
69
+ if (offset > lines.length) throw new Error(`Offset ${offset} exceeds ${lines.length} lines`);
70
+ const truncation = truncateHead(lines.slice(offset - 1).join("\n"), {
59
71
  maxLines: params.limit || DEFAULT_MAX_LINES,
60
72
  maxBytes: DEFAULT_MAX_BYTES
61
73
  });
62
74
  let outputText = truncation.content;
63
75
  if (truncation.truncated) if (truncation.firstLineExceedsLimit) outputText = `(Line exceeds ${formatSize(DEFAULT_MAX_BYTES)})`;
64
- else outputText += `\n\n[${truncation.outputLines}/${truncation.totalLines} lines]`;
76
+ else outputText += `\n\n[Lines ${offset}-${offset + truncation.outputLines - 1} of ${lines.length}; continue with offset=${offset + truncation.outputLines}]`;
65
77
  return {
66
78
  content: [{
67
79
  type: "text",
68
80
  text: outputText
69
81
  }],
70
- details: {}
82
+ details: {
83
+ path: normalized,
84
+ offset,
85
+ totalLines: lines.length,
86
+ truncated: truncation.truncated
87
+ }
71
88
  };
72
89
  } catch (error) {
73
90
  return {
@@ -75,7 +92,7 @@ async function executeReadFile(workspace, profileMarkdownRoot, params) {
75
92
  type: "text",
76
93
  text: `Error: ${error instanceof Error ? error.message : String(error)}`
77
94
  }],
78
- details: {}
95
+ details: { status: "failed" }
79
96
  };
80
97
  }
81
98
  }
@@ -0,0 +1,5 @@
1
+ /** Bounded native search; unavailable tools and invalid regexes are explicit failures. */
2
+ export declare function repositorySearch(cwd: string, args: string[], signal?: AbortSignal): Promise<{
3
+ output: string;
4
+ truncated: boolean;
5
+ }>;
@@ -0,0 +1,56 @@
1
+ import { resolveRipgrepBinary } from "../../infra/ripgrep.js";
2
+ import { spawn } from "node:child_process";
3
+ //#region src/agent/tools/repository-search.ts
4
+ /** Bounded native search; unavailable tools and invalid regexes are explicit failures. */
5
+ async function repositorySearch(cwd, args, signal) {
6
+ signal?.throwIfAborted();
7
+ const binary = await resolveRipgrepBinary();
8
+ return new Promise((resolve, reject) => {
9
+ const child = spawn(binary, [
10
+ "--no-config",
11
+ "--hidden",
12
+ "--glob",
13
+ "!.git",
14
+ "--glob",
15
+ "!node_modules",
16
+ ...args
17
+ ], { cwd });
18
+ const chunks = [];
19
+ let bytes = 0, truncated = false, stderr = "";
20
+ const timer = setTimeout(() => child.kill("SIGKILL"), 1e4);
21
+ const abort = () => child.kill("SIGKILL");
22
+ signal?.addEventListener("abort", abort, { once: true });
23
+ child.stdout.on("data", (chunk) => {
24
+ const remaining = Math.max(0, 5e4 - bytes);
25
+ chunks.push(chunk.subarray(0, remaining));
26
+ bytes += chunk.length;
27
+ if (bytes > 5e4) {
28
+ truncated = true;
29
+ child.kill("SIGKILL");
30
+ }
31
+ });
32
+ child.stderr.on("data", (chunk) => {
33
+ stderr = (stderr + String(chunk)).slice(-4e3);
34
+ });
35
+ child.on("error", reject);
36
+ child.on("close", (code) => {
37
+ clearTimeout(timer);
38
+ signal?.removeEventListener("abort", abort);
39
+ if (signal?.aborted) {
40
+ reject(signal.reason ?? /* @__PURE__ */ new Error("Search aborted"));
41
+ return;
42
+ }
43
+ if (code !== 0 && code !== 1 && !truncated) {
44
+ reject(new Error(stderr || "Search did not complete; check ripgrep installation or narrow the search."));
45
+ return;
46
+ }
47
+ resolve({
48
+ output: Buffer.concat(chunks).toString("utf8"),
49
+ truncated
50
+ });
51
+ });
52
+ if (signal?.aborted) abort();
53
+ });
54
+ }
55
+ //#endregion
56
+ export { repositorySearch };
@@ -0,0 +1,2 @@
1
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ export declare function createReviewWorkspaceTool(workspace: string): AgentTool;
@@ -0,0 +1,103 @@
1
+ import { readWorkspaceRevision } from "../coding/workspace-revision.js";
2
+ import { resolve } from "node:path";
3
+ import { execFile } from "node:child_process";
4
+ import { lstat, readFile, readlink, realpath } from "node:fs/promises";
5
+ import { promisify } from "node:util";
6
+ import { Type } from "@sinclair/typebox";
7
+ //#region src/agent/tools/review-workspace.ts
8
+ const exec$1 = promisify(execFile);
9
+ function createReviewWorkspaceTool(workspace) {
10
+ return {
11
+ name: "review_workspace",
12
+ label: "Review workspace",
13
+ parameters: Type.Object({}),
14
+ description: "Inspect the complete Git workspace diff against HEAD, including untracked text files. Includes pre-existing changes. A truncated view is explicitly incomplete; inspect large files separately. Does not modify Git state.",
15
+ supportsParallel: true,
16
+ idempotent: true,
17
+ async execute(_id, _args, signal) {
18
+ let cwd = workspace;
19
+ const git = async (args) => (await exec$1("git", [
20
+ "-c",
21
+ "core.fsmonitor=false",
22
+ ...args
23
+ ], {
24
+ cwd,
25
+ signal,
26
+ timeout: 1e4,
27
+ maxBuffer: 8 * 1024 * 1024
28
+ })).stdout;
29
+ cwd = await realpath((await git(["rev-parse", "--show-toplevel"])).trim());
30
+ const startRevision = await readWorkspaceRevision(cwd);
31
+ const head = await git([
32
+ "rev-parse",
33
+ "--verify",
34
+ "HEAD"
35
+ ]).catch(() => "");
36
+ const [diff, names] = await Promise.all([head ? git([
37
+ "diff",
38
+ "--no-ext-diff",
39
+ "--no-textconv",
40
+ "--binary",
41
+ "HEAD",
42
+ "--"
43
+ ]) : Promise.all([git([
44
+ "diff",
45
+ "--no-ext-diff",
46
+ "--no-textconv",
47
+ "--binary",
48
+ "--cached",
49
+ "--"
50
+ ]), git([
51
+ "diff",
52
+ "--no-ext-diff",
53
+ "--no-textconv",
54
+ "--binary",
55
+ "--"
56
+ ])]).then((parts) => parts.join("\n")), git([
57
+ "ls-files",
58
+ "--others",
59
+ "--exclude-standard",
60
+ "-z"
61
+ ])]);
62
+ let text = diff.slice(0, 2e5), complete = diff.length <= 2e5;
63
+ for (const path of names.split("\0").filter(Boolean)) {
64
+ signal?.throwIfAborted();
65
+ if (text.length >= 2e5) {
66
+ complete = false;
67
+ break;
68
+ }
69
+ const file = resolve(cwd, path), info = await lstat(file);
70
+ text += `\nUntracked file: ${path}\n`;
71
+ if (info.isSymbolicLink()) text += `Symlink to ${await readlink(file)}\n`;
72
+ else if (info.isFile() && info.size <= 5e4) {
73
+ const content = await readFile(file);
74
+ if (content.includes(0)) {
75
+ text += "(binary file; inspect separately)\n";
76
+ complete = false;
77
+ } else text += content.toString("utf8");
78
+ } else {
79
+ text += "(large file; inspect separately)\n";
80
+ complete = false;
81
+ }
82
+ }
83
+ complete &&= text.length <= 2e5;
84
+ const endRevision = await readWorkspaceRevision(cwd);
85
+ return {
86
+ content: [{
87
+ type: "text",
88
+ text: `Workspace changes against HEAD (including pre-existing changes):\n${text.slice(0, 2e5) || "(clean)"}${complete ? "" : "\n[Incomplete view]"}`
89
+ }],
90
+ details: {
91
+ status: "success",
92
+ command: "review_workspace",
93
+ complete,
94
+ exitCode: 0,
95
+ startRevision,
96
+ endRevision
97
+ }
98
+ };
99
+ }
100
+ };
101
+ }
102
+ //#endregion
103
+ export { createReviewWorkspaceTool };
@@ -33,7 +33,7 @@ function createWriteFileTool(workspace, options) {
33
33
  type: "text",
34
34
  text: `🚫 ${safety.message}`
35
35
  }],
36
- details: {}
36
+ details: { status: "failed" }
37
37
  };
38
38
  const writesProfileFile = Boolean(options?.profileMarkdownRoot && isBareProfileMarkdownFileName(p.path));
39
39
  const workspaceRoot = writesProfileFile ? options.profileMarkdownRoot : workspace;
@@ -47,7 +47,7 @@ function createWriteFileTool(workspace, options) {
47
47
  type: "text",
48
48
  text: `🚫 Sandbox: ${pathPolicy.reason}`
49
49
  }],
50
- details: {}
50
+ details: { status: "failed" }
51
51
  };
52
52
  const contentBytes = Buffer.byteLength(p.content, "utf-8");
53
53
  if (contentBytes > MAX_FILE_SIZE) return {
@@ -55,7 +55,7 @@ function createWriteFileTool(workspace, options) {
55
55
  type: "text",
56
56
  text: `🚫 File too large: ${contentBytes} bytes`
57
57
  }],
58
- details: {}
58
+ details: { status: "failed" }
59
59
  };
60
60
  const target = writesProfileFile ? resolveProfileMarkdownPathIfBareName(p.path, options.profileMarkdownRoot) : resolvePathUnderWorkspace(p.path, workspace);
61
61
  await mkdir(dirname(target), { recursive: true });
@@ -88,7 +88,7 @@ function createWriteFileTool(workspace, options) {
88
88
  type: "text",
89
89
  text: `Error: ${error instanceof Error ? error.message : String(error)}`
90
90
  }],
91
- details: {}
91
+ details: { status: "failed" }
92
92
  };
93
93
  }
94
94
  }
@@ -1,7 +1,7 @@
1
- import { extractToolCallsFromAssistant, extractToolResultId, sanitizeToolCallId, sanitizeToolCallIdsForCloudCodeAssist } from "./tool-call-id.js";
2
- import { makeMissingToolResult, repairToolUseResultPairing, sanitizeToolCallInputs, sanitizeToolUseResultPairing, stripToolResultDetails } from "./session-transcript-repair.js";
3
1
  import { resolveTranscriptPolicy } from "./transcript-policy.js";
4
2
  import { dropThinkingBlocks } from "./thinking.js";
3
+ import { extractToolCallsFromAssistant, extractToolResultId, sanitizeToolCallId, sanitizeToolCallIdsForCloudCodeAssist } from "./tool-call-id.js";
4
+ import { makeMissingToolResult, repairToolUseResultPairing, sanitizeToolCallInputs, sanitizeToolUseResultPairing, stripToolResultDetails } from "./session-transcript-repair.js";
5
5
  import { applySessionTranscriptHygiene, applySessionTranscriptHygieneForPersistence, applySessionTranscriptHygieneWithPolicy, resolvePolicyForModel, tryApplySessionTranscriptHygiene, tryApplySessionTranscriptHygieneForPersistence } from "./transcript-hygiene.js";
6
6
  import { stripToolMessages } from "./strip-tool-messages.js";
7
7
  export { applySessionTranscriptHygiene, applySessionTranscriptHygieneForPersistence, applySessionTranscriptHygieneWithPolicy, dropThinkingBlocks, extractToolCallsFromAssistant, extractToolResultId, makeMissingToolResult, repairToolUseResultPairing, resolvePolicyForModel, resolveTranscriptPolicy, sanitizeToolCallId, sanitizeToolCallIdsForCloudCodeAssist, sanitizeToolCallInputs, sanitizeToolUseResultPairing, stripToolMessages, stripToolResultDetails, tryApplySessionTranscriptHygiene, tryApplySessionTranscriptHygieneForPersistence };
@@ -1,9 +1,9 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { sanitizeToolCallIdsForCloudCodeAssist } from "./tool-call-id.js";
4
- import { sanitizeToolCallInputs, sanitizeToolUseResultPairing, stripToolResultDetails } from "./session-transcript-repair.js";
5
3
  import { resolveTranscriptPolicy } from "./transcript-policy.js";
6
4
  import { dropThinkingBlocks } from "./thinking.js";
5
+ import { sanitizeToolCallIdsForCloudCodeAssist } from "./tool-call-id.js";
6
+ import { sanitizeToolCallInputs, sanitizeToolUseResultPairing, stripToolResultDetails } from "./session-transcript-repair.js";
7
7
  //#region src/agent/transcript/transcript-hygiene.ts
8
8
  init_logger();
9
9
  const log = createLogger("transcript-hygiene");
@@ -10,8 +10,6 @@
10
10
  * without ever calling `structured_output`, we treat it as failure (`null`).
11
11
  * - Failures and aborts resolve to `null`. The workflow runtime continues — this
12
12
  * matches the pi-dynamic-workflows contract and keeps fan-out pipelines robust.
13
- * - We do NOT mutate `createDelegateChildHandle` — we just leverage its
14
- * `buildChildTools` injection point.
15
13
  */
16
14
  import type { AgentTool } from '@earendil-works/pi-agent-core';
17
15
  import type { Api, Model } from '@earendil-works/pi-ai';
@@ -1,8 +1,8 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { createSqliteTranscriptRuntime } from "../embedded/transcript-runtime.js";
3
4
  import { createDelegateChildHandle } from "../child-agent-factory.js";
4
5
  import { DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS } from "../tools/delegate-tool.js";
5
- import { emitSessionTranscriptUpdate } from "../../session/transcript-events.js";
6
6
  import { STRUCTURED_OUTPUT_TOOL_NAME, createStructuredOutputTool } from "./structured-output-tool.js";
7
7
  //#region src/agent/workflow/subagent-runner.ts
8
8
  init_logger();
@@ -27,24 +27,6 @@ var DelegateSubagentRunner = class {
27
27
  }
28
28
  const fullPrompt = buildPrompt(prompt, opts, wantStructured);
29
29
  const streamMode = resolveSubagentStreamMode(this.deps.getConfig);
30
- let transcriptPersistQueue = Promise.resolve();
31
- const persistTranscriptSnapshot = opts.sessionKey && this.deps.sessionStore ? (messages) => {
32
- const store = this.deps.sessionStore;
33
- const key = opts.sessionKey;
34
- if (!store || !key) return;
35
- const snapshot = cloneAgentMessages(messages);
36
- transcriptPersistQueue = transcriptPersistQueue.then(async () => {
37
- await store.saveMessages(key, snapshot);
38
- emitSessionTranscriptUpdate({ sessionKey: key });
39
- }).catch((err) => {
40
- const msg = err instanceof Error ? err.message : String(err);
41
- log.warn({
42
- err,
43
- sessionKey: key,
44
- errorMessage: msg
45
- }, `Failed to persist workflow subagent transcript snapshot: ${msg}`);
46
- });
47
- } : void 0;
48
30
  const childOptions = {
49
31
  workspace: this.deps.workspace,
50
32
  goal: fullPrompt,
@@ -72,20 +54,22 @@ var DelegateSubagentRunner = class {
72
54
  onProgress: (event) => {
73
55
  opts.onProgress?.(mapChildProgressEvent(event));
74
56
  }
75
- } : void 0,
76
- onTranscriptSnapshot: persistTranscriptSnapshot
57
+ } : void 0
77
58
  };
78
- if (opts.sessionKey && opts.sessionMetadata && this.deps.sessionStore) await this.preparePersistentSubagentSession(opts.sessionKey, opts.sessionMetadata);
59
+ if (opts.sessionKey && opts.sessionMetadata && this.deps.sessionStore) {
60
+ await this.preparePersistentSubagentSession(opts.sessionKey, opts.sessionMetadata);
61
+ childOptions.sessionKey = opts.sessionKey;
62
+ childOptions.transcriptRuntime = await createSqliteTranscriptRuntime({
63
+ sessionKey: opts.sessionKey,
64
+ sessionStore: this.deps.sessionStore
65
+ });
66
+ }
79
67
  const handle = createDelegateChildHandle(childOptions);
80
68
  const onAbort = () => handle.abort();
81
69
  opts.signal?.addEventListener("abort", onAbort, { once: true });
82
70
  try {
83
- const { summary, messages } = await handle.run();
84
- await transcriptPersistQueue;
85
- if (opts.sessionKey && this.deps.sessionStore) {
86
- await this.deps.sessionStore.saveMessages(opts.sessionKey, messages);
87
- emitSessionTranscriptUpdate({ sessionKey: opts.sessionKey });
88
- }
71
+ const { summary, status } = await handle.run();
72
+ if (status !== "success") return null;
89
73
  if (opts.signal?.aborted) return null;
90
74
  if (wantStructured) {
91
75
  if (!capture.called) {
@@ -144,9 +128,6 @@ var DelegateSubagentRunner = class {
144
128
  });
145
129
  }
146
130
  };
147
- function cloneAgentMessages(messages) {
148
- return messages.map((message) => structuredClone(message));
149
- }
150
131
  function resolveAllowedToolNames(requested, wantStructured) {
151
132
  const filtered = (requested && requested.length > 0 ? requested : [...DEFAULT_DELEGATE_TOOLS]).map((s) => String(s).trim()).filter((s) => s.length > 0).filter((s) => !DELEGATE_BLOCKED_TOOLS.has(s));
152
133
  if (wantStructured && !filtered.includes("structured_output")) filtered.push(STRUCTURED_OUTPUT_TOOL_NAME);