subharness 0.0.3 → 0.0.5

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 (241) hide show
  1. package/README.md +39 -9
  2. package/dist/adapters/approval-context.d.ts +2 -0
  3. package/dist/adapters/approval-context.js +9 -0
  4. package/dist/adapters/approval-context.js.map +1 -0
  5. package/dist/adapters/approval-lifetime.d.ts +8 -0
  6. package/dist/adapters/approval-lifetime.js +50 -0
  7. package/dist/adapters/approval-lifetime.js.map +1 -0
  8. package/dist/adapters/claude-approvals.d.ts +4 -0
  9. package/dist/adapters/claude-approvals.js +32 -0
  10. package/dist/adapters/claude-approvals.js.map +1 -0
  11. package/dist/adapters/claude-permissions.js +1 -1
  12. package/dist/adapters/claude-permissions.js.map +1 -1
  13. package/dist/adapters/claude-process.d.ts +3 -0
  14. package/dist/adapters/claude-process.js +11 -1
  15. package/dist/adapters/claude-process.js.map +1 -1
  16. package/dist/adapters/claude-result.d.ts +2 -0
  17. package/dist/adapters/claude-result.js +22 -0
  18. package/dist/adapters/claude-result.js.map +1 -0
  19. package/dist/adapters/claude.js +60 -12
  20. package/dist/adapters/claude.js.map +1 -1
  21. package/dist/adapters/codex-approvals.d.ts +6 -0
  22. package/dist/adapters/codex-approvals.js +111 -0
  23. package/dist/adapters/codex-approvals.js.map +1 -0
  24. package/dist/adapters/codex.js +36 -3
  25. package/dist/adapters/codex.js.map +1 -1
  26. package/dist/adapters/copilot-permissions.d.ts +26 -0
  27. package/dist/adapters/copilot-permissions.js +121 -0
  28. package/dist/adapters/copilot-permissions.js.map +1 -0
  29. package/dist/adapters/copilot-tools.d.ts +12 -0
  30. package/dist/adapters/copilot-tools.js +61 -0
  31. package/dist/adapters/copilot-tools.js.map +1 -0
  32. package/dist/adapters/copilot.d.ts +108 -0
  33. package/dist/adapters/copilot.js +819 -0
  34. package/dist/adapters/copilot.js.map +1 -0
  35. package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
  36. package/dist/adapters/cursor-cli-approvals.js +83 -0
  37. package/dist/adapters/cursor-cli-approvals.js.map +1 -0
  38. package/dist/adapters/cursor-cli-model.d.ts +4 -0
  39. package/dist/adapters/cursor-cli-model.js +64 -0
  40. package/dist/adapters/cursor-cli-model.js.map +1 -0
  41. package/dist/adapters/cursor-cli-session.d.ts +32 -0
  42. package/dist/adapters/cursor-cli-session.js +316 -0
  43. package/dist/adapters/cursor-cli-session.js.map +1 -0
  44. package/dist/adapters/cursor-cli-tools.d.ts +20 -0
  45. package/dist/adapters/cursor-cli-tools.js +181 -0
  46. package/dist/adapters/cursor-cli-tools.js.map +1 -0
  47. package/dist/adapters/cursor-cli.d.ts +2 -0
  48. package/dist/adapters/cursor-cli.js +306 -0
  49. package/dist/adapters/cursor-cli.js.map +1 -0
  50. package/dist/adapters/cursor-model.d.ts +7 -0
  51. package/dist/adapters/cursor-model.js +67 -0
  52. package/dist/adapters/cursor-model.js.map +1 -0
  53. package/dist/adapters/cursor-rpc.d.ts +42 -0
  54. package/dist/adapters/cursor-rpc.js +271 -0
  55. package/dist/adapters/cursor-rpc.js.map +1 -0
  56. package/dist/adapters/cursor-session.d.ts +4 -0
  57. package/dist/adapters/cursor-session.js +327 -0
  58. package/dist/adapters/cursor-session.js.map +1 -0
  59. package/dist/adapters/cursor-startup.d.ts +16 -0
  60. package/dist/adapters/cursor-startup.js +74 -0
  61. package/dist/adapters/cursor-startup.js.map +1 -0
  62. package/dist/adapters/cursor-tools.d.ts +11 -0
  63. package/dist/adapters/cursor-tools.js +49 -0
  64. package/dist/adapters/cursor-tools.js.map +1 -0
  65. package/dist/adapters/cursor.d.ts +6 -0
  66. package/dist/adapters/cursor.js +17 -0
  67. package/dist/adapters/cursor.js.map +1 -0
  68. package/dist/adapters/fx-approvals.d.ts +2 -0
  69. package/dist/adapters/fx-approvals.js +14 -0
  70. package/dist/adapters/fx-approvals.js.map +1 -0
  71. package/dist/adapters/fx-auth.d.ts +12 -2
  72. package/dist/adapters/fx-auth.js +51 -61
  73. package/dist/adapters/fx-auth.js.map +1 -1
  74. package/dist/adapters/fx-profile.d.ts +8 -0
  75. package/dist/adapters/fx-profile.js +101 -0
  76. package/dist/adapters/fx-profile.js.map +1 -0
  77. package/dist/adapters/fx-rpc.d.ts +2 -0
  78. package/dist/adapters/fx-rpc.js +30 -4
  79. package/dist/adapters/fx-rpc.js.map +1 -1
  80. package/dist/adapters/fx-status.d.ts +2 -0
  81. package/dist/adapters/fx-status.js +96 -0
  82. package/dist/adapters/fx-status.js.map +1 -0
  83. package/dist/adapters/fx.js +77 -30
  84. package/dist/adapters/fx.js.map +1 -1
  85. package/dist/adapters/opencode-access.d.ts +13 -0
  86. package/dist/adapters/opencode-access.js +76 -0
  87. package/dist/adapters/opencode-access.js.map +1 -0
  88. package/dist/adapters/opencode-config.d.ts +11 -0
  89. package/dist/adapters/opencode-config.js +238 -0
  90. package/dist/adapters/opencode-config.js.map +1 -0
  91. package/dist/adapters/opencode-http.d.ts +28 -0
  92. package/dist/adapters/opencode-http.js +297 -0
  93. package/dist/adapters/opencode-http.js.map +1 -0
  94. package/dist/adapters/opencode-tools.d.ts +19 -0
  95. package/dist/adapters/opencode-tools.js +127 -0
  96. package/dist/adapters/opencode-tools.js.map +1 -0
  97. package/dist/adapters/opencode.d.ts +2 -0
  98. package/dist/adapters/opencode.js +569 -0
  99. package/dist/adapters/opencode.js.map +1 -0
  100. package/dist/adapters/rpc.d.ts +3 -0
  101. package/dist/adapters/rpc.js +45 -4
  102. package/dist/adapters/rpc.js.map +1 -1
  103. package/dist/adapters/types.d.ts +7 -0
  104. package/dist/adapters/types.js.map +1 -1
  105. package/dist/approvals/schema.d.ts +4 -0
  106. package/dist/approvals/schema.js +70 -0
  107. package/dist/approvals/schema.js.map +1 -0
  108. package/dist/approvals/types.d.ts +47 -0
  109. package/dist/approvals/types.js +2 -0
  110. package/dist/approvals/types.js.map +1 -0
  111. package/dist/cli/args.d.ts +3 -2
  112. package/dist/cli/args.js +24 -3
  113. package/dist/cli/args.js.map +1 -1
  114. package/dist/cli/dashboard-client.d.ts +5 -1
  115. package/dist/cli/dashboard-client.js +162 -15
  116. package/dist/cli/dashboard-client.js.map +1 -1
  117. package/dist/cli/dashboard-controller.d.ts +7 -0
  118. package/dist/cli/dashboard-controller.js +27 -0
  119. package/dist/cli/dashboard-controller.js.map +1 -0
  120. package/dist/cli/dashboard-detail-view.d.ts +16 -0
  121. package/dist/cli/dashboard-detail-view.js +162 -0
  122. package/dist/cli/dashboard-detail-view.js.map +1 -0
  123. package/dist/cli/dashboard-history-view.d.ts +29 -0
  124. package/dist/cli/dashboard-history-view.js +211 -0
  125. package/dist/cli/dashboard-history-view.js.map +1 -0
  126. package/dist/cli/dashboard-input.d.ts +14 -0
  127. package/dist/cli/dashboard-input.js +128 -0
  128. package/dist/cli/dashboard-input.js.map +1 -0
  129. package/dist/cli/dashboard-layout.d.ts +12 -1
  130. package/dist/cli/dashboard-layout.js +32 -30
  131. package/dist/cli/dashboard-layout.js.map +1 -1
  132. package/dist/cli/dashboard-renderer.d.ts +30 -2
  133. package/dist/cli/dashboard-renderer.js +125 -7
  134. package/dist/cli/dashboard-renderer.js.map +1 -1
  135. package/dist/cli/dashboard-style.d.ts +9 -0
  136. package/dist/cli/dashboard-style.js +36 -0
  137. package/dist/cli/dashboard-style.js.map +1 -0
  138. package/dist/cli/dashboard.d.ts +5 -3
  139. package/dist/cli/dashboard.js +102 -12
  140. package/dist/cli/dashboard.js.map +1 -1
  141. package/dist/cli/help.d.ts +1 -1
  142. package/dist/cli/help.js +37 -12
  143. package/dist/cli/help.js.map +1 -1
  144. package/dist/cli/input.d.ts +1 -0
  145. package/dist/cli/input.js +23 -17
  146. package/dist/cli/input.js.map +1 -1
  147. package/dist/cli/main.js +6 -2
  148. package/dist/cli/main.js.map +1 -1
  149. package/dist/cli/output.js +17 -1
  150. package/dist/cli/output.js.map +1 -1
  151. package/dist/config/access-provenance.d.ts +10 -0
  152. package/dist/config/access-provenance.js +31 -0
  153. package/dist/config/access-provenance.js.map +1 -0
  154. package/dist/config/access.d.ts +12 -2
  155. package/dist/config/access.js +125 -27
  156. package/dist/config/access.js.map +1 -1
  157. package/dist/config/loader.js +1 -0
  158. package/dist/config/loader.js.map +1 -1
  159. package/dist/config/oidc.js +4 -2
  160. package/dist/config/oidc.js.map +1 -1
  161. package/dist/config/project.js +2 -1
  162. package/dist/config/project.js.map +1 -1
  163. package/dist/config/resolve-access.js +24 -10
  164. package/dist/config/resolve-access.js.map +1 -1
  165. package/dist/index.d.ts +2 -2
  166. package/dist/index.js +1 -1
  167. package/dist/index.js.map +1 -1
  168. package/dist/process-diagnostics.d.ts +2 -0
  169. package/dist/process-diagnostics.js +11 -0
  170. package/dist/process-diagnostics.js.map +1 -0
  171. package/dist/runtime/access-errors.d.ts +4 -0
  172. package/dist/runtime/access-errors.js +25 -0
  173. package/dist/runtime/access-errors.js.map +1 -0
  174. package/dist/runtime/approval-registry.d.ts +27 -0
  175. package/dist/runtime/approval-registry.js +126 -0
  176. package/dist/runtime/approval-registry.js.map +1 -0
  177. package/dist/runtime/client.js +54 -14
  178. package/dist/runtime/client.js.map +1 -1
  179. package/dist/runtime/coordinator.d.ts +17 -1
  180. package/dist/runtime/coordinator.js +124 -6
  181. package/dist/runtime/coordinator.js.map +1 -1
  182. package/dist/runtime/dashboard-sanitize.d.ts +2 -0
  183. package/dist/runtime/dashboard-sanitize.js +7 -0
  184. package/dist/runtime/dashboard-sanitize.js.map +1 -0
  185. package/dist/runtime/dashboard.d.ts +43 -1
  186. package/dist/runtime/dashboard.js +2 -3
  187. package/dist/runtime/dashboard.js.map +1 -1
  188. package/dist/runtime/definition.js +11 -1
  189. package/dist/runtime/definition.js.map +1 -1
  190. package/dist/runtime/select-native.d.ts +2 -1
  191. package/dist/runtime/select-native.js +28 -10
  192. package/dist/runtime/select-native.js.map +1 -1
  193. package/dist/runtime/service.js +24 -1
  194. package/dist/runtime/service.js.map +1 -1
  195. package/dist/runtime/types.d.ts +9 -1
  196. package/dist/runtime/types.js.map +1 -1
  197. package/dist/runtime/worker-approvals.d.ts +21 -0
  198. package/dist/runtime/worker-approvals.js +51 -0
  199. package/dist/runtime/worker-approvals.js.map +1 -0
  200. package/dist/runtime/worker-client.js +73 -20
  201. package/dist/runtime/worker-client.js.map +1 -1
  202. package/dist/runtime/worker-server.d.ts +2 -0
  203. package/dist/runtime/worker-server.js +39 -10
  204. package/dist/runtime/worker-server.js.map +1 -1
  205. package/dist/sdk/definitions.d.ts +4 -1
  206. package/dist/sdk/definitions.js +16 -2
  207. package/dist/sdk/definitions.js.map +1 -1
  208. package/dist/sdk/permission-validation.js +10 -1
  209. package/dist/sdk/permission-validation.js.map +1 -1
  210. package/dist/sdk/types.d.ts +29 -1
  211. package/dist/sdk/types.js.map +1 -1
  212. package/package.json +4 -1
  213. package/sdk/access-config.md +86 -4
  214. package/sdk/adapter-contract.md +7 -13
  215. package/sdk/additional-harnesses.md +43 -0
  216. package/sdk/agent-skill.md +7 -4
  217. package/sdk/agent.md +5 -3
  218. package/sdk/approvals.md +120 -0
  219. package/sdk/authentication.md +1 -1
  220. package/sdk/cli/dashboard-design.md +44 -4
  221. package/sdk/cli/dashboard-inspection.md +25 -0
  222. package/sdk/cli/index.md +20 -11
  223. package/sdk/cli/output.md +10 -4
  224. package/sdk/completion-notifications.md +2 -0
  225. package/sdk/config.md +1 -1
  226. package/sdk/copilot.md +53 -0
  227. package/sdk/cursor.md +68 -0
  228. package/sdk/diagnostics.md +29 -0
  229. package/sdk/distribution.md +53 -1
  230. package/sdk/evals.md +10 -4
  231. package/sdk/fx.md +51 -6
  232. package/sdk/harnesses.md +13 -13
  233. package/sdk/index.md +4 -2
  234. package/sdk/message-delivery.md +1 -1
  235. package/sdk/opencode.md +57 -0
  236. package/sdk/permissions.md +7 -5
  237. package/sdk/pr-integration.md +1 -1
  238. package/sdk/project-team.md +2 -0
  239. package/sdk/sessions.md +4 -1
  240. package/sdk/tools.md +1 -1
  241. package/sdk/v1-runtime.md +6 -6
