@gajae-code/coding-agent 0.18.7 → 0.18.9

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 (344) hide show
  1. package/CHANGELOG.md +377 -1
  2. package/dist/types/async/endpoint-id.d.ts +16 -0
  3. package/dist/types/async/job-manager.d.ts +1 -1
  4. package/dist/types/async/support.d.ts +0 -14
  5. package/dist/types/capability/mcp.d.ts +2 -0
  6. package/dist/types/capability/skill.d.ts +2 -0
  7. package/dist/types/capability/types.d.ts +2 -0
  8. package/dist/types/cli/public-command-errors.d.ts +3 -1
  9. package/dist/types/cli/setup-cli.d.ts +1 -1
  10. package/dist/types/commands/deep-interview.d.ts +3 -0
  11. package/dist/types/commands/mcp-serve.d.ts +4 -0
  12. package/dist/types/config/autorouting-tier-map.d.ts +348 -9
  13. package/dist/types/config/file-lock.d.ts +1 -0
  14. package/dist/types/config/model-bindings-applier.d.ts +2 -0
  15. package/dist/types/config/model-profile-activation.d.ts +11 -3
  16. package/dist/types/config/model-registry.d.ts +4 -9
  17. package/dist/types/config/skill-settings-defaults.d.ts +2 -0
  18. package/dist/types/cursor-delete-path.d.ts +1 -0
  19. package/dist/types/cursor-mcp-name.d.ts +8 -0
  20. package/dist/types/customization/inventory.d.ts +2 -0
  21. package/dist/types/debug/report-bundle-parent.d.ts +2 -0
  22. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.d.ts +1 -0
  23. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/version-manager.d.ts +31 -0
  24. package/dist/types/defaults/gjc-skills.generated.d.ts +5 -6
  25. package/dist/types/discovery/helpers.d.ts +6 -1
  26. package/dist/types/discovery/mcp-json.d.ts +1 -0
  27. package/dist/types/eval/py/kernel.d.ts +18 -0
  28. package/dist/types/export/html/css-color.d.ts +2 -0
  29. package/dist/types/export/html/html-export-destination.d.ts +2 -0
  30. package/dist/types/export/html/template.generated.d.ts +1 -1
  31. package/dist/types/extensibility/extensions/function-hooks-internal.d.ts +5 -0
  32. package/dist/types/extensibility/extensions/types.d.ts +7 -0
  33. package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +14 -1
  34. package/dist/types/extensibility/plugins/marketplace/cache.d.ts +2 -0
  35. package/dist/types/extensibility/plugins/plugin-link-path.d.ts +2 -0
  36. package/dist/types/extensibility/runtime-skill-discovery.d.ts +3 -1
  37. package/dist/types/extensibility/skill-management.d.ts +4 -1
  38. package/dist/types/extensibility/skills.d.ts +2 -0
  39. package/dist/types/gjc-runtime/deep-interview-crystallize.d.ts +74 -0
  40. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +11 -0
  41. package/dist/types/gjc-runtime/gc-runtime.d.ts +5 -0
  42. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -3
  43. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +0 -5
  44. package/dist/types/gjc-runtime/sidecar-bootstrap-env.d.ts +6 -0
  45. package/dist/types/gjc-runtime/state-argv.d.ts +1 -1
  46. package/dist/types/gjc-runtime/state-migrations.d.ts +8 -0
  47. package/dist/types/gjc-runtime/state-runtime.d.ts +95 -0
  48. package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
  49. package/dist/types/gjc-runtime/tmux-common.d.ts +8 -5
  50. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -0
  51. package/dist/types/internal-urls/skill-path.d.ts +1 -0
  52. package/dist/types/lsp/config.d.ts +8 -5
  53. package/dist/types/lsp/workspace-path.d.ts +1 -0
  54. package/dist/types/modes/acp/acp-agent.d.ts +7 -0
  55. package/dist/types/modes/components/custom-editor.d.ts +6 -0
  56. package/dist/types/modes/components/customization/customization-dashboard.d.ts +1 -0
  57. package/dist/types/modes/components/extensions/state-manager.d.ts +4 -3
  58. package/dist/types/modes/controllers/input-controller.d.ts +9 -0
  59. package/dist/types/modes/interactive-mode.d.ts +1 -0
  60. package/dist/types/modes/utils/interrupt-ownership.d.ts +3 -0
  61. package/dist/types/modes/utils/keybinding-matchers.d.ts +1 -0
  62. package/dist/types/modes/utils/macos-option-forwarding.d.ts +17 -0
  63. package/dist/types/progress/collect-project-progress.d.ts +38 -0
  64. package/dist/types/progress/progress-contract.d.ts +154 -0
  65. package/dist/types/progress/progress-snapshot.d.ts +11 -0
  66. package/dist/types/progress/project-progress.d.ts +141 -0
  67. package/dist/types/progress/render-progress.d.ts +28 -0
  68. package/dist/types/runtime-mcp/manager.d.ts +2 -1
  69. package/dist/types/runtime-mcp/mcp-redirect.d.ts +9 -0
  70. package/dist/types/runtime-mcp/oauth-public-url.d.ts +3 -0
  71. package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +1 -0
  72. package/dist/types/runtime-mcp/project-host-values.d.ts +27 -0
  73. package/dist/types/runtime-mcp/smithery-registry.d.ts +24 -0
  74. package/dist/types/runtime-mcp/types.d.ts +6 -0
  75. package/dist/types/sdk/acp/adapter.d.ts +1 -1
  76. package/dist/types/sdk/broker/broker-exit.d.ts +6 -2
  77. package/dist/types/sdk/broker/broker.d.ts +24 -2
  78. package/dist/types/sdk/broker/doctor-restart.d.ts +5 -0
  79. package/dist/types/sdk/broker/ensure.d.ts +14 -1
  80. package/dist/types/sdk/broker/session-index.d.ts +12 -6
  81. package/dist/types/sdk/bus/index.d.ts +12 -1
  82. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -1
  83. package/dist/types/sdk/client/client.d.ts +2 -0
  84. package/dist/types/sdk/host/query/handlers.d.ts +3 -0
  85. package/dist/types/sdk/index.d.ts +1 -0
  86. package/dist/types/sdk/router/session-router.d.ts +2 -0
  87. package/dist/types/sdk/session-list.d.ts +1 -1
  88. package/dist/types/sdk/session.d.ts +8 -0
  89. package/dist/types/session/agent-session.d.ts +38 -9
  90. package/dist/types/session/artifacts.d.ts +2 -2
  91. package/dist/types/session/internal/managed-gc-retirement-codec.d.ts +32 -0
  92. package/dist/types/session/internal/managed-session-scope.d.ts +79 -2
  93. package/dist/types/session/internal/managed-session-storage.d.ts +26 -1
  94. package/dist/types/session/internal/managed-task-owner-cleanup.d.ts +62 -0
  95. package/dist/types/session/internal/task-artifact-owner-access.d.ts +2 -0
  96. package/dist/types/session/internal/task-artifact-owner-transcript.d.ts +9 -1
  97. package/dist/types/session/session-manager.d.ts +31 -5
  98. package/dist/types/session/session-retirement.d.ts +31 -7
  99. package/dist/types/session/session-storage.d.ts +69 -2
  100. package/dist/types/session/task-artifact-owner-codec.d.ts +2 -0
  101. package/dist/types/setup/credential-auto-import.d.ts +1 -1
  102. package/dist/types/setup/credential-import.d.ts +6 -4
  103. package/dist/types/skill-state/active-state.d.ts +38 -0
  104. package/dist/types/skill-state/workflow-mutation-guard.d.ts +3 -0
  105. package/dist/types/slash-commands/helpers/progress-report.d.ts +8 -0
  106. package/dist/types/task/executor.d.ts +3 -0
  107. package/dist/types/task/isolation-dir.d.ts +26 -0
  108. package/dist/types/tools/ast-edit-write-path.d.ts +13 -0
  109. package/dist/types/tools/bash-skill-urls.d.ts +1 -1
  110. package/dist/types/tools/browser/cdp-url.d.ts +2 -0
  111. package/dist/types/tools/github-side-effect.d.ts +22 -0
  112. package/dist/types/tools/index.d.ts +3 -0
  113. package/dist/types/tools/monitor-mutation.d.ts +9 -0
  114. package/dist/types/tools/python.d.ts +9 -1
  115. package/dist/types/tools/recipe/recipe-guard.d.ts +7 -0
  116. package/dist/types/tools/restricted-cwd.d.ts +1 -0
  117. package/dist/types/tools/todo-write.d.ts +6 -0
  118. package/dist/types/utils/tools-checksum.d.ts +7 -0
  119. package/package.json +7 -7
  120. package/scripts/generate-sdk-operation-inventory.ts +21 -0
  121. package/scripts/verify-managed-empty-stop.ts +28 -0
  122. package/src/async/endpoint-id.ts +26 -0
  123. package/src/async/job-manager.ts +247 -132
  124. package/src/async/support.ts +0 -25
  125. package/src/capability/index.ts +15 -0
  126. package/src/capability/mcp.ts +2 -0
  127. package/src/capability/skill.ts +2 -0
  128. package/src/capability/types.ts +2 -0
  129. package/src/cli/auth-broker-cli.ts +1 -1
  130. package/src/cli/customize-doctor.ts +15 -2
  131. package/src/cli/doctor/repairs.ts +4 -1
  132. package/src/cli/doctor-supervisor.ts +3 -0
  133. package/src/cli/public-command-errors.ts +21 -1
  134. package/src/cli/public-command-registry.ts +28 -6
  135. package/src/cli/setup-cli.ts +4 -4
  136. package/src/cli/skills-cli.ts +5 -0
  137. package/src/commands/deep-interview.ts +47 -8
  138. package/src/commands/mcp-serve.ts +7 -0
  139. package/src/commands/sdk.ts +455 -397
  140. package/src/config/autorouting-tier-map.ts +117 -7
  141. package/src/config/file-lock.ts +316 -79
  142. package/src/config/mcp-schema.json +4 -0
  143. package/src/config/model-bindings-applier.ts +20 -0
  144. package/src/config/model-profile-activation.ts +240 -46
  145. package/src/config/model-registry.ts +47 -153
  146. package/src/config/skill-settings-defaults.ts +7 -0
  147. package/src/coordinator-mcp/policy.ts +3 -2
  148. package/src/coordinator-mcp/server.ts +2 -0
  149. package/src/cursor-delete-path.ts +10 -0
  150. package/src/cursor-mcp-name.ts +15 -0
  151. package/src/cursor.ts +13 -2
  152. package/src/customization/inventory.ts +4 -13
  153. package/src/dap/config.ts +2 -2
  154. package/src/debug/report-bundle-parent.ts +22 -0
  155. package/src/debug/report-bundle.ts +3 -0
  156. package/src/debug/system-info.ts +13 -1
  157. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +10 -6
  158. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.ts +67 -4
  159. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/version-manager.ts +80 -0
  160. package/src/defaults/gjc/skills/deep-interview/SKILL.md +105 -10
  161. package/src/defaults/gjc/skills/ralplan/SKILL.md +6 -4
  162. package/src/defaults/gjc-defaults.test.ts +18 -1
  163. package/src/defaults/gjc-defaults.ts +3 -0
  164. package/src/defaults/gjc-skills.generated.ts +58 -36
  165. package/src/discovery/agents.ts +6 -1
  166. package/src/discovery/builtin.ts +13 -1
  167. package/src/discovery/helpers.ts +171 -29
  168. package/src/discovery/mcp-json.ts +26 -12
  169. package/src/discovery/ssh.ts +1 -1
  170. package/src/discovery/substitute-plugin-root.ts +3 -1
  171. package/src/edit/file-read-cache.ts +1 -1
  172. package/src/eval/py/executor.ts +796 -154
  173. package/src/eval/py/kernel.ts +79 -13
  174. package/src/eval/py/tool-bridge.ts +4 -0
  175. package/src/export/html/css-color.ts +9 -0
  176. package/src/export/html/html-export-destination.ts +16 -0
  177. package/src/export/html/index.ts +7 -10
  178. package/src/export/html/template.generated.ts +1 -1
  179. package/src/extensibility/extensions/function-hooks-internal.ts +27 -0
  180. package/src/extensibility/extensions/runner.ts +15 -1
  181. package/src/extensibility/extensions/types.ts +7 -0
  182. package/src/extensibility/gjc-plugins/mcp-policy.ts +2 -1
  183. package/src/extensibility/gjc-plugins/runtime-adapters.ts +85 -8
  184. package/src/extensibility/plugins/manager.ts +3 -2
  185. package/src/extensibility/plugins/marketplace/cache.ts +15 -0
  186. package/src/extensibility/plugins/marketplace/manager.ts +11 -3
  187. package/src/extensibility/plugins/plugin-link-path.ts +12 -0
  188. package/src/extensibility/runtime-skill-discovery.ts +20 -2
  189. package/src/extensibility/skill-management.ts +9 -2
  190. package/src/extensibility/skills.ts +6 -1
  191. package/src/gjc-runtime/deep-interview-crystallize.ts +1814 -0
  192. package/src/gjc-runtime/deep-interview-recorder.ts +20 -2
  193. package/src/gjc-runtime/deep-interview-runtime.ts +1415 -13
  194. package/src/gjc-runtime/deep-interview-stage.ts +98 -21
  195. package/src/gjc-runtime/gc-runtime.ts +206 -9
  196. package/src/gjc-runtime/launch-worktree.ts +70 -9
  197. package/src/gjc-runtime/psmux-detect.ts +28 -4
  198. package/src/gjc-runtime/ralplan-runtime.ts +447 -52
  199. package/src/gjc-runtime/session-state-sidecar.ts +3 -2
  200. package/src/gjc-runtime/sidecar-bootstrap-env.ts +19 -0
  201. package/src/gjc-runtime/state-argv.ts +2 -0
  202. package/src/gjc-runtime/state-migrations.ts +91 -29
  203. package/src/gjc-runtime/state-runtime.ts +3716 -135
  204. package/src/gjc-runtime/state-writer.ts +105 -16
  205. package/src/gjc-runtime/tmux-common.ts +8 -5
  206. package/src/gjc-runtime/ultragoal-runtime.ts +16 -4
  207. package/src/gjc-runtime/workflow-manifest.generated.json +70 -42
  208. package/src/gjc-runtime/workflow-manifest.ts +54 -21
  209. package/src/harness-control-plane/operate.ts +12 -4
  210. package/src/harness-control-plane/owner.ts +5 -1
  211. package/src/hashline/parser.ts +48 -9
  212. package/src/hashline/recovery.ts +13 -4
  213. package/src/internal-urls/docs-index.generated.ts +20 -19
  214. package/src/internal-urls/skill-path.ts +19 -0
  215. package/src/internal-urls/skill-protocol.ts +2 -0
  216. package/src/lsp/config.ts +12 -63
  217. package/src/lsp/edits.ts +6 -0
  218. package/src/lsp/workspace-path.ts +51 -0
  219. package/src/main.ts +195 -31
  220. package/src/memories/index.ts +88 -7
  221. package/src/modes/acp/acp-agent.ts +88 -4
  222. package/src/modes/components/custom-editor.ts +14 -0
  223. package/src/modes/components/customization/customization-dashboard.ts +12 -0
  224. package/src/modes/components/extensions/extension-dashboard.ts +2 -2
  225. package/src/modes/components/extensions/state-manager.ts +15 -5
  226. package/src/modes/components/hook-editor.ts +1 -1
  227. package/src/modes/components/hook-selector.ts +1 -1
  228. package/src/modes/components/model-selector.ts +1 -4
  229. package/src/modes/components/provider-onboarding-selector.ts +1 -1
  230. package/src/modes/components/status-line/segments.ts +4 -0
  231. package/src/modes/controllers/event-controller.ts +11 -4
  232. package/src/modes/controllers/input-controller.ts +76 -31
  233. package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -16
  234. package/src/modes/controllers/selector-controller.ts +24 -15
  235. package/src/modes/controllers/todo-command-controller.ts +1 -1
  236. package/src/modes/interactive-mode.ts +5 -1
  237. package/src/modes/runtime-init.ts +4 -0
  238. package/src/modes/utils/abort-message.ts +3 -1
  239. package/src/modes/utils/interrupt-ownership.ts +12 -0
  240. package/src/modes/utils/keybinding-matchers.ts +4 -0
  241. package/src/modes/utils/macos-option-forwarding.ts +80 -0
  242. package/src/progress/collect-project-progress.ts +153 -0
  243. package/src/progress/progress-contract.ts +172 -0
  244. package/src/progress/progress-snapshot.ts +140 -0
  245. package/src/progress/project-progress.ts +446 -0
  246. package/src/progress/render-progress.ts +209 -0
  247. package/src/prompts/system/master-mode.md +1 -0
  248. package/src/prompts/tools/skill-discovery.md +1 -1
  249. package/src/runtime-mcp/client.ts +4 -2
  250. package/src/runtime-mcp/config-writer.ts +10 -6
  251. package/src/runtime-mcp/config.ts +1 -0
  252. package/src/runtime-mcp/json-rpc.ts +2 -1
  253. package/src/runtime-mcp/manager.ts +29 -11
  254. package/src/runtime-mcp/mcp-redirect.ts +73 -0
  255. package/src/runtime-mcp/oauth-flow.ts +14 -2
  256. package/src/runtime-mcp/oauth-public-url.ts +14 -0
  257. package/src/runtime-mcp/plugin-network-boundary.ts +4 -0
  258. package/src/runtime-mcp/pool.ts +6 -0
  259. package/src/runtime-mcp/project-host-values.ts +46 -0
  260. package/src/runtime-mcp/smithery-registry.ts +22 -3
  261. package/src/runtime-mcp/transports/http.ts +4 -3
  262. package/src/runtime-mcp/types.ts +6 -0
  263. package/src/sdk/acp/adapter.ts +95 -8
  264. package/src/sdk/broker/broker-exit.ts +52 -23
  265. package/src/sdk/broker/broker.ts +81 -6
  266. package/src/sdk/broker/doctor-restart.ts +4 -0
  267. package/src/sdk/broker/ensure.ts +31 -2
  268. package/src/sdk/broker/lifecycle.ts +711 -66
  269. package/src/sdk/broker/session-index.ts +191 -81
  270. package/src/sdk/bus/chat-daemon-cli.ts +38 -1
  271. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  272. package/src/sdk/bus/index.ts +238 -43
  273. package/src/sdk/bus/telegram-daemon-contract.ts +6 -1
  274. package/src/sdk/cli/session-cli.ts +17 -3
  275. package/src/sdk/client/client.ts +28 -8
  276. package/src/sdk/host/query/handlers.ts +9 -1
  277. package/src/sdk/host/session-runtime.test.ts +2705 -303
  278. package/src/sdk/host/session-runtime.ts +490 -143
  279. package/src/sdk/host/surface-policy.ts +1 -0
  280. package/src/sdk/index.ts +8 -0
  281. package/src/sdk/lifecycle-session.ts +3 -1
  282. package/src/sdk/prompt-deadline-manager.ts +15 -0
  283. package/src/sdk/protocol/operation-inventory.generated.json +146 -0
  284. package/src/sdk/protocol/operation-registry.ts +9 -2
  285. package/src/sdk/router/session-router.ts +82 -18
  286. package/src/sdk/session-list.ts +1 -0
  287. package/src/sdk/session.ts +69 -45
  288. package/src/session/agent-session.ts +679 -238
  289. package/src/session/artifacts.ts +176 -71
  290. package/src/session/internal/managed-gc-retirement-codec.ts +319 -0
  291. package/src/session/internal/managed-session-scope.ts +3779 -462
  292. package/src/session/internal/managed-session-storage.ts +501 -78
  293. package/src/session/internal/managed-task-owner-cleanup.ts +473 -0
  294. package/src/session/internal/task-artifact-owner-access.ts +19 -3
  295. package/src/session/internal/task-artifact-owner-transcript.ts +547 -1
  296. package/src/session/session-manager.ts +951 -133
  297. package/src/session/session-retirement.ts +573 -14
  298. package/src/session/session-storage.ts +447 -15
  299. package/src/session/task-artifact-owner-codec.ts +71 -8
  300. package/src/session/task-artifact-owner-retirement.ts +21 -19
  301. package/src/setup/credential-auto-import.ts +12 -3
  302. package/src/setup/credential-import.ts +176 -5
  303. package/src/setup/paseo/announce.ts +6 -1
  304. package/src/skill-state/active-state.ts +145 -2
  305. package/src/skill-state/workflow-mutation-guard.ts +102 -10
  306. package/src/slash-commands/builtin-registry.ts +39 -9
  307. package/src/slash-commands/helpers/mcp.ts +8 -4
  308. package/src/slash-commands/helpers/progress-report.ts +23 -0
  309. package/src/stt/setup.ts +3 -5
  310. package/src/task/commands.ts +3 -1
  311. package/src/task/executor.ts +4 -0
  312. package/src/task/index.ts +6 -0
  313. package/src/task/isolation-dir.ts +143 -0
  314. package/src/task/worktree.ts +16 -7
  315. package/src/tools/ask.ts +205 -6
  316. package/src/tools/ast-edit-write-path.ts +68 -0
  317. package/src/tools/ast-edit.ts +10 -1
  318. package/src/tools/bash-allowed-prefixes.ts +15 -0
  319. package/src/tools/bash-skill-urls.ts +56 -3
  320. package/src/tools/bash.ts +48 -79
  321. package/src/tools/browser/cdp-url.ts +18 -0
  322. package/src/tools/browser.ts +8 -1
  323. package/src/tools/descriptors.ts +5 -1
  324. package/src/tools/eval.ts +56 -36
  325. package/src/tools/gh.ts +10 -0
  326. package/src/tools/github-side-effect.ts +112 -0
  327. package/src/tools/image-gen.ts +1 -1
  328. package/src/tools/index.ts +3 -0
  329. package/src/tools/monitor-mutation.ts +27 -0
  330. package/src/tools/monitor.ts +7 -0
  331. package/src/tools/python.ts +188 -66
  332. package/src/tools/recipe/index.ts +9 -0
  333. package/src/tools/recipe/recipe-guard.ts +19 -0
  334. package/src/tools/restricted-cwd.ts +10 -0
  335. package/src/tools/skill-discovery.ts +5 -0
  336. package/src/tools/skill.ts +28 -1
  337. package/src/tools/todo-write.ts +10 -1
  338. package/src/tools/tool-catalog.generated.ts +1 -1
  339. package/src/tools/write.ts +1 -0
  340. package/src/utils/external-editor.ts +3 -2
  341. package/src/utils/tools-checksum.ts +34 -0
  342. package/src/utils/tools-manager.ts +24 -6
  343. package/src/web/insane/url-guard.ts +2 -1
  344. package/src/web/search/providers/codex.ts +3 -2
package/src/tools/eval.ts CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  } from "./output-meta";
21
21
  import { formatTitle, replaceTabs, shortenPath, truncateToWidth, wrapBrackets } from "./render-utils";
22
22
  import { evalToolDescriptionForSession } from "./session-descriptions";
23
- import { ToolAbortError, ToolError } from "./tool-errors";
23
+ import { ToolError, throwIfAborted } from "./tool-errors";
24
24
  import { toolResult } from "./tool-result";
25
25
  import { clampTimeout } from "./tool-timeouts";
26
26
 
@@ -233,24 +233,23 @@ export class EvalTool implements AgentTool<typeof evalSchema> {
233
233
  throw new ToolError("Eval tool requires a session when not using proxy executor");
234
234
  }
235
235
  const session = this.session;
236
-
237
- const cells: ResolvedEvalCell[] = [];
238
- for (let i = 0; i < params.cells.length; i++) {
239
- const cell = params.cells[i];
240
- const language: EvalLanguage = cell.language === "py" ? "python" : "js";
241
- const resolved = await resolveBackend(session, language);
242
- cells.push({
243
- index: i,
244
- title: cell.title,
245
- code: cell.code,
246
- timeoutMs: (cell.timeout ?? 30) * 1000,
247
- reset: cell.reset ?? false,
248
- resolved,
249
- });
250
- }
251
- const languages = uniqueEvalLanguages(cells);
252
- const notice = detailsNotice(cells);
236
+ session.assertEvalExecutionAllowed?.();
237
+ const cwd = session.cwd;
238
+ const settings = session.settings;
239
+ const sessionFile = session.getSessionFile?.() ?? null;
240
+ const kernelOwnerId = session.getEvalKernelOwnerId?.() ?? null;
241
+ const sessionId = sessionFile ? `session:${sessionFile}:cwd:${cwd}` : `cwd:${cwd}`;
242
+ const evalSession = {
243
+ ...session,
244
+ cwd,
245
+ settings,
246
+ getSessionFile: () => sessionFile,
247
+ getEvalKernelOwnerId: () => kernelOwnerId,
248
+ };
253
249
  const sessionAbortController = new AbortController();