@@ -10,7 +10,10 @@ import { ClaudeInput } from "./claude-input.js";
10
10
  import { claudeDelegationPermissions } from "./claude-permissions.js";
11
11
  import { claudeSettings, verifyClaudeAccess, verifyClaudePolicy, verifyClaudeOptions } from "./claude-auth.js";
12
12
  import { ClaudeSettingsUnavailable, claudeDefaultUnavailable, readClaudeAppliedSettings, verifyAppliedClaudeEffort } from "./claude-settings.js";
13
+ import { NativeApprovals } from "./approval-lifetime.js";
14
+ import { claudeApproval } from "./claude-approvals.js";
13
15
  import { ClaudeProcessOwner } from "./claude-process.js";
16
+ import { claudeResultFailure } from "./claude-result.js";
14
17
  const dependencies = {
15
18
  query,
16
19
  async managedSettings(cwd) {
@@ -59,7 +62,11 @@ export function createClaudeOpener(deps) {
59
62
  const input = new ClaudeInput();
60
63
  const processOwner = new ClaudeProcessOwner();
61
64
  let inputFailure;
65
+ const approvals = new NativeApprovals();
66
+ let acceptingApprovals = false;
62
67
  const requireInput = (toolName) => {
68
+ acceptingApprovals = false;
69
+ approvals.clear();
63
70
  tools.stopAdmission();
64
71
  const subject = toolName && /^[A-Za-z_][A-Za-z0-9_-]{0,127}$/u.test(toolName)
65
72
  ? `approval for native tool ${toolName}`
@@ -85,11 +92,25 @@ export function createClaudeOpener(deps) {
85
92
  ? { type: "preset", preset: "claude_code", append: options.agent.instructions }
86
93
  : { type: "preset", preset: "claude_code" },
87
94
  settingSources: ["user", "project", "local"],
88
- canUseTool: async (toolName) => {
95
+ canUseTool: async (toolName, toolInput, metadata) => {
96
+ if (options.onApproval && acceptingApprovals && toolName !== "AskUserQuestion") {
97
+ try {
98
+ const answer = await claudeApproval(approvals, options.onApproval, toolName, toolInput, metadata);
99
+ if (!acceptingApprovals || metadata.signal.aborted)
100
+ return { behavior: "deny", message: "The permission request is no longer pending." };
101
+ return answer;
102
+ }
103
+ catch (error) {
104
+ if (error instanceof AgentError && error.code === "REQUEST_EXPIRED")
105
+ return { behavior: "deny", message: "The permission request is no longer pending." };
106
+ }
107
+ }
89
108
  requireInput(toolName);
90
109
  return { behavior: "deny", message: inputFailure.message, interrupt: true };
91
110
  },
92
111
  onElicitation: async () => {
112
+ acceptingApprovals = false;
113
+ approvals.clear();
93
114
  requireInput();
94
115
  try {
95
116
  await native.interrupt();
@@ -102,6 +123,7 @@ export function createClaudeOpener(deps) {
102
123
  } });
103
124
  }
104
125
  catch {
126
+ const exit = processOwner.exitDescription();
105
127
  input.close();
106
128
  try {
107
129
  await processOwner.close();
@@ -109,20 +131,24 @@ export function createClaudeOpener(deps) {
109
131
  finally {
110
132
  await config.cleanup();
111
133
  }
112
- throw new AgentError("HARNESS_UNAVAILABLE", "Claude Code could not start.");
134
+ throw new AgentError("HARNESS_UNAVAILABLE", `Claude Code could not start${exit}.`);
113
135
  }
114
136
  const expectedModels = new Set();
115
137
  let retainedModel;
138
+ let startupPhase = "account inspection";
116
139
  try {
117
- verifyClaudeAccess(await native.accountInfo(), options.access);
140
+ const account = await native.accountInfo();
141
+ verifyClaudeAccess(account, options.access);
142
+ startupPhase = "model catalog retrieval";
118
143
  const models = await native.supportedModels();
119
144
  if (options.harness.model) {
120
145
  addCatalogEquivalentModels(expectedModels, models, options.harness.model);
121
146
  verifyClaudeOptions(models, options);
147
+ startupPhase = "model settings validation";
122
148
  try {
123
149
  const applied = await readClaudeAppliedSettings(native);
124
150
  if (!expectedModels.has(applied.model))
125
- throw new AgentError("INVALID_CONFIG", "Claude Code selected a different model than requested.");
151
+ throw new AgentError("INVALID_CONFIG", "Claude Code selected a different model than requested during startup settings validation.");
126
152
  verifyAppliedClaudeEffort(applied.effort, options.harness.effort);
127
153
  retainedModel = applied.model;
128
154
  expectedModels.add(applied.model);
@@ -133,6 +159,7 @@ export function createClaudeOpener(deps) {
133
159
  }
134
160
  }
135
161
  else {
162
+ startupPhase = "model settings validation";
136
163
  if (!native.getSettings || !native.setModel)
137
164
  throw claudeDefaultUnavailable();
138
165
  let selected;
@@ -144,9 +171,13 @@ export function createClaudeOpener(deps) {
144
171
  throw claudeDefaultUnavailable();
145
172
  throw error;
146
173
  }
174
+ startupPhase = "model catalog retrieval";
147
175
  verifyClaudeOptions(models, options, selected.model);
176
+ startupPhase = "model settings validation";
148
177
  verifyAppliedClaudeEffort(selected.effort, options.harness.effort);
178
+ startupPhase = "model catalog retrieval";
149
179
  addCatalogEquivalentModels(expectedModels, models, selected.model);
180
+ startupPhase = "model settings validation";
150
181
  try {
151
182
  await native.setModel(selected.model);
152
183
  }
@@ -162,16 +193,20 @@ export function createClaudeOpener(deps) {
162
193
  throw claudeDefaultUnavailable();
163
194
  throw error;
164
195
  }
165
- if (!expectedModels.has(pinned.model))
166
- throw claudeDefaultUnavailable();
196
+ if (!expectedModels.has(pinned.model)) {
197
+ throw new AgentError("INVALID_CONFIG", "Claude Code changed the selected native default during startup settings validation. Supply --model <model>.");
198
+ }
167
199
  verifyAppliedClaudeEffort(pinned.effort, options.harness.effort);
168
200
  retainedModel = pinned.model;
201
+ startupPhase = "model catalog retrieval";
169
202
  addCatalogEquivalentModels(expectedModels, models, pinned.model);
203
+ startupPhase = "model settings validation";
170
204
  }
171
205
  if (inputFailure)
172
206
  throw inputFailure;
173
207
  }
174
208
  catch (error) {
209
+ const exit = processOwner.exitDescription();
175
210
  input.close();
176
211
  native.close();
177
212
  try {
@@ -182,18 +217,19 @@ export function createClaudeOpener(deps) {
182
217
  }
183
218
  if (error instanceof AgentError)
184
219
  throw error;
185
- throw new AgentError("ACCESS_UNAVAILABLE", "Claude Code authentication could not be verified.");
220
+ throw new AgentError("HARNESS_FAILED", `Claude Code ${startupPhase} failed${exit}.`);
186
221
  }
187
222
  let closed = false;
188
223
  let preflight;
189
224
  let sessionFailure;
225
+ let exitObservedBeforeClose;
190
226
  let active;
191
227
  const reading = (async () => {
192
228
  try {
193
229
  for await (const message of native) {
194
230
  if (message.type === "system" && message.subtype === "init") {
195
231
  if (!expectedModels.has(message.model)) {
196
- sessionFailure = new AgentError("INVALID_CONFIG", "Claude Code selected a different model than requested.");
232
+ sessionFailure = new AgentError("INVALID_CONFIG", "Claude Code selected a different model than requested during native initialization.");
197
233
  }
198
234
  else if (permissionMode !== undefined && message.permissionMode !== permissionMode) {
199
235
  sessionFailure = new AgentError("INVALID_CONFIG", "Claude Code reported a different permission mode than requested.");
@@ -207,6 +243,8 @@ export function createClaudeOpener(deps) {
207
243
  if (message.type !== "result" || !active)
208
244
  continue;
209
245
  const current = active;
246
+ acceptingApprovals = false;
247
+ approvals.clear();
210
248
  await tools.drain();
211
249
  active = undefined;
212
250
  current.stop();
@@ -222,18 +260,22 @@ export function createClaudeOpener(deps) {
222
260
  current.resolve(message.result);
223
261
  }
224
262
  else
225
- current.reject(new AgentError("HARNESS_ERROR", "Claude Code could not complete the turn."));
263
+ current.reject(claudeResultFailure(message.subtype));
226
264
  }
227
265
  }
228
266
  catch {
229
267
  // Native diagnostics may contain credentials; return a stable safe message.
230
268
  }
231
269
  finally {
232
- const code = closed ? "SESSION_CLOSED" : "HARNESS_ERROR";
270
+ acceptingApprovals = false;
271
+ approvals.clear();
272
+ const explicitClose = exitObservedBeforeClose !== undefined;
273
+ const code = explicitClose ? "SESSION_CLOSED" : "HARNESS_ERROR";
233
274
  closed = true;
234
275
  input.close();
235
276
  await tools.drain();
236
- active?.reject(sessionFailure ?? inputFailure ?? new AgentError(code, "The Claude Code process stopped before completing the turn."));
277
+ const exit = explicitClose ? exitObservedBeforeClose : processOwner.exitDescription();
278
+ active?.reject(sessionFailure ?? inputFailure ?? new AgentError(code, `The Claude Code process stopped${exit} before completing the turn.`));
237
279
  active?.stop();
238
280
  active = undefined;
239
281
  try {
@@ -270,7 +312,7 @@ export function createClaudeOpener(deps) {
270
312
  throw error;
271
313
  }
272
314
  if (!expectedModels.has(applied.model))
273
- throw new AgentError("INVALID_CONFIG", "Claude Code changed the retained session model before submission.");
315
+ throw new AgentError("INVALID_CONFIG", "Claude Code changed the model during retained-session validation before submission.");
274
316
  verifyAppliedClaudeEffort(applied.effort, options.harness.effort);
275
317
  }
276
318
  if (closed)
@@ -287,6 +329,7 @@ export function createClaudeOpener(deps) {
287
329
  let stop;
288
330
  const stopped = new Promise(resolve => { stop = resolve; });
289
331
  active = { resolve, reject, stopped, stop, interrupted: false };
332
+ acceptingApprovals = true;
290
333
  input.push({ type: "user", message: { role: "user", content: prompt }, parent_tool_use_id: null, uuid: randomUUID() });
291
334
  });
292
335
  },
@@ -302,6 +345,8 @@ export function createClaudeOpener(deps) {
302
345
  if (!current)
303
346
  return;
304
347
  current.interrupted = true;
348
+ acceptingApprovals = false;
349
+ approvals.clear();
305
350
  tools.stopAdmission();
306
351
  try {
307
352
  await native.interrupt();
@@ -314,7 +359,10 @@ export function createClaudeOpener(deps) {
314
359
  },
315
360
  async resume() { throw new AgentError("RECOVERY_UNSUPPORTED", "Claude Code cannot retry failed execution without replaying input."); },
316
361
  async close() {
362
+ exitObservedBeforeClose ??= processOwner.exitDescription();
317
363
  closed = true;
364
+ acceptingApprovals = false;
365
+ approvals.clear();
318
366
  const pending = preflight;
319
367
  if (pending) {
320
368
  pending.cancel(new AgentError("SESSION_CLOSED", "The native session closed before submission."));
@@ -1 +1 @@
1
- {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"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","sourcesContent":["import { access } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { query, resolveSettings, type AccountInfo, type Options, type SDKMessage, type SDKUserMessage, type Settings, type ModelInfo } from \"@anthropic-ai/claude-agent-sdk\";\nimport { AgentError } from \"../errors.js\";\nimport type { AdapterOptions, NativeSession } from \"./types.js\";\nimport { privateClaudeConfig } from \"./claude-config.js\";\nimport { claudeTools } from \"./claude-tools.js\";\nimport { ClaudeInput } from \"./claude-input.js\";\nimport { claudeDelegationPermissions } from \"./claude-permissions.js\";\nimport { claudeSettings, verifyClaudeAccess, verifyClaudePolicy, verifyClaudeOptions } from \"./claude-auth.js\";\nimport { ClaudeSettingsUnavailable, claudeDefaultUnavailable, readClaudeAppliedSettings, verifyAppliedClaudeEffort } from \"./claude-settings.js\";\nimport { ClaudeProcessOwner } from \"./claude-process.js\";\n\ninterface ClaudeQuery extends AsyncIterable<SDKMessage> {\n accountInfo(): Promise<AccountInfo>;\n supportedModels(): Promise<ModelInfo[]>;\n interrupt(): Promise<unknown>;\n close(): void;\n getSettings?(): Promise<unknown>;\n setModel?(model?: string): Promise<void>;\n}\nexport interface ClaudeDependencies {\n query(args: {prompt: AsyncIterable<SDKUserMessage>; options: Options}): ClaudeQuery;\n executable(env: NodeJS.ProcessEnv): Promise<string>;\n managedSettings(cwd: string): Promise<Settings[]>;\n}\n\nconst dependencies: ClaudeDependencies = {\n query,\n async managedSettings(cwd) {\n const settings = await resolveSettings({cwd, settingSources:[\"user\", \"project\", \"local\"]});\n return settings.sources.filter(source => source.source === \"managed\").map(source => source.settings);\n },\n async executable(env) {\n for (const directory of (env.PATH ?? \"\").split(delimiter)) {\n const file = join(directory, \"claude\");\n try { await access(file, constants.X_OK); return file; } catch { /* Try the next PATH entry. */ }\n }\n throw new AgentError(\"HARNESS_UNAVAILABLE\", \"Install Claude Code and make claude available on PATH.\");\n },\n};\n\nfunction addCatalogEquivalentModels(expected: Set<string>, models: ModelInfo[], selected: string): void {\n expected.add(selected);\n for (const model of models) {\n if (model.value !== selected && model.resolvedModel !== selected) continue;\n expected.add(model.value);\n if (model.resolvedModel) expected.add(model.resolvedModel);\n }\n}\n\nexport const openClaude = createClaudeOpener(dependencies);\n\n/** Dependency injection is internal and replaces only the external SDK boundary in tests. */\nexport function createClaudeOpener(deps: ClaudeDependencies) {\n return async (options: AdapterOptions): Promise<NativeSession> => {\n if (options.harness.kind !== \"claudeCode\") throw new AgentError(\"INVALID_CONFIG\", \"Claude Code received configuration for a different harness.\");\n const permissionMode = options.harness.permissionMode;\n const settings = claudeSettings(options);\n const executable = await deps.executable(options.env);\n verifyClaudePolicy(await deps.managedSettings(options.cwd), settings.settings as Settings);\n const tools = claudeTools(options.agent);\n const allowedTools = [\n ...(options.harness.allowedTools ?? []),\n ...(tools.config.allowedTools ?? []),\n ...claudeDelegationPermissions(options),\n ];\n const config = await privateClaudeConfig(settings.settings as Settings);\n const input = new ClaudeInput<SDKUserMessage>();\n const processOwner = new ClaudeProcessOwner();\n let inputFailure: AgentError | undefined;\n const requireInput = (toolName?: string) => {\n tools.stopAdmission();\n const subject = toolName && /^[A-Za-z_][A-Za-z0-9_-]{0,127}$/u.test(toolName)\n ? `approval for native tool ${toolName}`\n : \"interactive input\";\n inputFailure = new AgentError(\"INPUT_REQUIRED\", `Claude Code needs ${subject}. Configure its native permissions before retrying.`);\n };\n let native: ClaudeQuery;\n try { native = deps.query({prompt: input, options: {\n pathToClaudeCodeExecutable: executable,\n spawnClaudeCodeProcess: processOwner.spawn,\n cwd: options.cwd,\n ...settings,\n ...tools.config,\n ...(allowedTools.length ? {allowedTools} : {}),\n ...(options.harness.disallowedTools !== undefined ? {disallowedTools:[...options.harness.disallowedTools]} : {}),\n ...(permissionMode !== undefined ? {permissionMode} : {}),\n ...(permissionMode === \"bypassPermissions\" ? {allowDangerouslySkipPermissions:true} : {}),\n settings: config.path,\n stderr: () => {},\n ...(options.harness.model ? {model: options.harness.model} : {}),\n systemPrompt: options.agent.instructions\n ? {type: \"preset\", preset: \"claude_code\", append: options.agent.instructions}\n : {type: \"preset\", preset: \"claude_code\"},\n settingSources: [\"user\", \"project\", \"local\"],\n canUseTool: async (toolName) => {\n requireInput(toolName);\n return {behavior: \"deny\", message: inputFailure!.message, interrupt: true};\n },\n onElicitation: async () => {\n requireInput();\n try { await native.interrupt(); } catch { native.close(); }\n return {action: \"decline\"};\n },\n }}); }\n catch {\n input.close();\n try { await processOwner.close(); }\n finally { await config.cleanup(); }\n throw new AgentError(\"HARNESS_UNAVAILABLE\", \"Claude Code could not start.\");\n }\n const expectedModels = new Set<string>();\n let retainedModel: string | undefined;\n try {\n verifyClaudeAccess(await native.accountInfo(), options.access);\n const models = await native.supportedModels();\n if (options.harness.model) {\n addCatalogEquivalentModels(expectedModels, models, options.harness.model);\n verifyClaudeOptions(models, options);\n try {\n const applied = await readClaudeAppliedSettings(native);\n if (!expectedModels.has(applied.model)) throw new AgentError(\"INVALID_CONFIG\", \"Claude Code selected a different model than requested.\");\n verifyAppliedClaudeEffort(applied.effort, options.harness.effort);\n retainedModel = applied.model;\n expectedModels.add(applied.model);\n } catch (error) {\n if (!(error instanceof ClaudeSettingsUnavailable)) throw error;\n }\n } else {\n if (!native.getSettings || !native.setModel) throw claudeDefaultUnavailable();\n let selected;\n try { selected = await readClaudeAppliedSettings(native); }\n catch (error) { if (error instanceof ClaudeSettingsUnavailable) throw claudeDefaultUnavailable(); throw error; }\n verifyClaudeOptions(models, options, selected.model);\n verifyAppliedClaudeEffort(selected.effort, options.harness.effort);\n addCatalogEquivalentModels(expectedModels, models, selected.model);\n try { await native.setModel(selected.model); } catch { throw claudeDefaultUnavailable(); }\n let pinned;\n try { pinned = await readClaudeAppliedSettings(native); }\n catch (error) { if (error instanceof ClaudeSettingsUnavailable) throw claudeDefaultUnavailable(); throw error; }\n if (!expectedModels.has(pinned.model)) throw claudeDefaultUnavailable();\n verifyAppliedClaudeEffort(pinned.effort, options.harness.effort);\n retainedModel = pinned.model;\n addCatalogEquivalentModels(expectedModels, models, pinned.model);\n }\n if (inputFailure) throw inputFailure;\n }\n catch (error) {\n input.close();\n native.close();\n try { await processOwner.close(); }\n finally { await config.cleanup(); }\n if (error instanceof AgentError) throw error;\n throw new AgentError(\"ACCESS_UNAVAILABLE\", \"Claude Code authentication could not be verified.\");\n }\n let closed = false;\n let preflight: {\n cancellation: Promise<never>;\n cancel(error: AgentError): void;\n stopped: Promise<void>;\n stop(): void;\n } | undefined;\n let sessionFailure: AgentError | undefined;\n let active: {\n resolve(text: string): void; reject(error: unknown): void;\n stopped: Promise<void>; stop(): void; interrupted: boolean;\n } | undefined;\n const reading = (async () => {\n try {\n for await (const message of native) {\n if (message.type === \"system\" && message.subtype === \"init\") {\n if (!expectedModels.has(message.model)) {\n sessionFailure = new AgentError(\"INVALID_CONFIG\", \"Claude Code selected a different model than requested.\");\n } else if (permissionMode !== undefined && message.permissionMode !== permissionMode) {\n sessionFailure = new AgentError(\"INVALID_CONFIG\", \"Claude Code reported a different permission mode than requested.\");\n }\n if (sessionFailure) {\n tools.stopAdmission();\n native.close();\n break;\n }\n }\n if (message.type !== \"result\" || !active) continue;\n const current = active;\n await tools.drain();\n active = undefined;\n current.stop();\n if (inputFailure) current.reject(inputFailure);\n else if (current.interrupted) current.reject(new AgentError(\"INTERRUPTED\", \"The native turn was interrupted.\"));\n else if (message.subtype === \"success\" && !message.is_error) {\n if (Buffer.byteLength(message.result, \"utf8\") > 1024 * 1024) {\n current.reject(new AgentError(\"RESPONSE_TOO_LARGE\", \"The Claude Code response exceeds 1 MiB.\"));\n } else current.resolve(message.result);\n }\n else current.reject(new AgentError(\"HARNESS_ERROR\", \"Claude Code could not complete the turn.\"));\n }\n } catch {\n // Native diagnostics may contain credentials; return a stable safe message.\n } finally {\n const code = closed ? \"SESSION_CLOSED\" : \"HARNESS_ERROR\";\n closed = true;\n input.close();\n await tools.drain();\n active?.reject(sessionFailure ?? inputFailure ?? new AgentError(code, \"The Claude Code process stopped before completing the turn.\"));\n active?.stop();\n active = undefined;\n try { await processOwner.close(); }\n finally { await config.cleanup(); }\n }\n })();\n return {\n async turn(prompt) {\n if (closed) return Promise.reject(sessionFailure ?? new AgentError(\"SESSION_CLOSED\", \"The native session has closed.\"));\n if (active || preflight) return Promise.reject(new AgentError(\"SESSION_BUSY\", \"A native turn is already active.\"));\n let cancel!: (error: AgentError) => void, stop!: () => void;\n const currentPreflight = {\n cancellation: new Promise<never>((_resolve, reject) => { cancel = reject; }),\n cancel(error: AgentError) { cancel(error); },\n stopped: new Promise<void>(resolve => { stop = resolve; }),\n stop() { stop(); },\n };\n preflight = currentPreflight;\n try {\n if (native.getSettings && retainedModel) {\n let applied;\n try { applied = await Promise.race([readClaudeAppliedSettings(native), currentPreflight.cancellation]); }\n catch (error) {\n if (error instanceof ClaudeSettingsUnavailable) throw new AgentError(\"INVALID_CONFIG\", \"Claude Code could not verify the retained session model before submission.\");\n throw error;\n }\n if (!expectedModels.has(applied.model)) throw new AgentError(\"INVALID_CONFIG\", \"Claude Code changed the retained session model before submission.\");\n verifyAppliedClaudeEffort(applied.effort, options.harness.effort);\n }\n if (closed) throw sessionFailure ?? new AgentError(\"SESSION_CLOSED\", \"The native session has closed.\");\n } finally {\n if (preflight === currentPreflight) preflight = undefined;\n currentPreflight.stop();\n }\n return await new Promise((resolve, reject) => {\n inputFailure = undefined;\n tools.start();\n let stop!: () => void;\n const stopped = new Promise<void>(resolve => { stop = resolve; });\n active = {resolve, reject, stopped, stop, interrupted:false};\n input.push({type:\"user\",message:{role:\"user\",content:prompt},parent_tool_use_id:null,uuid:randomUUID()});\n });\n },\n async steer() { throw new AgentError(\"UNSUPPORTED_DELIVERY\", \"Claude Code does not expose verified active steering.\"); },\n async interrupt() {\n const pending = preflight;\n if (pending) {\n pending.cancel(new AgentError(\"INTERRUPTED\", \"The native turn was interrupted before submission.\"));\n await pending.stopped;\n return;\n }\n const current = active;\n if (!current) return;\n current.interrupted = true;\n tools.stopAdmission();\n try { await native.interrupt(); }\n catch {\n current.interrupted = false;\n throw new AgentError(\"CANCEL_FAILED\", \"Claude Code did not confirm interruption.\");\n }\n await current.stopped;\n },\n async resume() { throw new AgentError(\"RECOVERY_UNSUPPORTED\", \"Claude Code cannot retry failed execution without replaying input.\"); },\n async close() {\n closed = true;\n const pending = preflight;\n if (pending) {\n pending.cancel(new AgentError(\"SESSION_CLOSED\", \"The native session closed before submission.\"));\n await pending.stopped;\n }\n tools.stopAdmission();\n input.close();\n native.close();\n const stopping = processOwner.close();\n try { await reading; }\n finally { await stopping; }\n },\n };\n };\n}\n"]}
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"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","sourcesContent":["import { access } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { query, resolveSettings, type AccountInfo, type Options, type SDKMessage, type SDKUserMessage, type Settings, type ModelInfo } from \"@anthropic-ai/claude-agent-sdk\";\nimport { AgentError } from \"../errors.js\";\nimport type { AdapterOptions, NativeSession } from \"./types.js\";\nimport { privateClaudeConfig } from \"./claude-config.js\";\nimport { claudeTools } from \"./claude-tools.js\";\nimport { ClaudeInput } from \"./claude-input.js\";\nimport { claudeDelegationPermissions } from \"./claude-permissions.js\";\nimport { claudeSettings, verifyClaudeAccess, verifyClaudePolicy, verifyClaudeOptions } from \"./claude-auth.js\";\nimport { ClaudeSettingsUnavailable, claudeDefaultUnavailable, readClaudeAppliedSettings, verifyAppliedClaudeEffort } from \"./claude-settings.js\";\nimport { NativeApprovals } from \"./approval-lifetime.js\";\nimport { claudeApproval } from \"./claude-approvals.js\";\nimport { ClaudeProcessOwner } from \"./claude-process.js\";\nimport { claudeResultFailure } from \"./claude-result.js\";\n\ninterface ClaudeQuery extends AsyncIterable<SDKMessage> {\n accountInfo(): Promise<AccountInfo>;\n supportedModels(): Promise<ModelInfo[]>;\n interrupt(): Promise<unknown>;\n close(): void;\n getSettings?(): Promise<unknown>;\n setModel?(model?: string): Promise<void>;\n}\nexport interface ClaudeDependencies {\n query(args: {prompt: AsyncIterable<SDKUserMessage>; options: Options}): ClaudeQuery;\n executable(env: NodeJS.ProcessEnv): Promise<string>;\n managedSettings(cwd: string): Promise<Settings[]>;\n}\n\nconst dependencies: ClaudeDependencies = {\n query,\n async managedSettings(cwd) {\n const settings = await resolveSettings({cwd, settingSources:[\"user\", \"project\", \"local\"]});\n return settings.sources.filter(source => source.source === \"managed\").map(source => source.settings);\n },\n async executable(env) {\n for (const directory of (env.PATH ?? \"\").split(delimiter)) {\n const file = join(directory, \"claude\");\n try { await access(file, constants.X_OK); return file; } catch { /* Try the next PATH entry. */ }\n }\n throw new AgentError(\"HARNESS_UNAVAILABLE\", \"Install Claude Code and make claude available on PATH.\");\n },\n};\n\nfunction addCatalogEquivalentModels(expected: Set<string>, models: ModelInfo[], selected: string): void {\n expected.add(selected);\n for (const model of models) {\n if (model.value !== selected && model.resolvedModel !== selected) continue;\n expected.add(model.value);\n if (model.resolvedModel) expected.add(model.resolvedModel);\n }\n}\n\nexport const openClaude = createClaudeOpener(dependencies);\n\n/** Dependency injection is internal and replaces only the external SDK boundary in tests. */\nexport function createClaudeOpener(deps: ClaudeDependencies) {\n return async (options: AdapterOptions): Promise<NativeSession> => {\n if (options.harness.kind !== \"claudeCode\") throw new AgentError(\"INVALID_CONFIG\", \"Claude Code received configuration for a different harness.\");\n const permissionMode = options.harness.permissionMode;\n const settings = claudeSettings(options);\n const executable = await deps.executable(options.env);\n verifyClaudePolicy(await deps.managedSettings(options.cwd), settings.settings as Settings);\n const tools = claudeTools(options.agent);\n const allowedTools = [\n ...(options.harness.allowedTools ?? []),\n ...(tools.config.allowedTools ?? []),\n ...claudeDelegationPermissions(options),\n ];\n const config = await privateClaudeConfig(settings.settings as Settings);\n const input = new ClaudeInput<SDKUserMessage>();\n const processOwner = new ClaudeProcessOwner();\n let inputFailure: AgentError | undefined;\n const approvals = new NativeApprovals();\n let acceptingApprovals = false;\n const requireInput = (toolName?: string) => {\n acceptingApprovals = false;\n approvals.clear();\n tools.stopAdmission();\n const subject = toolName && /^[A-Za-z_][A-Za-z0-9_-]{0,127}$/u.test(toolName)\n ? `approval for native tool ${toolName}`\n : \"interactive input\";\n inputFailure = new AgentError(\"INPUT_REQUIRED\", `Claude Code needs ${subject}. Configure its native permissions before retrying.`);\n };\n let native: ClaudeQuery;\n try { native = deps.query({prompt: input, options: {\n pathToClaudeCodeExecutable: executable,\n spawnClaudeCodeProcess: processOwner.spawn,\n cwd: options.cwd,\n ...settings,\n ...tools.config,\n ...(allowedTools.length ? {allowedTools} : {}),\n ...(options.harness.disallowedTools !== undefined ? {disallowedTools:[...options.harness.disallowedTools]} : {}),\n ...(permissionMode !== undefined ? {permissionMode} : {}),\n ...(permissionMode === \"bypassPermissions\" ? {allowDangerouslySkipPermissions:true} : {}),\n settings: config.path,\n stderr: () => {},\n ...(options.harness.model ? {model: options.harness.model} : {}),\n systemPrompt: options.agent.instructions\n ? {type: \"preset\", preset: \"claude_code\", append: options.agent.instructions}\n : {type: \"preset\", preset: \"claude_code\"},\n settingSources: [\"user\", \"project\", \"local\"],\n canUseTool: async (toolName, toolInput, metadata) => {\n if (options.onApproval && acceptingApprovals && toolName !== \"AskUserQuestion\") {\n try {\n const answer = await claudeApproval(approvals, options.onApproval, toolName, toolInput, metadata);\n if (!acceptingApprovals || metadata.signal.aborted) return {behavior:\"deny\",message:\"The permission request is no longer pending.\"};\n return answer;\n }\n catch (error) {\n if (error instanceof AgentError && error.code === \"REQUEST_EXPIRED\") return {behavior:\"deny\",message:\"The permission request is no longer pending.\"};\n }\n }\n requireInput(toolName);\n return {behavior: \"deny\", message: inputFailure!.message, interrupt: true};\n },\n onElicitation: async () => {\n acceptingApprovals = false;\n approvals.clear();\n requireInput();\n try { await native.interrupt(); } catch { native.close(); }\n return {action: \"decline\"};\n },\n }}); }\n catch {\n const exit = processOwner.exitDescription();\n input.close();\n try { await processOwner.close(); }\n finally { await config.cleanup(); }\n throw new AgentError(\"HARNESS_UNAVAILABLE\", `Claude Code could not start${exit}.`);\n }\n const expectedModels = new Set<string>();\n let retainedModel: string | undefined;\n let startupPhase: \"account inspection\" | \"model catalog retrieval\" | \"model settings validation\" = \"account inspection\";\n try {\n const account = await native.accountInfo();\n verifyClaudeAccess(account, options.access);\n startupPhase = \"model catalog retrieval\";\n const models = await native.supportedModels();\n if (options.harness.model) {\n addCatalogEquivalentModels(expectedModels, models, options.harness.model);\n verifyClaudeOptions(models, options);\n startupPhase = \"model settings validation\";\n try {\n const applied = await readClaudeAppliedSettings(native);\n if (!expectedModels.has(applied.model)) throw new AgentError(\"INVALID_CONFIG\", \"Claude Code selected a different model than requested during startup settings validation.\");\n verifyAppliedClaudeEffort(applied.effort, options.harness.effort);\n retainedModel = applied.model;\n expectedModels.add(applied.model);\n } catch (error) {\n if (!(error instanceof ClaudeSettingsUnavailable)) throw error;\n }\n } else {\n startupPhase = \"model settings validation\";\n if (!native.getSettings || !native.setModel) throw claudeDefaultUnavailable();\n let selected;\n try { selected = await readClaudeAppliedSettings(native); }\n catch (error) { if (error instanceof ClaudeSettingsUnavailable) throw claudeDefaultUnavailable(); throw error; }\n startupPhase = \"model catalog retrieval\";\n verifyClaudeOptions(models, options, selected.model);\n startupPhase = \"model settings validation\";\n verifyAppliedClaudeEffort(selected.effort, options.harness.effort);\n startupPhase = \"model catalog retrieval\";\n addCatalogEquivalentModels(expectedModels, models, selected.model);\n startupPhase = \"model settings validation\";\n try { await native.setModel(selected.model); } catch { throw claudeDefaultUnavailable(); }\n let pinned;\n try { pinned = await readClaudeAppliedSettings(native); }\n catch (error) { if (error instanceof ClaudeSettingsUnavailable) throw claudeDefaultUnavailable(); throw error; }\n if (!expectedModels.has(pinned.model)) {\n throw new AgentError(\"INVALID_CONFIG\", \"Claude Code changed the selected native default during startup settings validation. Supply --model <model>.\");\n }\n verifyAppliedClaudeEffort(pinned.effort, options.harness.effort);\n retainedModel = pinned.model;\n startupPhase = \"model catalog retrieval\";\n addCatalogEquivalentModels(expectedModels, models, pinned.model);\n startupPhase = \"model settings validation\";\n }\n if (inputFailure) throw inputFailure;\n }\n catch (error) {\n const exit = processOwner.exitDescription();\n input.close();\n native.close();\n try { await processOwner.close(); }\n finally { await config.cleanup(); }\n if (error instanceof AgentError) throw error;\n throw new AgentError(\"HARNESS_FAILED\", `Claude Code ${startupPhase} failed${exit}.`);\n }\n let closed = false;\n let preflight: {\n cancellation: Promise<never>;\n cancel(error: AgentError): void;\n stopped: Promise<void>;\n stop(): void;\n } | undefined;\n let sessionFailure: AgentError | undefined;\n let exitObservedBeforeClose: string | undefined;\n let active: {\n resolve(text: string): void; reject(error: unknown): void;\n stopped: Promise<void>; stop(): void; interrupted: boolean;\n } | undefined;\n const reading = (async () => {\n try {\n for await (const message of native) {\n if (message.type === \"system\" && message.subtype === \"init\") {\n if (!expectedModels.has(message.model)) {\n sessionFailure = new AgentError(\"INVALID_CONFIG\", \"Claude Code selected a different model than requested during native initialization.\");\n } else if (permissionMode !== undefined && message.permissionMode !== permissionMode) {\n sessionFailure = new AgentError(\"INVALID_CONFIG\", \"Claude Code reported a different permission mode than requested.\");\n }\n if (sessionFailure) {\n tools.stopAdmission();\n native.close();\n break;\n }\n }\n if (message.type !== \"result\" || !active) continue;\n const current = active;\n acceptingApprovals = false;\n approvals.clear();\n await tools.drain();\n active = undefined;\n current.stop();\n if (inputFailure) current.reject(inputFailure);\n else if (current.interrupted) current.reject(new AgentError(\"INTERRUPTED\", \"The native turn was interrupted.\"));\n else if (message.subtype === \"success\" && !message.is_error) {\n if (Buffer.byteLength(message.result, \"utf8\") > 1024 * 1024) {\n current.reject(new AgentError(\"RESPONSE_TOO_LARGE\", \"The Claude Code response exceeds 1 MiB.\"));\n } else current.resolve(message.result);\n }\n else current.reject(claudeResultFailure(message.subtype));\n }\n } catch {\n // Native diagnostics may contain credentials; return a stable safe message.\n } finally {\n acceptingApprovals = false;\n approvals.clear();\n const explicitClose = exitObservedBeforeClose !== undefined;\n const code = explicitClose ? \"SESSION_CLOSED\" : \"HARNESS_ERROR\";\n closed = true;\n input.close();\n await tools.drain();\n const exit = explicitClose ? exitObservedBeforeClose : processOwner.exitDescription();\n active?.reject(sessionFailure ?? inputFailure ?? new AgentError(code, `The Claude Code process stopped${exit} before completing the turn.`));\n active?.stop();\n active = undefined;\n try { await processOwner.close(); }\n finally { await config.cleanup(); }\n }\n })();\n return {\n async turn(prompt) {\n if (closed) return Promise.reject(sessionFailure ?? new AgentError(\"SESSION_CLOSED\", \"The native session has closed.\"));\n if (active || preflight) return Promise.reject(new AgentError(\"SESSION_BUSY\", \"A native turn is already active.\"));\n let cancel!: (error: AgentError) => void, stop!: () => void;\n const currentPreflight = {\n cancellation: new Promise<never>((_resolve, reject) => { cancel = reject; }),\n cancel(error: AgentError) { cancel(error); },\n stopped: new Promise<void>(resolve => { stop = resolve; }),\n stop() { stop(); },\n };\n preflight = currentPreflight;\n try {\n if (native.getSettings && retainedModel) {\n let applied;\n try { applied = await Promise.race([readClaudeAppliedSettings(native), currentPreflight.cancellation]); }\n catch (error) {\n if (error instanceof ClaudeSettingsUnavailable) throw new AgentError(\"INVALID_CONFIG\", \"Claude Code could not verify the retained session model before submission.\");\n throw error;\n }\n if (!expectedModels.has(applied.model)) throw new AgentError(\"INVALID_CONFIG\", \"Claude Code changed the model during retained-session validation before submission.\");\n verifyAppliedClaudeEffort(applied.effort, options.harness.effort);\n }\n if (closed) throw sessionFailure ?? new AgentError(\"SESSION_CLOSED\", \"The native session has closed.\");\n } finally {\n if (preflight === currentPreflight) preflight = undefined;\n currentPreflight.stop();\n }\n return await new Promise((resolve, reject) => {\n inputFailure = undefined;\n tools.start();\n let stop!: () => void;\n const stopped = new Promise<void>(resolve => { stop = resolve; });\n active = {resolve, reject, stopped, stop, interrupted:false};\n acceptingApprovals = true;\n input.push({type:\"user\",message:{role:\"user\",content:prompt},parent_tool_use_id:null,uuid:randomUUID()});\n });\n },\n async steer() { throw new AgentError(\"UNSUPPORTED_DELIVERY\", \"Claude Code does not expose verified active steering.\"); },\n async interrupt() {\n const pending = preflight;\n if (pending) {\n pending.cancel(new AgentError(\"INTERRUPTED\", \"The native turn was interrupted before submission.\"));\n await pending.stopped;\n return;\n }\n const current = active;\n if (!current) return;\n current.interrupted = true;\n acceptingApprovals = false;\n approvals.clear();\n tools.stopAdmission();\n try { await native.interrupt(); }\n catch {\n current.interrupted = false;\n throw new AgentError(\"CANCEL_FAILED\", \"Claude Code did not confirm interruption.\");\n }\n await current.stopped;\n },\n async resume() { throw new AgentError(\"RECOVERY_UNSUPPORTED\", \"Claude Code cannot retry failed execution without replaying input.\"); },\n async close() {\n exitObservedBeforeClose ??= processOwner.exitDescription();\n closed = true;\n acceptingApprovals = false;\n approvals.clear();\n const pending = preflight;\n if (pending) {\n pending.cancel(new AgentError(\"SESSION_CLOSED\", \"The native session closed before submission.\"));\n await pending.stopped;\n }\n tools.stopAdmission();\n input.close();\n native.close();\n const stopping = processOwner.close();\n try { await reading; }\n finally { await stopping; }\n },\n };\n };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { ApprovalContent, NativeApprovalRequest } from "../approvals/types.js";
2
+ export interface CodexApproval {
3
+ request: NativeApprovalRequest;
4
+ response(content: ApprovalContent): unknown;
5
+ }
6
+ export declare function codexApproval(method: string | undefined, params: any, item?: unknown): CodexApproval | undefined;
@@ -0,0 +1,111 @@
1
+ import { approvalContext } from "./approval-context.js";
2
+ import { AgentError } from "../errors.js";
3
+ const titles = { accept: "Allow once", acceptForSession: "Allow for this session", decline: "Deny", cancel: "Cancel the native operation" };
4
+ const unsupported = () => new AgentError("INPUT_REQUIRED", "Codex requested permissions that cannot be represented safely.");
5
+ export function codexApproval(method, params, item) {
6
+ if (method === "item/permissions/requestApproval")
7
+ return permissionProfile(params);
8
+ if (method !== "item/commandExecution/requestApproval" && method !== "item/fileChange/requestApproval")
9
+ return undefined;
10
+ if (method === "item/commandExecution/requestApproval" && params.kind !== undefined && !["command", "writeStdin"].includes(params.kind))
11
+ throw unsupported();
12
+ const decisions = params.availableDecisions ?? ["accept", "acceptForSession", "decline", "cancel"];
13
+ if (!Array.isArray(decisions))
14
+ throw unsupported();
15
+ const supported = [];
16
+ for (const decision of decisions) {
17
+ if (typeof decision === "string" && Object.hasOwn(titles, decision))
18
+ supported.push(decision);
19
+ else if (!decision || typeof decision !== "object" || (!Object.hasOwn(decision, "acceptWithExecpolicyAmendment") && !Object.hasOwn(decision, "applyNetworkPolicyAmendment")))
20
+ throw unsupported();
21
+ }
22
+ if (!supported.length || new Set(supported).size !== supported.length)
23
+ throw unsupported();
24
+ const message = method === "item/fileChange/requestApproval" ? "Allow the requested file change?"
25
+ : params.kind === "writeStdin" ? "Allow sending input to the existing terminal?" : "Allow the requested command execution?";
26
+ return {
27
+ request: { kind: "permission", harness: "codex", message,
28
+ requestedSchema: { type: "object", properties: { decision: { type: "string", oneOf: supported.map(value => ({ const: value, title: titles[value] })) } }, required: ["decision"] },
29
+ context: { ...approvalContext(params, ["threadId", "turnId", "itemId", "approvalId", "kind", "environmentId", "reason", "command", "cwd", "commandActions", "networkApprovalContext", "additionalPermissions", "grantRoot"]), ...(item ? { item: fileContext(item) } : {}) } },
30
+ response: content => ({ decision: content.decision }),
31
+ };
32
+ }
33
+ function object(value) { return typeof value === "object" && value !== null && !Array.isArray(value); }
34
+ function only(value, keys) { return Object.keys(value).every(key => keys.includes(key)); }
35
+ function permissionProfile(params) {
36
+ const profile = structuredClone(params.permissions);
37
+ if (!object(profile) || !only(profile, ["network", "fileSystem"]))
38
+ throw unsupported();
39
+ const grants = [];
40
+ if (profile.network != null) {
41
+ if (!object(profile.network) || !only(profile.network, ["enabled"]) || ![true, false, null].includes(profile.network.enabled))
42
+ throw unsupported();
43
+ if (profile.network.enabled === true)
44
+ grants.push({ id: "network", title: "Enable network access", apply: target => { target.network = { enabled: true }; } });
45
+ }
46
+ const fs = profile.fileSystem;
47
+ if (fs != null) {
48
+ const filesystemStart = grants.length;
49
+ if (!object(fs) || !only(fs, ["read", "write", "entries", "globScanMaxDepth"]))
50
+ throw unsupported();
51
+ if (fs.globScanMaxDepth !== undefined && (!Number.isInteger(fs.globScanMaxDepth) || fs.globScanMaxDepth < 0))
52
+ throw unsupported();
53
+ const init = (target) => target.fileSystem ??= { read: null, write: null, ...(fs.globScanMaxDepth !== undefined ? { globScanMaxDepth: fs.globScanMaxDepth } : {}) };
54
+ for (const access of ["read", "write"]) {
55
+ if (fs[access] == null)
56
+ continue;
57
+ if (!Array.isArray(fs[access]) || !fs[access].every((path) => typeof path === "string"))
58
+ throw unsupported();
59
+ fs[access].forEach((path, index) => grants.push({ id: `${access}_${index}`, title: `${access === "read" ? "Read" : "Write"}: ${path}`, apply: target => { (init(target)[access] ??= []).push(path); } }));
60
+ }
61
+ if (fs.entries !== undefined) {
62
+ if (!Array.isArray(fs.entries))
63
+ throw unsupported();
64
+ fs.entries.forEach((entry, index) => {
65
+ if (!object(entry) || !only(entry, ["path", "access"]) || !["read", "write", "deny"].includes(entry.access) || !validPath(entry.path))
66
+ throw unsupported();
67
+ if (entry.access !== "deny")
68
+ grants.push({ id: `entry_${index}`, title: `${entry.access === "read" ? "Read" : "Write"}: ${JSON.stringify(entry.path)}`, apply: target => { (init(target).entries ??= []).push(entry); } });
69
+ });
70
+ if (grants.length > filesystemStart) {
71
+ // Overlapping read/write/deny entries form one native policy; do not infer precedence.
72
+ grants.splice(filesystemStart);
73
+ grants.push({ id: "filesystem", title: "Requested filesystem access with its native restrictions", apply: target => { target.fileSystem = structuredClone(fs); } });
74
+ }
75
+ }
76
+ }
77
+ if (!grants.length)
78
+ throw unsupported();
79
+ return {
80
+ request: { kind: "permission", harness: "codex", message: "Select the additional permissions to grant and their duration. An empty selection denies all requested grants.",
81
+ requestedSchema: { type: "object", properties: { grants: { type: "array", items: { type: "string", anyOf: grants.map(grant => ({ const: grant.id, title: grant.title })) }, uniqueItems: true }, scope: { type: "string", oneOf: [{ const: "turn", title: "This turn" }, { const: "session", title: "This session" }] } }, required: ["grants", "scope"] }, context: approvalContext(params, ["threadId", "turnId", "itemId", "environmentId", "cwd", "reason", "permissions"]) },
82
+ response: content => {
83
+ const permissions = {};
84
+ for (const id of content.grants)
85
+ grants.find(grant => grant.id === id).apply(permissions);
86
+ if (permissions.fileSystem && profile.network?.enabled === false)
87
+ permissions.network = { enabled: false };
88
+ return { permissions, scope: content.scope };
89
+ },
90
+ };
91
+ }
92
+ function validPath(path) {
93
+ if (!object(path))
94
+ return false;
95
+ if (path.type === "path")
96
+ return only(path, ["type", "path"]) && typeof path.path === "string";
97
+ if (path.type === "glob_pattern")
98
+ return only(path, ["type", "pattern"]) && typeof path.pattern === "string";
99
+ if (path.type !== "special" || !only(path, ["type", "value"]) || !object(path.value))
100
+ return false;
101
+ const value = path.value;
102
+ if (["root", "minimal", "tmpdir", "slash_tmp"].includes(value.kind))
103
+ return only(value, ["kind"]);
104
+ if (value.kind === "project_roots")
105
+ return only(value, ["kind", "subpath"]) && (value.subpath === null || typeof value.subpath === "string");
106
+ return value.kind === "unknown" && only(value, ["kind", "path", "subpath"]) && typeof value.path === "string" && (value.subpath === null || typeof value.subpath === "string");
107
+ }
108
+ function fileContext(item) {
109
+ return { ...approvalContext(item, ["id", "type", "status"]), ...(Array.isArray(item.changes) ? { changes: item.changes.map((change) => ({ ...approvalContext(change, ["path", "diff"]), ...(object(change.kind) ? { kind: approvalContext(change.kind, ["type", "move_path"]) } : {}) })) } : {}) };
110
+ }
111
+ //# sourceMappingURL=codex-approvals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-approvals.js","sourceRoot":"","sources":["../../src/adapters/codex-approvals.ts"],"names":[],"mappings":"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","sourcesContent":["import { approvalContext } from \"./approval-context.js\";\nimport { AgentError } from \"../errors.js\";\nimport type { ApprovalContent, NativeApprovalRequest } from \"../approvals/types.js\";\n\nexport interface CodexApproval {\n request: NativeApprovalRequest;\n response(content: ApprovalContent): unknown;\n}\nconst titles: Record<string,string> = {accept:\"Allow once\",acceptForSession:\"Allow for this session\",decline:\"Deny\",cancel:\"Cancel the native operation\"};\nconst unsupported = () => new AgentError(\"INPUT_REQUIRED\", \"Codex requested permissions that cannot be represented safely.\");\nexport function codexApproval(method: string | undefined, params: any, item?: unknown): CodexApproval | undefined {\n if (method === \"item/permissions/requestApproval\") return permissionProfile(params);\n if (method !== \"item/commandExecution/requestApproval\" && method !== \"item/fileChange/requestApproval\") return undefined;\n if (method === \"item/commandExecution/requestApproval\" && params.kind !== undefined && ![\"command\",\"writeStdin\"].includes(params.kind)) throw unsupported();\n const decisions: unknown = params.availableDecisions ?? [\"accept\",\"acceptForSession\",\"decline\",\"cancel\"];\n if (!Array.isArray(decisions)) throw unsupported();\n const supported: string[] = [];\n for (const decision of decisions) {\n if (typeof decision === \"string\" && Object.hasOwn(titles,decision)) supported.push(decision);\n else if (!decision || typeof decision !== \"object\" || (!Object.hasOwn(decision,\"acceptWithExecpolicyAmendment\") && !Object.hasOwn(decision,\"applyNetworkPolicyAmendment\"))) throw unsupported();\n }\n if (!supported.length || new Set(supported).size !== supported.length) throw unsupported();\n const message = method === \"item/fileChange/requestApproval\" ? \"Allow the requested file change?\"\n : params.kind === \"writeStdin\" ? \"Allow sending input to the existing terminal?\" : \"Allow the requested command execution?\";\n return {\n request: {kind:\"permission\",harness:\"codex\",message,\n requestedSchema:{type:\"object\",properties:{decision:{type:\"string\",oneOf:supported.map(value=>({const:value,title:titles[value]!}))}},required:[\"decision\"]},\n context:{...approvalContext(params,[\"threadId\",\"turnId\",\"itemId\",\"approvalId\",\"kind\",\"environmentId\",\"reason\",\"command\",\"cwd\",\"commandActions\",\"networkApprovalContext\",\"additionalPermissions\",\"grantRoot\"]),...(item ? {item:fileContext(item)} : {})}},\n response: content => ({decision:content.decision}),\n };\n}\n\nfunction object(value: unknown): value is Record<string,any> { return typeof value === \"object\" && value !== null && !Array.isArray(value); }\nfunction only(value: Record<string,any>, keys: string[]): boolean {return Object.keys(value).every(key=>keys.includes(key));}\nfunction permissionProfile(params: any): CodexApproval {\n const profile = structuredClone(params.permissions);\n if (!object(profile) || !only(profile,[\"network\",\"fileSystem\"])) throw unsupported();\n const grants: {id:string;title:string;apply:(target:any)=>void}[]=[];\n if (profile.network != null) {\n if (!object(profile.network) || !only(profile.network,[\"enabled\"]) || ![true,false,null].includes(profile.network.enabled)) throw unsupported();\n if (profile.network.enabled === true) grants.push({id:\"network\",title:\"Enable network access\",apply:target=>{target.network={enabled:true};}});\n }\n const fs = profile.fileSystem;\n if (fs != null) {\n const filesystemStart = grants.length;\n if (!object(fs) || !only(fs,[\"read\",\"write\",\"entries\",\"globScanMaxDepth\"])) throw unsupported();\n if (fs.globScanMaxDepth !== undefined && (!Number.isInteger(fs.globScanMaxDepth) || fs.globScanMaxDepth < 0)) throw unsupported();\n const init = (target:any) => target.fileSystem ??= {read:null,write:null,...(fs.globScanMaxDepth !== undefined ? {globScanMaxDepth:fs.globScanMaxDepth} : {})};\n for (const access of [\"read\",\"write\"]) {\n if (fs[access] == null) continue;\n if (!Array.isArray(fs[access]) || !fs[access].every((path:unknown)=>typeof path === \"string\")) throw unsupported();\n fs[access].forEach((path:string,index:number)=>grants.push({id:`${access}_${index}`,title:`${access === \"read\" ? \"Read\" : \"Write\"}: ${path}`,apply:target=>{(init(target)[access] ??= []).push(path);}}));\n }\n if (fs.entries !== undefined) {\n if (!Array.isArray(fs.entries)) throw unsupported();\n fs.entries.forEach((entry:any,index:number)=>{\n if (!object(entry) || !only(entry,[\"path\",\"access\"]) || ![\"read\",\"write\",\"deny\"].includes(entry.access) || !validPath(entry.path)) throw unsupported();\n if (entry.access !== \"deny\") grants.push({id:`entry_${index}`,title:`${entry.access === \"read\" ? \"Read\" : \"Write\"}: ${JSON.stringify(entry.path)}`,apply:target=>{(init(target).entries ??= []).push(entry);}});\n });\n if (grants.length > filesystemStart) {\n // Overlapping read/write/deny entries form one native policy; do not infer precedence.\n grants.splice(filesystemStart);\n grants.push({id:\"filesystem\",title:\"Requested filesystem access with its native restrictions\",apply:target=>{target.fileSystem=structuredClone(fs);}});\n }\n }\n }\n if (!grants.length) throw unsupported();\n return {\n request:{kind:\"permission\",harness:\"codex\",message:\"Select the additional permissions to grant and their duration. An empty selection denies all requested grants.\",\n requestedSchema:{type:\"object\",properties:{grants:{type:\"array\",items:{type:\"string\",anyOf:grants.map(grant=>({const:grant.id,title:grant.title}))},uniqueItems:true},scope:{type:\"string\",oneOf:[{const:\"turn\",title:\"This turn\"},{const:\"session\",title:\"This session\"}]}},required:[\"grants\",\"scope\"]},context:approvalContext(params,[\"threadId\",\"turnId\",\"itemId\",\"environmentId\",\"cwd\",\"reason\",\"permissions\"])},\n response: content=>{\n const permissions: any={};\n for (const id of content.grants as string[]) grants.find(grant=>grant.id===id)!.apply(permissions);\n if (permissions.fileSystem && profile.network?.enabled === false) permissions.network={enabled:false};\n return {permissions,scope:content.scope};\n },\n };\n}\nfunction validPath(path: any): boolean {\n if (!object(path)) return false;\n if (path.type === \"path\") return only(path,[\"type\",\"path\"]) && typeof path.path === \"string\";\n if (path.type === \"glob_pattern\") return only(path,[\"type\",\"pattern\"]) && typeof path.pattern === \"string\";\n if (path.type !== \"special\" || !only(path,[\"type\",\"value\"]) || !object(path.value)) return false;\n const value=path.value;\n if ([\"root\",\"minimal\",\"tmpdir\",\"slash_tmp\"].includes(value.kind)) return only(value,[\"kind\"]);\n if (value.kind === \"project_roots\") return only(value,[\"kind\",\"subpath\"]) && (value.subpath === null || typeof value.subpath === \"string\");\n return value.kind === \"unknown\" && only(value,[\"kind\",\"path\",\"subpath\"]) && typeof value.path === \"string\" && (value.subpath === null || typeof value.subpath === \"string\");\n}\n\nfunction fileContext(item: any): Record<string, unknown> {\n return {...approvalContext(item,[\"id\",\"type\",\"status\"]),...(Array.isArray(item.changes) ? {changes:item.changes.map((change: any)=>({...approvalContext(change,[\"path\",\"diff\"]),...(object(change.kind)?{kind:approvalContext(change.kind,[\"type\",\"move_path\"])}:{})}))} : {})};\n}\n"]}
@@ -2,6 +2,8 @@ import { AgentError } from "../errors.js";
2
2
  import { executeTool, toolJsonSchema } from "../sdk/tools.js";
3
3
  import { NativeRpc } from "./rpc.js";
4
4
  import { codexEnvironment, codexConfiguration, validateCodexModel } from "./codex-config.js";
5
+ import { NativeApprovals } from "./approval-lifetime.js";
6
+ import { codexApproval } from "./codex-approvals.js";
5
7
  import { codexInputRequired } from "./codex-input.js";
6
8
  import { codexPermissionSettings, verifyCodexPermissionSettings } from "./codex-permissions.js";
7
9
  export async function openCodex(options) {
@@ -79,9 +81,19 @@ class CodexSession {
79
81
  const turnId = p.turnId ?? p.turn?.id;
80
82
  if (turnId && turnId !== current.id)
81
83
  return;
84
+ if (message.method === "serverRequest/resolved") {
85
+ current.withdrawnApprovals.add(p.requestId);
86
+ current.approvals.withdraw(p.requestId);
87
+ return;
88
+ }
89
+ if (message.method === "item/started" && p.item?.type === "fileChange")
90
+ current.items.set(p.item.id, p.item);
82
91
  if (message.method === "item/tool/call" && message.id !== undefined) {
83
92
  if (!current.acceptingTools) {
84
- this.rpc.send({ id: message.id, result: { success: false, contentItems: [{ type: "inputText", text: "The task is not accepting tool calls." }] } });
93
+ try {
94
+ this.rpc.send({ id: message.id, result: { success: false, contentItems: [{ type: "inputText", text: "The task is not accepting tool calls." }] } });
95
+ }
96
+ catch { /* A closing native turn no longer accepts its rejected tool-call result. */ }
85
97
  return;
86
98
  }
87
99
  const call = this.toolCall(message.id, p);
@@ -90,6 +102,22 @@ class CodexSession {
90
102
  return;
91
103
  }
92
104
  if (message.id !== undefined) {
105
+ if (this.options.onApproval && current.acceptingTools) {
106
+ try {
107
+ const approval = codexApproval(message.method, p, current.items.get(p.itemId));
108
+ if (approval) {
109
+ void current.approvals.request(message.id, approval.request, this.options.onApproval).then(content => {
110
+ if (this.active === current && !current.terminal && current.acceptingTools && !current.withdrawnApprovals.has(message.id))
111
+ this.rpc.send({ id: message.id, result: approval.response(content) });
112
+ }).catch(error => {
113
+ if (!(error instanceof AgentError && error.code === "REQUEST_EXPIRED"))
114
+ this.stopForInput(message.method);
115
+ });
116
+ return;
117
+ }
118
+ }
119
+ catch { /* Unsupported native requests use the explicit input failure path. */ }
120
+ }
93
121
  this.stopForInput(message.method);
94
122
  return;
95
123
  }
@@ -112,6 +140,7 @@ class CodexSession {
112
140
  if (active.terminal)
113
141
  return;
114
142
  active.terminal = true;
143
+ active.approvals.clear();
115
144
  active.acceptingTools = false;
116
145
  await Promise.allSettled([...active.tools]);
117
146
  if (this.active === active)
@@ -145,6 +174,7 @@ class CodexSession {
145
174
  if (!active || active.failure)
146
175
  return;
147
176
  active.acceptingTools = false;
177
+ active.approvals.clear();
148
178
  active.failure = codexInputRequired(method);
149
179
  void (async () => {
150
180
  try {
@@ -181,7 +211,7 @@ class CodexSession {
181
211
  throw new AgentError("SESSION_BUSY", "Codex already has an active turn.");
182
212
  let resolve, reject;
183
213
  const completion = new Promise((a, b) => { resolve = a; reject = b; });
184
- const active = { messages: new Map(), tools: new Set(), acceptingTools: true, resolve, reject, completion };
214
+ const active = { messages: new Map(), tools: new Set(), approvals: new NativeApprovals(), items: new Map(), withdrawnApprovals: new Set(), acceptingTools: true, resolve, reject, completion };
185
215
  this.active = active;
186
216
  void completion.catch(() => { });
187
217
  try {
@@ -211,6 +241,7 @@ class CodexSession {
211
241
  if (!active)
212
242
  return;
213
243
  active.acceptingTools = false;
244
+ active.approvals.clear();
214
245
  await active.started;
215
246
  if (this.active !== active)
216
247
  return;
@@ -227,8 +258,10 @@ class CodexSession {
227
258
  async resume() { throw new AgentError("RECOVERY_UNSUPPORTED", "Codex does not expose retry of a failed turn without replay."); }
228
259
  async close() {
229
260
  const active = this.active;
230
- if (active)
261
+ if (active) {
231
262
  active.acceptingTools = false;
263
+ active.approvals.clear();
264
+ }
232
265
  await this.rpc.close();
233
266
  if (active)
234
267
  await Promise.allSettled([...active.tools]);