250
+ const abortFromCaller = (): void => sessionAbortController.abort(signal?.reason);
251
+ if (signal?.aborted) abortFromCaller();
252
+ else signal?.addEventListener("abort", abortFromCaller, { once: true });
254
253
  let outputSink: OutputSink | undefined;
255
254
  let outputSummary: OutputSummary | undefined;
256
255
  let outputDumped = false;
@@ -261,12 +260,30 @@ export class EvalTool implements AgentTool<typeof evalSchema> {
261
260
  return outputSummary;
262
261
  };
263
262
 
264
- const execution = (async (): Promise<AgentToolResult<EvalToolDetails | undefined>> => {
263
+ const execution = Promise.resolve().then(async (): Promise<AgentToolResult<EvalToolDetails | undefined>> => {
265
264
  try {
266
- if (signal?.aborted) {
267
- throw new ToolAbortError();
268
- }
265
+ throwIfAborted(sessionAbortController.signal);
269
266
  session.assertEvalExecutionAllowed?.();
267
+ const cells: ResolvedEvalCell[] = [];
268
+ for (let i = 0; i < params.cells.length; i++) {
269
+ throwIfAborted(sessionAbortController.signal);
270
+ session.assertEvalExecutionAllowed?.();
271
+ const cell = params.cells[i];
272
+ const language: EvalLanguage = cell.language === "py" ? "python" : "js";
273
+ const resolved = await resolveBackend(evalSession, language);
274
+ throwIfAborted(sessionAbortController.signal);
275
+ session.assertEvalExecutionAllowed?.();
276
+ cells.push({
277
+ index: i,
278
+ title: cell.title,
279
+ code: cell.code,
280
+ timeoutMs: (cell.timeout ?? 30) * 1000,
281
+ reset: cell.reset ?? false,
282
+ resolved,
283
+ });
284
+ }
285
+ const languages = uniqueEvalLanguages(cells);
286
+ const notice = detailsNotice(cells);
270
287
 
271
288
  const tailBuffer = new TailBuffer(DEFAULT_MAX_BYTES * 2);
272
289
  const jsonOutputs: unknown[] = [];
@@ -320,31 +337,28 @@ export class EvalTool implements AgentTool<typeof evalSchema> {
320
337
  });
321
338
  };
322
339
 
323
- const sessionFile = session.getSessionFile?.() ?? undefined;
324
- const kernelOwnerId = session.getEvalKernelOwnerId?.() ?? undefined;
340
+ throwIfAborted(sessionAbortController.signal);
341
+ session.assertEvalExecutionAllowed?.();
325
342
  const { path: artifactPath, id: artifactId } = (await session.allocateOutputArtifact?.("eval")) ?? {};
343
+ throwIfAborted(sessionAbortController.signal);
326
344
  session.assertEvalExecutionAllowed?.();
327
345
  outputSink = new OutputSink({
328
346
  artifactPath,
329
347
  artifactId,
330
- headBytes: resolveOutputSinkHeadBytes(session.settings),
331
- maxColumns: resolveOutputMaxColumns(session.settings),
348
+ headBytes: resolveOutputSinkHeadBytes(settings),
349
+ maxColumns: resolveOutputMaxColumns(settings),
332
350
  onChunk: chunk => {
333
351
  appendTail(chunk);
334
352
  pushUpdate();
335
353
  },
336
354
  });
337
- const sessionId = sessionFile ? `session:${sessionFile}:cwd:${session.cwd}` : `cwd:${session.cwd}`;
338
-
339
355
  for (let i = 0; i < cells.length; i++) {
340
356
  const cell = cells[i];
341
357
  const backend = cell.resolved.backend;
342
358
  const timeoutSec = timeoutSecondsFromMs(cell.timeoutMs);
343
359
  const deadlineMs = Date.now() + timeoutSec * 1000;
344
360
  const timeoutSignal = AbortSignal.timeout(Math.max(0, deadlineMs - Date.now()));
345
- const combinedSignal = signal
346
- ? AbortSignal.any([signal, timeoutSignal, sessionAbortController.signal])
347
- : AbortSignal.any([timeoutSignal, sessionAbortController.signal]);
361
+ const combinedSignal = AbortSignal.any([timeoutSignal, sessionAbortController.signal]);
348
362
 
349
363
  const cellResult = cellResults[i];
350
364
  cellResult.status = "running";
@@ -353,15 +367,17 @@ export class EvalTool implements AgentTool<typeof evalSchema> {
353
367
  cellResult.exitCode = undefined;
354
368
  cellResult.durationMs = undefined;
355
369
  pushUpdate();
370
+ throwIfAborted(sessionAbortController.signal);
371
+ session.assertEvalExecutionAllowed?.();
356
372
 
357
373
  const startTime = Date.now();
358
374
  const result = await backend.execute(cell.code, {
359
- cwd: session.cwd,
375
+ cwd,
360
376
  sessionId,
361
377
  sessionFile: sessionFile ?? undefined,
362
- kernelOwnerId,
378
+ kernelOwnerId: kernelOwnerId ?? undefined,
363
379
  signal: combinedSignal,
364
- session,
380
+ session: evalSession,
365
381
  deadlineMs,
366
382
  reset: cell.reset,
367
383
  artifactPath,
@@ -511,9 +527,13 @@ export class EvalTool implements AgentTool<typeof evalSchema> {
511
527
  } catch {}
512
528
  }
513
529
  }
514
- })();
530
+ });
515
531
 
516
- return await (session.trackEvalExecution?.(execution, sessionAbortController) ?? execution);
532
+ try {
533
+ return await (session.trackEvalExecution?.(execution, sessionAbortController) ?? execution);
534
+ } finally {
535
+ signal?.removeEventListener("abort", abortFromCaller);
536
+ }
517
537
  }
518
538
  }
519
539
 
package/src/tools/gh.ts CHANGED
@@ -8,10 +8,12 @@ import { getWorktreeDir, hashPath, isEnoent, prompt, untilAborted } from "@gajae
8
8
  import * as z from "zod/v4";
9
9
  import type { Settings } from "../config/settings";
10
10
  import githubDescription from "../prompts/tools/github.md" with { type: "text" };
11
+ import { assertWorkflowMutationAllowed } from "../skill-state/workflow-mutation-guard";
11
12
  import * as git from "../utils/git";
12
13
  import type { ToolSession } from ".";
13
14
  import { formatShortSha } from "./gh-format";
14
15
  import { type CacheStatus, getOrFetchView, resolveGithubCacheAuthKey } from "./github-cache";
16
+ import { githubMutationTool, isGithubReadOnlyOp } from "./github-side-effect";
15
17
  import type { OutputMeta } from "./output-meta";
16
18
  import { ToolError, throwIfAborted } from "./tool-errors";
17
19
  import { toolResult } from "./tool-result";
@@ -2591,6 +2593,14 @@ export class GithubTool implements AgentTool<typeof githubSchema, GhToolDetails>
2591
2593
  _context?: AgentToolContext,
2592
2594
  ): Promise<AgentToolResult<GhToolDetails>> {
2593
2595
  return untilAborted(signal, async () => {
2596
+ if (!isGithubReadOnlyOp(params.op)) {
2597
+ await assertWorkflowMutationAllowed({
2598
+ cwd: this.session.cwd,
2599
+ sessionId: this.session.getSessionId?.() ?? undefined,
2600
+ tool: githubMutationTool,
2601
+ args: params,
2602
+ });
2603
+ }
2594
2604
  switch (params.op) {
2595
2605
  case "repo_view":
2596
2606
  return executeRepoView(this.session, params, signal);
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Classify `github` tool operations for the approval gate and the planning
3
+ * mutation guard. Read-only ops stay available. Every other op, including a
4
+ * missing or unrecognized one, is a side effect and fails closed.
5
+ */
6
+ import type { AgentTool } from "@gajae-code/agent-core";
7
+
8
+ /** Name-only tool the planning guard uses when `GithubTool.execute` checks itself. */
9
+ export const githubMutationTool = {
10
+ name: "github",
11
+ label: "GitHub",
12
+ description: "github",
13
+ parameters: {},
14
+ execute: async () => ({ content: [] }),
15
+ } as AgentTool;
16
+
17
+ const GITHUB_READ_ONLY_OPS = new Set([
18
+ "repo_view",
19
+ "search_issues",
20
+ "search_prs",
21
+ "search_code",
22
+ "search_commits",
23
+ "search_repos",
24
+ "run_watch",
25
+ ]);
26
+
27
+ const GITHUB_SIDE_EFFECT_OPS = new Set(["pr_create", "pr_checkout", "pr_push"]);
28
+
29
+ const TITLE_MAX = 160;
30
+
31
+ function recordOf(args: unknown): Record<string, unknown> | undefined {
32
+ if (!args || typeof args !== "object" || Array.isArray(args)) return undefined;
33
+ return args as Record<string, unknown>;
34
+ }
35
+
36
+ function stringField(record: Record<string, unknown> | undefined, key: string): string | undefined {
37
+ const value = record?.[key];
38
+ if (typeof value !== "string") return undefined;
39
+ const trimmed = value.trim();
40
+ return trimmed.length > 0 ? trimmed : undefined;
41
+ }
42
+
43
+ function clip(value: string): string {
44
+ const cleaned = value
45
+ .replace(/[\u0000-\u001f\u007f]/g, " ")
46
+ .replace(/\s+/g, " ")
47
+ .trim();
48
+ if (cleaned.length <= TITLE_MAX) return cleaned;
49
+ return `${cleaned.slice(0, TITLE_MAX - 1)}…`;
50
+ }
51
+
52
+ function formatPr(value: unknown): string {
53
+ if (typeof value === "string" && value.trim()) return value.trim();
54
+ if (!Array.isArray(value)) return "the current pull request";
55
+ const parts = value.filter((item): item is string => typeof item === "string" && item.trim().length > 0);
56
+ return parts.length > 0 ? parts.join(", ") : "the current pull request";
57
+ }
58
+
59
+ export function githubOp(args: unknown): string | undefined {
60
+ const op = recordOf(args)?.op;
61
+ return typeof op === "string" ? op : undefined;
62
+ }
63
+
64
+ /** True only for a known read-only github op. Missing and unknown ops are not read-only. */
65
+ export function isGithubReadOnlyArgs(args: unknown): boolean {
66
+ const op = githubOp(args);
67
+ return op !== undefined && GITHUB_READ_ONLY_OPS.has(op);
68
+ }
69
+
70
+ export function isGithubReadOnlyOp(op: string): boolean {
71
+ return GITHUB_READ_ONLY_OPS.has(op);
72
+ }
73
+
74
+ /**
75
+ * Approval summary for a side-effect github call. The PR body is omitted so a
76
+ * token pasted into `body` is not copied into the permission title.
77
+ */
78
+ export function describeGithubSideEffect(args: unknown): string {
79
+ const record = recordOf(args);
80
+ const op = githubOp(args) ?? "";
81
+ if (op === "pr_push") {
82
+ const branch = stringField(record, "branch") ?? "the current branch";
83
+ const lease = record?.forceWithLease === true ? " with --force-with-lease" : "";
84
+ return clip(`Push ${branch} to its pull request branch${lease} using stored git credentials`);
85
+ }
86
+ if (op === "pr_checkout") {
87
+ const force = record?.force === true ? " and reset the local branch" : "";
88
+ return clip(
89
+ `Check out ${formatPr(record?.pr)} into ~/.gjc/wt, write branch git config, and may add a remote${force}`,
90
+ );
91
+ }
92
+ if (op === "pr_create") {
93
+ const repo = stringField(record, "repo") ?? "the current repository";
94
+ const head = stringField(record, "head") ?? "the current branch";
95
+ const base = stringField(record, "base") ?? "the default base";
96
+ return clip(`Create a pull request on ${repo} from ${head} into ${base} with gh`);
97
+ }
98
+ return "Run a github operation that is not read-only";
99
+ }
100
+
101
+ export function githubPermissionIntent(
102
+ args: unknown,
103
+ ): { toolName: string; title: string; cacheKey: string } | undefined {
104
+ if (isGithubReadOnlyArgs(args)) return undefined;
105
+ const op = githubOp(args);
106
+ const cacheOp = op && GITHUB_SIDE_EFFECT_OPS.has(op) ? op : "unspecified";
107
+ return {
108
+ toolName: "github",
109
+ title: describeGithubSideEffect(args),
110
+ cacheKey: `github:${cacheOp}`,
111
+ };
112
+ }
@@ -1273,7 +1273,7 @@ function buildOpenAIImageHeaders(model: Model, apiKey: string, sessionId: string
1273
1273
  headers.set(OPENAI_HEADERS.ORIGINATOR, OPENAI_HEADER_VALUES.ORIGINATOR_CODEX);
1274
1274
  headers.set(
1275
1275
  "User-Agent",
1276
- `pi/${packageJson.version} (${sanitizeHeaderComponent(os.platform())} ${sanitizeHeaderComponent(os.release())}; ${sanitizeHeaderComponent(os.arch())})`,
1276
+ `${OPENAI_HEADER_VALUES.ORIGINATOR_CODEX}/${packageJson.version} (${sanitizeHeaderComponent(os.platform())} ${sanitizeHeaderComponent(os.release())}; ${sanitizeHeaderComponent(os.arch())})`,
1277
1277
  );
1278
1278
  if (sessionId) {
1279
1279
  headers.set(OPENAI_HEADERS.CONVERSATION_ID, sessionId);
@@ -19,6 +19,7 @@ import type { ArtifactManager } from "../session/artifacts";
19
19
  import type { ClientBridge } from "../session/client-bridge";
20
20
  import type { FoldAdapter } from "../session/fold-coordinator";
21
21
  import type { CustomMessage } from "../session/messages";
22
+ import type { SessionArtifactPublication } from "../session/session-manager";
22
23
  import type { ToolChoiceQueue } from "../session/tool-choice-queue";
23
24
  import type { SkillActiveEntry } from "../skill-state/active-state";
24
25
  import type { AgentOutputManager } from "../task/output-manager";
@@ -308,6 +309,8 @@ export interface ToolSession {
308
309
  registerSessionCleanup?: (cleanup: () => Promise<void> | void) => () => void;
309
310
  /** Allocate a new artifact path and ID for session-scoped truncated output. */
310
311
  allocateOutputArtifact?: (toolType: string) => Promise<{ id?: string; path?: string }>;
312
+ /** Capture owner-bound artifact publication authority for one session lifecycle. */
313
+ captureArtifactPublication?: () => SessionArtifactPublication;
311
314
  /** Get session spawns */
312
315
  getSessionSpawns: () => string | null;
313
316
  /** Get resolved model string if explicitly set for this session */
@@ -0,0 +1,27 @@
1
+ import type { AgentTool } from "@gajae-code/agent-core";
2
+ import { assertWorkflowMutationAllowed } from "../skill-state/workflow-mutation-guard";
3
+
4
+ const bashShapedTool = {
5
+ name: "bash",
6
+ label: "bash",
7
+ description: "bash",
8
+ parameters: {},
9
+ execute: async () => ({ content: [] }),
10
+ } as AgentTool;
11
+
12
+ /**
13
+ * Judge a monitor command with the same mutation rules as bash. Monitor is a
14
+ * background shell, so a planning-phase mutation must fail before the job starts.
15
+ */
16
+ export async function assertMonitorMutationAllowed(input: {
17
+ cwd: string;
18
+ sessionId?: string;
19
+ command: string;
20
+ }): Promise<void> {
21
+ await assertWorkflowMutationAllowed({
22
+ cwd: input.cwd,
23
+ sessionId: input.sessionId,
24
+ tool: bashShapedTool,
25
+ args: { command: input.command },
26
+ });
27
+ }
@@ -7,6 +7,7 @@ import { truncateTail } from "../session/streaming-output";
7
7
  import { lookupOwnedRegistration } from "../session/terminal-abort";
8
8
  import { BashTool } from "./bash";
9
9
  import type { ToolSession } from "./index";
10
+ import { assertMonitorMutationAllowed } from "./monitor-mutation";
10
11
  import { ToolError } from "./tool-errors";
11
12
  import { TOOL_TIMEOUTS } from "./tool-timeouts";
12
13
 
@@ -137,6 +138,12 @@ export class MonitorTool implements AgentTool<typeof monitorSchema, MonitorToolD
137
138
  throw new ToolError("Async execution is disabled; the monitor tool is unavailable in this session.");
138
139
  }
139
140
 
141
+ await assertMonitorMutationAllowed({
142
+ cwd: this.session.cwd,
143
+ sessionId: this.session.getSessionId?.() ?? undefined,
144
+ command: params.command,
145
+ });
146
+
140
147
  const persistent = params.persistent ?? false;
141
148
  const label = buildMonitorLabel(params);
142
149
  const ownerId = this.session.getAgentId?.() ?? undefined;