@astrosheep/keiyaku 2.9.3 → 2.9.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 (282) hide show
  1. package/build/.tsbuildinfo +1 -1
  2. package/build/agents/call-terms.js +14 -94
  3. package/build/agents/harness/activity-values.js +16 -0
  4. package/build/agents/harness/event-persistence.js +218 -0
  5. package/build/agents/harness/execution-handle.js +26 -222
  6. package/build/agents/harness/index.js +3 -1
  7. package/build/agents/harness/outcome.js +68 -5
  8. package/build/agents/harness/projection.js +179 -124
  9. package/build/agents/harness/provider-adapter.js +58 -0
  10. package/build/agents/harness/router.js +11 -187
  11. package/build/agents/harness/runtime.js +17 -4
  12. package/build/agents/harness/session.js +15 -0
  13. package/build/agents/launch-snapshot/model.js +15 -236
  14. package/build/agents/launch-snapshot/parse-helpers.js +114 -0
  15. package/build/agents/launch-snapshot/resolve.js +17 -43
  16. package/build/agents/opencode-sdk.js +45 -12
  17. package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
  18. package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
  19. package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
  20. package/build/agents/providers/codex-app-server/adapter.js +82 -53
  21. package/build/agents/providers/codex-app-server/events.js +90 -11
  22. package/build/agents/providers/codex-app-server/identity.js +1 -0
  23. package/build/agents/providers/codex-app-server/policy.js +29 -0
  24. package/build/agents/providers/codex-app-server/registration.js +248 -0
  25. package/build/agents/providers/codex-app-server/session-schema.js +6 -0
  26. package/build/agents/providers/codex-app-server/session.js +23 -17
  27. package/build/agents/providers/codex-app-server/terms.js +1 -0
  28. package/build/agents/providers/opencode-sdk/adapter.js +94 -50
  29. package/build/agents/providers/opencode-sdk/events.js +8 -4
  30. package/build/agents/providers/opencode-sdk/registration.js +135 -0
  31. package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
  32. package/build/agents/providers/opencode-sdk/session.js +21 -14
  33. package/build/agents/providers/opencode-sdk/terms.js +1 -0
  34. package/build/agents/providers/pi/adapter.js +36 -30
  35. package/build/agents/providers/pi/events.js +4 -3
  36. package/build/agents/providers/pi/registration.js +145 -0
  37. package/build/agents/providers/pi/session-schema.js +6 -0
  38. package/build/agents/providers/pi/terms.js +1 -0
  39. package/build/agents/providers/registration.js +7 -0
  40. package/build/agents/providers/registry.js +76 -0
  41. package/build/agents/selector.js +2 -29
  42. package/build/agents/types.js +10 -0
  43. package/build/artifact-directories.js +22 -0
  44. package/build/cli/commands/akuma/akuma/handler.js +1 -1
  45. package/build/cli/commands/akuma/akuma/meta.js +1 -1
  46. package/build/cli/commands/akuma/list/meta-ls.js +1 -1
  47. package/build/cli/commands/akuma/view/handler.js +5 -4
  48. package/build/cli/commands/akuma/view/meta.js +1 -1
  49. package/build/cli/commands/akuma.js +6 -0
  50. package/build/cli/commands/contract/amend/handler.js +8 -2
  51. package/build/cli/commands/contract/amend/meta.js +4 -4
  52. package/build/cli/commands/contract/arc/handler.js +8 -2
  53. package/build/cli/commands/contract/arc/meta.js +4 -4
  54. package/build/cli/commands/contract/audit/handler.js +16 -0
  55. package/build/cli/commands/contract/audit/meta.js +16 -0
  56. package/build/cli/commands/contract/bind/handler.js +4 -3
  57. package/build/cli/commands/contract/bind/meta.js +44 -8
  58. package/build/cli/commands/contract/catalog.js +2 -0
  59. package/build/cli/commands/contract/forfeit/handler.js +4 -4
  60. package/build/cli/commands/contract/forfeit/meta.js +1 -1
  61. package/build/cli/commands/contract/log/handler.js +3 -3
  62. package/build/cli/commands/contract/log/meta.js +1 -1
  63. package/build/cli/commands/contract/petition/handler.js +5 -8
  64. package/build/cli/commands/contract/petition/meta.js +6 -6
  65. package/build/cli/commands/contract/renew/handler.js +20 -6
  66. package/build/cli/commands/contract/renew/meta.js +6 -5
  67. package/build/cli/commands/metadata.js +59 -0
  68. package/build/cli/commands/projection/call/handler.js +6 -5
  69. package/build/cli/commands/projection/call/meta.js +4 -1
  70. package/build/cli/commands/projection/kill/handler.js +16 -32
  71. package/build/cli/commands/projection/kill/meta.js +1 -1
  72. package/build/cli/commands/projection/revive/meta.js +4 -1
  73. package/build/cli/commands/projection/shared.js +28 -0
  74. package/build/cli/commands/projection/status/handler.js +1 -1
  75. package/build/cli/commands/projection/status/meta.js +1 -1
  76. package/build/cli/commands/projection/tell/handler.js +14 -30
  77. package/build/cli/commands/projection/tell/meta.js +4 -1
  78. package/build/cli/commands/projection/wait/handler.js +45 -22
  79. package/build/cli/commands/projection/wait/meta.js +8 -3
  80. package/build/cli/commands/registry.js +2 -54
  81. package/build/cli/commands/shared.js +10 -7
  82. package/build/cli/commands/skills/install/handler.js +2 -5
  83. package/build/cli/commands/skills/install/meta.js +1 -1
  84. package/build/cli/commands/skills/skills/handler.js +1 -1
  85. package/build/cli/commands/skills/skills/meta.js +1 -1
  86. package/build/cli/commands/system/completion/meta.js +1 -1
  87. package/build/cli/commands/system/dump-env/meta.js +1 -1
  88. package/build/cli/commands/system/guide/meta.js +1 -1
  89. package/build/cli/commands/task/add/handler.js +7 -15
  90. package/build/cli/commands/task/add/meta.js +4 -1
  91. package/build/cli/commands/task/catalog.js +2 -2
  92. package/build/cli/commands/task/doctor/meta.js +1 -1
  93. package/build/cli/commands/task/done/handler.js +4 -8
  94. package/build/cli/commands/task/done/meta.js +1 -1
  95. package/build/cli/commands/task/drop/handler.js +3 -6
  96. package/build/cli/commands/task/drop/meta.js +1 -1
  97. package/build/cli/commands/task/ls/handler.js +12 -8
  98. package/build/cli/commands/task/ls/meta.js +3 -3
  99. package/build/cli/commands/task/shared.js +14 -4
  100. package/build/cli/commands/task/{view → show}/handler.js +7 -8
  101. package/build/cli/commands/task/show/meta.js +8 -0
  102. package/build/cli/commands/task/start/handler.js +3 -6
  103. package/build/cli/commands/task/start/meta.js +1 -1
  104. package/build/cli/commands/task/stop/handler.js +4 -8
  105. package/build/cli/commands/task/stop/meta.js +1 -1
  106. package/build/cli/commands/task/task/handler.js +1 -1
  107. package/build/cli/commands/task/task/meta.js +1 -1
  108. package/build/cli/commands/task/update/handler.js +6 -11
  109. package/build/cli/commands/task/update/meta.js +4 -1
  110. package/build/cli/completion.js +1 -1
  111. package/build/cli/flags.js +37 -6
  112. package/build/cli/help.js +7 -14
  113. package/build/cli/index.js +112 -154
  114. package/build/cli/missing-subcommand.js +7 -0
  115. package/build/cli/output-stream-error-policy.js +19 -5
  116. package/build/cli/parse-flags.js +33 -7
  117. package/build/cli/parse-metadata.js +3 -9
  118. package/build/cli/parse-selectors.js +2 -1
  119. package/build/cli/parse.js +35 -5
  120. package/build/cli/projection-address.js +12 -12
  121. package/build/cli/render/address.js +41 -37
  122. package/build/cli/render/arc.js +24 -12
  123. package/build/cli/render/audit.js +121 -0
  124. package/build/cli/render/call.js +11 -5
  125. package/build/cli/render/errors.js +36 -1
  126. package/build/cli/render/format.js +4 -0
  127. package/build/cli/render/kanshi.js +6 -12
  128. package/build/cli/render/kill.js +9 -0
  129. package/build/cli/render/misc.js +58 -13
  130. package/build/cli/render/petition.js +20 -15
  131. package/build/cli/render/projection-activity.js +15 -6
  132. package/build/cli/render/shared.js +60 -21
  133. package/build/cli/render/skills.js +10 -0
  134. package/build/cli/render/status.js +56 -23
  135. package/build/cli/render/success-response.js +78 -0
  136. package/build/cli/render/task.js +66 -57
  137. package/build/cli/render/tell.js +5 -0
  138. package/build/cli/render/terminal-failure.js +63 -0
  139. package/build/cli/render/types.js +1 -0
  140. package/build/cli/render/wait.js +68 -38
  141. package/build/cli/types.js +1 -1
  142. package/build/config/akuma-loader.js +0 -5
  143. package/build/config/env-keys.js +3 -1
  144. package/build/config/env.js +3 -0
  145. package/build/config/provider-policy-ownership.js +3 -32
  146. package/build/config/settings/disease.js +8 -1
  147. package/build/config/settings/loader.js +11 -3
  148. package/build/config/settings/provider-instance-fields.js +51 -0
  149. package/build/config/settings/schema.js +6 -176
  150. package/build/core/addressing.js +66 -16
  151. package/build/core/amend.js +61 -18
  152. package/build/core/arc.js +33 -73
  153. package/build/core/audit.js +650 -0
  154. package/build/core/bind.js +82 -35
  155. package/build/core/call/call.js +15 -9
  156. package/build/core/call/context.js +6 -51
  157. package/build/core/call/execution.js +22 -22
  158. package/build/core/call/prompt.js +14 -1
  159. package/build/core/command-markdown.js +45 -0
  160. package/build/core/context.js +13 -7
  161. package/build/core/contract-view.js +22 -6
  162. package/build/core/draft.js +139 -19
  163. package/build/core/entry.js +3 -4
  164. package/build/core/forfeit.js +5 -2
  165. package/build/core/hints.js +1 -75
  166. package/build/core/identifier-slug.js +66 -0
  167. package/build/core/ids.js +25 -11
  168. package/build/core/ledger.js +20 -68
  169. package/build/core/markdown/lex.js +2 -1
  170. package/build/core/markdown/parser.js +0 -68
  171. package/build/core/markdown/render.js +68 -0
  172. package/build/core/markdown/sections.js +2 -1
  173. package/build/core/outcome-base.js +4 -0
  174. package/build/core/projection/generation/database.js +41 -52
  175. package/build/core/projection/generation/model.js +63 -2
  176. package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
  177. package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +36 -53
  178. package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
  179. package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +9 -7
  180. package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
  181. package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +19 -3
  182. package/build/core/projection/generation/store.js +3 -3
  183. package/build/core/projection/generation/transitions.js +19 -3
  184. package/build/core/projection/index.js +27 -0
  185. package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
  186. package/build/core/{projection-alias.js → projection/projection-alias.js} +13 -13
  187. package/build/core/projection/projection-coordinate.js +61 -0
  188. package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
  189. package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +37 -78
  190. package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
  191. package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
  192. package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +16 -2
  193. package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
  194. package/build/core/{projection-status.js → projection/projection-status.js} +163 -45
  195. package/build/core/projection/projection-terminal-failure.js +106 -0
  196. package/build/core/projection/projection-wait.js +275 -0
  197. package/build/core/projection/projection-wake.js +227 -0
  198. package/build/core/provider-loader-ports.js +4 -0
  199. package/build/core/ref-log.js +65 -40
  200. package/build/core/registry.js +63 -10
  201. package/build/core/renew-session.js +128 -0
  202. package/build/core/renew.js +448 -102
  203. package/build/core/scope.js +272 -68
  204. package/build/core/seal.js +165 -40
  205. package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +8 -8
  206. package/build/core/{claim.js → settlement/claim.js} +32 -8
  207. package/build/core/settlement/index.js +19 -0
  208. package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +24 -49
  209. package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
  210. package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
  211. package/build/core/settlement/petition-io.js +1 -0
  212. package/build/core/{petition-preview.js → settlement/petition-preview.js} +2 -2
  213. package/build/core/{petition.js → settlement/petition.js} +21 -12
  214. package/build/core/settlement/queue-read-model.js +143 -0
  215. package/build/core/settlement/queue-seat-allocation.js +156 -0
  216. package/build/core/settlement/queue.js +6 -0
  217. package/build/core/settlement/settlement.js +288 -0
  218. package/build/core/{verdict.js → settlement/verdict.js} +9 -37
  219. package/build/core/settlement/verification.js +59 -0
  220. package/build/core/status/board.js +62 -41
  221. package/build/core/status/ledger-batch.js +158 -0
  222. package/build/core/status/reconciliation.js +10 -4
  223. package/build/core/stored-agent-event.js +6 -2
  224. package/build/core/task/board.js +41 -4
  225. package/build/core/task/commands.js +45 -28
  226. package/build/core/task/document.js +5 -0
  227. package/build/core/task/index.js +12 -0
  228. package/build/core/task/model.js +8 -1
  229. package/build/core/task/query.js +172 -0
  230. package/build/core/task/settlement-git.js +265 -74
  231. package/build/core/task/settlement-policy.js +67 -29
  232. package/build/core/task/source-board.js +1 -0
  233. package/build/core/task/task-contract.js +444 -0
  234. package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
  235. package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
  236. package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
  237. package/build/core/{task-git-store.js → task/task-git-store.js} +90 -19
  238. package/build/core/task/task-repository.js +1 -0
  239. package/build/core/{task-store-repository.js → task/task-store-repository.js} +6 -4
  240. package/build/core/task/task-store.js +1 -0
  241. package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
  242. package/build/core/task/task.js +7 -0
  243. package/build/core/task/tree.js +37 -0
  244. package/build/core/task/validation.js +5 -2
  245. package/build/core/transcripts.js +15 -3
  246. package/build/core/worktree-path.js +43 -28
  247. package/build/flow-error.js +83 -39
  248. package/build/fs/path-coordinate.js +16 -0
  249. package/build/generated/version.js +3 -2
  250. package/build/git/branches.js +2 -1
  251. package/build/git/core.js +106 -2
  252. package/build/git/diff/parsers.js +23 -13
  253. package/build/git/diff/structured.js +127 -0
  254. package/build/git/path-coordinate.js +17 -0
  255. package/build/git/refs.js +57 -0
  256. package/build/git/streaming-batch.js +301 -0
  257. package/build/git/worktree.js +65 -0
  258. package/build/index.js +9 -9
  259. package/build/keiyaku.js +2 -36
  260. package/build/telemetry/logger.js +4 -2
  261. package/package.json +4 -10
  262. package/skills/keiyaku/SKILL.md +5 -4
  263. package/skills/keiyaku-akuma/SKILL.md +25 -11
  264. package/skills/keiyaku-task/SKILL.md +17 -8
  265. package/skills/keiyaku-workflow/SKILL.md +58 -9
  266. package/build/agents/providers/codex-sdk.js +0 -329
  267. package/build/cli/commands/task/view/meta.js +0 -8
  268. package/build/core/command-io.js +0 -174
  269. package/build/core/path-coordinate.js +0 -27
  270. package/build/core/petition-claim.js +0 -117
  271. package/build/core/petition-run.js +0 -83
  272. package/build/core/projection-coordinate.js +0 -63
  273. package/build/core/projection-wait.js +0 -165
  274. package/build/core/projection-wake.js +0 -136
  275. package/build/core/queue.js +0 -343
  276. package/build/core/task-contract.js +0 -237
  277. package/build/core/task.js +0 -4
  278. /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
  279. /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
  280. /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
  281. /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
  282. /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
@@ -1,6 +1,4 @@
1
- import * as path from "node:path";
2
- import { nativePolicyOwnership } from "../../config/provider-policy-ownership.js";
3
- import { buildCodexAppServerWorkspaceWriteSandboxPolicy, configOwnsApprovalPolicy, configOwnsSandboxPolicy, } from "../providers/codex-app-server/adapter.js";
1
+ import { getProviderRegistration } from "../providers/registry.js";
4
2
  import { assertEffortAllowed, assertEffortRequiresModel, parseResolvedAkumaLaunchSnapshot, } from "./model.js";
5
3
  export function resolveAkumaLaunchSnapshot(selected, input) {
6
4
  const model = input.model ?? selected.profile.model;
@@ -28,45 +26,21 @@ export function resolveAkumaLaunchSnapshot(selected, input) {
28
26
  policy,
29
27
  };
30
28
  const instance = selected.profile.providerInstance;
31
- const common = { name: selected.profile.provider, source: selected.profile.providerSource, kind: instance.kind };
32
- let provider;
33
- switch (instance.kind) {
34
- case "codex-sdk": {
35
- const threadOptions = { ...(instance.threadOptions ?? {}) };
36
- const ownership = nativePolicyOwnership(selected.profile.provider, instance);
37
- if (ownership.access.length === 0) {
38
- threadOptions.sandboxMode = selected.profile.access === "read" ? "read-only" : selected.profile.access === "auto" ? "danger-full-access" : "workspace-write";
39
- }
40
- if (ownership.network.length === 0)
41
- threadOptions.networkAccessEnabled = selected.profile.network === "enabled";
42
- if (ownership.webSearch.length === 0)
43
- threadOptions.webSearchMode = selected.profile.webSearch ?? "disabled";
44
- if (model !== undefined)
45
- threadOptions.model = model;
46
- if (effort !== undefined)
47
- threadOptions.modelReasoningEffort = effort;
48
- threadOptions.workingDirectory = input.executionCwd;
49
- threadOptions.skipGitRepoCheck = true;
50
- provider = { ...common, ...(instance.executable !== undefined ? { executable: instance.executable } : {}), ...(instance.profile !== undefined ? { profile: instance.profile } : {}), ...(instance.config !== undefined ? { config: instance.config } : {}), threadOptions };
51
- break;
52
- }
53
- case "codex-app-server": {
54
- const roots = [path.resolve(input.executionCwd), ...(instance.writableRoots ?? []).map((root) => path.resolve(input.projectRoot, root))];
55
- const writableRoots = [...new Set(roots)];
56
- provider = { ...common, ...(instance.executable !== undefined ? { executable: instance.executable } : {}), ...(instance.profile !== undefined ? { profile: instance.profile } : {}), ...(instance.config !== undefined ? { config: instance.config } : {}), ...(model !== undefined ? { model } : {}), ...(effort !== undefined ? { effort } : {}), ...(!configOwnsSandboxPolicy(instance.config) ? { sandboxPolicy: buildCodexAppServerWorkspaceWriteSandboxPolicy({ writableRoots, networkAccess: selected.profile.network === "enabled" }) } : {}), ...(!configOwnsApprovalPolicy(instance.config) ? { approvalPolicy: "never" } : {}), ...(instance.env !== undefined ? { env: instance.env } : {}) };
57
- break;
58
- }
59
- case "claude-agent-sdk": {
60
- const permissionMode = selected.profile.access === "read" ? "plan" : selected.profile.access === "write" ? "acceptEdits" : selected.profile.access === "auto" ? "bypassPermissions" : "default";
61
- provider = { ...common, ...(instance.executable !== undefined ? { executable: instance.executable } : {}), ...(model !== undefined ? { model } : {}), ...(effort !== undefined ? { effort } : {}), ...(instance.settingSources !== undefined ? { settingSources: instance.settingSources } : {}), permissionMode, ...(permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {}), ...(selected.profile.webSearch === "disabled" ? { disallowedTools: ["WebSearch"] } : {}), ...(instance.env !== undefined ? { env: instance.env } : {}) };
62
- break;
63
- }
64
- case "opencode-sdk":
65
- provider = { ...common, ...(instance.executable !== undefined ? { executable: instance.executable } : {}), ...(model !== undefined ? { model } : {}), ...(effort !== undefined ? { effort } : {}), ...(instance.env !== undefined ? { env: instance.env } : {}) };
66
- break;
67
- case "pi":
68
- provider = { ...common, ...(model !== undefined ? { model } : {}), ...(effort !== undefined ? { thinkingLevel: effort } : {}), ...(instance.env !== undefined ? { env: instance.env } : {}) };
69
- break;
70
- }
29
+ const common = {
30
+ name: selected.profile.provider,
31
+ source: selected.profile.providerSource,
32
+ };
33
+ const registration = getProviderRegistration(instance.kind);
34
+ const provider = registration.resolveLaunchProvider({
35
+ common,
36
+ instance,
37
+ model,
38
+ effort,
39
+ executionCwd: input.executionCwd,
40
+ projectRoot: input.projectRoot,
41
+ access: selected.profile.access,
42
+ network: selected.profile.network,
43
+ webSearch: selected.profile.webSearch,
44
+ });
71
45
  return parseResolvedAkumaLaunchSnapshot({ version: 1, akuma, provider });
72
46
  }
@@ -7,6 +7,7 @@ const DEFAULT_HOSTNAME = "127.0.0.1";
7
7
  const DEFAULT_STARTUP_TIMEOUT_MS = 10_000;
8
8
  const SERVER_READY_POLL_INTERVAL_MS = 100;
9
9
  const SERVER_SHUTDOWN_FORCE_KILL_MS = 1000;
10
+ const SERVER_SHUTDOWN_HARD_TIMEOUT_MS = 2000;
10
11
  const OPENCODE_SERVE_SUBCOMMAND = "serve";
11
12
  const OPENCODE_HOSTNAME_FLAG = "--hostname";
12
13
  const OPENCODE_PORT_FLAG = "--port";
@@ -33,7 +34,10 @@ async function waitForServerReady(client, directory, timeoutMs, signal) {
33
34
  if (signal?.aborted)
34
35
  throw createAbortError("OpenCode server startup aborted");
35
36
  try {
36
- await client.config.get({ directory }, { throwOnError: true });
37
+ // Legacy config endpoints become available before the runtime model
38
+ // catalog. Prompting in that window is admitted, then fails asynchronously
39
+ // with ModelUnavailableError and no terminal event.
40
+ await client.v2.model.list({ location: { directory } }, { throwOnError: true });
37
41
  return;
38
42
  }
39
43
  catch {
@@ -67,13 +71,23 @@ export async function createOpencodeServer(options = {}) {
67
71
  return;
68
72
  if (mode === "force") {
69
73
  forceStop ??= new Promise((resolve, reject) => {
70
- child.once("close", resolve);
74
+ let timer;
75
+ const finish = (error) => {
76
+ if (timer)
77
+ clearTimeout(timer);
78
+ error === undefined ? resolve() : reject(error);
79
+ };
80
+ child.once("close", () => finish());
81
+ timer = setTimeout(() => {
82
+ finish(new Error("OpenCode server forced process exit was not observed"));
83
+ }, SERVER_SHUTDOWN_HARD_TIMEOUT_MS);
84
+ timer.unref?.();
71
85
  try {
72
86
  if (!child.kill("SIGKILL") && !exited)
73
- reject(new Error("OpenCode server force kill failed"));
87
+ finish(new Error("OpenCode server force kill failed"));
74
88
  }
75
89
  catch (error) {
76
- reject(error);
90
+ finish(error);
77
91
  }
78
92
  });
79
93
  await forceStop;
@@ -83,24 +97,43 @@ export async function createOpencodeServer(options = {}) {
83
97
  await forceStop;
84
98
  return;
85
99
  }
86
- gracefulStop ??= new Promise((resolve) => {
100
+ gracefulStop ??= new Promise((resolve, reject) => {
87
101
  let settled = false;
88
102
  let forceKill;
89
- const finish = () => {
103
+ let hardTimeout;
104
+ const finish = (error) => {
90
105
  if (settled)
91
106
  return;
92
107
  settled = true;
93
108
  if (forceKill)
94
109
  clearTimeout(forceKill);
95
- resolve();
110
+ if (hardTimeout)
111
+ clearTimeout(hardTimeout);
112
+ error === undefined ? resolve() : reject(error);
96
113
  };
97
- child.once("close", finish);
98
- child.kill("SIGTERM");
114
+ child.once("close", () => finish());
115
+ try {
116
+ child.kill("SIGTERM");
117
+ }
118
+ catch (error) {
119
+ finish(error);
120
+ return;
121
+ }
99
122
  forceKill = setTimeout(() => {
100
- if (!exited)
101
- child.kill("SIGKILL");
123
+ if (!exited) {
124
+ try {
125
+ child.kill("SIGKILL");
126
+ }
127
+ catch (error) {
128
+ finish(error);
129
+ }
130
+ }
102
131
  }, SERVER_SHUTDOWN_FORCE_KILL_MS);
103
- forceKill.unref();
132
+ forceKill.unref?.();
133
+ hardTimeout = setTimeout(() => {
134
+ finish(new Error("OpenCode server process exit was not observed"));
135
+ }, SERVER_SHUTDOWN_HARD_TIMEOUT_MS);
136
+ hardTimeout.unref?.();
104
137
  });
105
138
  await gracefulStop;
106
139
  };
@@ -1,33 +1,20 @@
1
- import { z } from "zod";
2
1
  import { appendDebugLog } from "../../../telemetry/debug-log.js";
3
2
  import { SUBAGENT_SESSION_VERSION } from "../../session.js";
4
3
  import { createProjectionDriver } from "../../harness/execution-handle.js";
4
+ import { createProviderFailure } from "../../harness/provider-adapter.js";
5
5
  import { buildSubagentEnv, createAbortError, emitProviderEvidence, linkAbortSignal, sha256Utf8 } from "../../harness/runtime.js";
6
- import { SubagentFailure } from "../../types.js";
7
6
  import { claudeIngressDisposition, emitClaudeThoughts, emitClaudeToolResults, emitClaudeToolStarts, emitClaudeUsage, extractAssistantMessage, extractAssistantMessageId, extractAssistantMessageModel, extractOverloadFallbackWarning, extractResultText, extractResumeToken, isClaudeApiRetryEvent, isClaudeModelRefusalFallbackEvent, isClaudeModelRefusalNoFallbackEvent, mapClaudeApiRetryWarning, } from "./events.js";
8
7
  import { CLAUDE_AGENT_SDK_PROVIDER, createPushableUserMessageStream, toClaudeUserMessage, } from "./session.js";
9
8
  function toClaudeSdkEffort(effort) {
10
9
  return effort; // opacity boundary
11
10
  }
12
- export const claudeSessionSchema = z.object({ sessionId: z.string().trim().min(1) });
13
- let claudeAgentSdkLoader;
11
+ export { claudeSessionSchema } from "./session-schema.js";
14
12
  async function loadClaudeAgentSdk(loader) {
15
13
  if (loader) {
16
14
  return loader();
17
15
  }
18
- if (claudeAgentSdkLoader) {
19
- return claudeAgentSdkLoader();
20
- }
21
16
  return (await import("@anthropic-ai/claude-agent-sdk"));
22
17
  }
23
- /** @deprecated Use ClaudeProviderOptions.loader instead. Kept for pipeline-based tests pending loader channel. */
24
- export function setClaudeAgentSdkLoaderForTests(loader) {
25
- claudeAgentSdkLoader = loader;
26
- }
27
- /** @deprecated Use ClaudeProviderOptions.loader instead. */
28
- export function resetClaudeAgentSdkLoaderForTests() {
29
- claudeAgentSdkLoader = undefined;
30
- }
31
18
  export async function startClaudeAgentSdk(prompt, cwd, options) {
32
19
  const sessionId = options.sessionId?.trim();
33
20
  let liveQuery;
@@ -314,7 +301,7 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
314
301
  const failCode = unavailable ? "SUBAGENT_PROVIDER_UNAVAILABLE" : "SUBAGENT_EXEC_ERROR";
315
302
  builder.emit({ type: "fail", message, code: failCode });
316
303
  inputStream?.end();
317
- throw new SubagentFailure(failCode, message);
304
+ throw createProviderFailure(message, { code: failCode });
318
305
  }
319
306
  default:
320
307
  break;
@@ -327,7 +314,7 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
327
314
  if (!resumedSessionId) {
328
315
  const message = `${CLAUDE_AGENT_SDK_PROVIDER} exec could not determine session id`;
329
316
  builder.emit({ type: "fail", message });
330
- throw new Error(message);
317
+ throw createProviderFailure(message);
331
318
  }
332
319
  const session = {
333
320
  provider: "claude-agent-sdk",
@@ -366,3 +353,5 @@ export async function startClaudeAgentSdk(prompt, cwd, options) {
366
353
  },
367
354
  });
368
355
  }
356
+ // Compiler-level binding to the named ProviderAdapter function contract.
357
+ startClaudeAgentSdk;
@@ -0,0 +1,214 @@
1
+ import { z } from "zod";
2
+ import { claudeSettingSourceSchema, executableSchema, providerCommonFields, providerEnvSchema, } from "../../../config/settings/provider-instance-fields.js";
3
+ import { FlowError } from "../../../flow-error.js";
4
+ import { exactKeys, optionalString, optionalStringRecord, requiredEnum, snapshotError, } from "../../launch-snapshot/parse-helpers.js";
5
+ import { SUBAGENT_SESSION_VERSION, subagentSessionEnvelopeSchema, } from "../../session.js";
6
+ import { CLAUDE_AGENT_SDK_PROVIDER } from "./session.js";
7
+ import { claudeSessionSchema } from "./session-schema.js";
8
+ const startClaudeAgentSdk = async (prompt, cwd, options) => {
9
+ const { startClaudeAgentSdk: start } = await import("./adapter.js");
10
+ return start(prompt, cwd, options);
11
+ };
12
+ const CLAUDE_SETTING_SOURCES = new Set(["project", "user", "local"]);
13
+ const ACCESS_VALUES = ["read", "write", "auto"];
14
+ function admitResumeShape(schema, session, resumePath) {
15
+ const envelopeResult = subagentSessionEnvelopeSchema.safeParse(session);
16
+ if (!envelopeResult.success) {
17
+ throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' includes an invalid session envelope.`);
18
+ }
19
+ if (session.provider !== CLAUDE_AGENT_SDK_PROVIDER) {
20
+ throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' was created with provider '${session.provider}', but the selected subagent resolves to '${CLAUDE_AGENT_SDK_PROVIDER}'. Cross-provider resume is not supported.`);
21
+ }
22
+ if (session.version !== SUBAGENT_SESSION_VERSION) {
23
+ throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' uses unsupported session version '${session.version}' for provider '${session.provider}'.`);
24
+ }
25
+ const shapeResult = schema.safeParse(session.handle);
26
+ if (!shapeResult.success) {
27
+ throw new FlowError("INVALID_RESPONSE_PATH", `Resume path file '${resumePath}' includes an invalid session handle for provider '${session.provider}'.`);
28
+ }
29
+ return shapeResult.data;
30
+ }
31
+ export const claudeAgentSdkRegistration = {
32
+ name: CLAUDE_AGENT_SDK_PROVIDER,
33
+ start: startClaudeAgentSdk,
34
+ sessionSchema: claudeSessionSchema,
35
+ effortField: "effort",
36
+ instanceSchema: z
37
+ .object({
38
+ kind: z.literal(CLAUDE_AGENT_SDK_PROVIDER),
39
+ ...providerCommonFields,
40
+ executable: executableSchema.optional(),
41
+ settingSources: z.array(claudeSettingSourceSchema).optional(),
42
+ env: providerEnvSchema,
43
+ })
44
+ .strict(),
45
+ builtinInstance: {
46
+ name: CLAUDE_AGENT_SDK_PROVIDER,
47
+ source: "builtin",
48
+ instance: {
49
+ kind: CLAUDE_AGENT_SDK_PROVIDER,
50
+ executable: "claude",
51
+ settingSources: ["project"],
52
+ },
53
+ },
54
+ builtinAkumaProfiles: [
55
+ { name: "akuma-claude", description: "Default Claude Agent SDK Akuma." },
56
+ ],
57
+ portablePolicy: {
58
+ access: new Set(ACCESS_VALUES),
59
+ network: new Set(),
60
+ webSearch: new Set(["disabled"]),
61
+ },
62
+ maxCaptureChars: (config) => config.claude.execMaxCaptureChars,
63
+ buildCallTerms: ({ snapshot, baseTerms, body }) => {
64
+ const provider = snapshot.provider;
65
+ return {
66
+ ...baseTerms,
67
+ provider: CLAUDE_AGENT_SDK_PROVIDER,
68
+ ...(provider.model !== undefined ? { model: provider.model } : {}),
69
+ ...(provider.effort !== undefined ? { effort: provider.effort } : {}),
70
+ ...(provider.executable !== undefined ? { executable: provider.executable } : {}),
71
+ ...(provider.settingSources !== undefined ? { settingSources: provider.settingSources } : {}),
72
+ permissionMode: provider.permissionMode,
73
+ ...(provider.allowDangerouslySkipPermissions !== undefined
74
+ ? { allowDangerouslySkipPermissions: provider.allowDangerouslySkipPermissions }
75
+ : {}),
76
+ ...(provider.disallowedTools !== undefined ? { disallowedTools: provider.disallowedTools } : {}),
77
+ ...(provider.env !== undefined ? { env: provider.env } : {}),
78
+ systemPrompt: body
79
+ ? { type: "preset", preset: "claude_code", append: body }
80
+ : undefined,
81
+ onCheckpoint() { },
82
+ };
83
+ },
84
+ resolveLaunchProvider: ({ common, instance, model, effort, access, webSearch }) => {
85
+ if (instance.kind !== CLAUDE_AGENT_SDK_PROVIDER) {
86
+ throw new Error(`resolveLaunchProvider expected ${CLAUDE_AGENT_SDK_PROVIDER}`);
87
+ }
88
+ const claudeInstance = instance;
89
+ const permissionMode = access === "read"
90
+ ? "plan"
91
+ : access === "write"
92
+ ? "acceptEdits"
93
+ : access === "auto"
94
+ ? "bypassPermissions"
95
+ : "default";
96
+ return Object.freeze({
97
+ ...common,
98
+ kind: CLAUDE_AGENT_SDK_PROVIDER,
99
+ ...(claudeInstance.executable !== undefined ? { executable: claudeInstance.executable } : {}),
100
+ ...(model !== undefined ? { model } : {}),
101
+ ...(effort !== undefined ? { effort } : {}),
102
+ ...(claudeInstance.settingSources !== undefined ? { settingSources: claudeInstance.settingSources } : {}),
103
+ permissionMode,
104
+ ...(permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {}),
105
+ ...(webSearch === "disabled" ? { disallowedTools: ["WebSearch"] } : {}),
106
+ ...(claudeInstance.env !== undefined ? { env: claudeInstance.env } : {}),
107
+ });
108
+ },
109
+ parseLaunchProvider: (provider, common) => {
110
+ exactKeys(provider, [
111
+ "name",
112
+ "source",
113
+ "kind",
114
+ "executable",
115
+ "model",
116
+ "effort",
117
+ "settingSources",
118
+ "permissionMode",
119
+ "allowDangerouslySkipPermissions",
120
+ "disallowedTools",
121
+ "env",
122
+ ], "provider");
123
+ const modes = new Set(["default", "plan", "acceptEdits", "bypassPermissions"]);
124
+ const permissionMode = requiredEnum(provider, "permissionMode", "provider", modes);
125
+ if (permissionMode === "bypassPermissions") {
126
+ if (provider.allowDangerouslySkipPermissions !== true) {
127
+ throw snapshotError("provider.allowDangerouslySkipPermissions", "must be true for bypassPermissions");
128
+ }
129
+ }
130
+ else if ("allowDangerouslySkipPermissions" in provider) {
131
+ throw snapshotError("provider.allowDangerouslySkipPermissions", "is only valid for bypassPermissions");
132
+ }
133
+ let settingSources;
134
+ if ("settingSources" in provider) {
135
+ if (!Array.isArray(provider.settingSources))
136
+ throw snapshotError("provider.settingSources", "must be an array");
137
+ settingSources = Object.freeze(provider.settingSources.map((source, index) => {
138
+ if (typeof source !== "string" || !CLAUDE_SETTING_SOURCES.has(source)) {
139
+ throw snapshotError(`provider.settingSources[${index}]`, "has an invalid setting source");
140
+ }
141
+ return source;
142
+ }));
143
+ }
144
+ let disallowedTools;
145
+ if ("disallowedTools" in provider) {
146
+ if (!Array.isArray(provider.disallowedTools) ||
147
+ provider.disallowedTools.length !== 1 ||
148
+ provider.disallowedTools[0] !== "WebSearch") {
149
+ throw snapshotError("provider.disallowedTools", "must equal ['WebSearch']");
150
+ }
151
+ disallowedTools = Object.freeze(["WebSearch"]);
152
+ }
153
+ const executable = optionalString(provider, "executable", "provider");
154
+ const model = optionalString(provider, "model", "provider");
155
+ const effort = optionalString(provider, "effort", "provider");
156
+ const env = optionalStringRecord(provider, "env");
157
+ return Object.freeze({
158
+ ...common,
159
+ kind: CLAUDE_AGENT_SDK_PROVIDER,
160
+ ...(executable !== undefined ? { executable } : {}),
161
+ ...(model !== undefined ? { model } : {}),
162
+ ...(effort !== undefined ? { effort } : {}),
163
+ ...(settingSources !== undefined ? { settingSources } : {}),
164
+ permissionMode,
165
+ ...(permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {}),
166
+ ...(disallowedTools !== undefined ? { disallowedTools } : {}),
167
+ ...(env !== undefined ? { env } : {}),
168
+ });
169
+ },
170
+ applyEffort: (provider, effort) => Object.freeze({ ...provider, effort }),
171
+ providerEffortAndModel: (provider) => {
172
+ const resolved = provider;
173
+ return { model: resolved.model, effort: resolved.effort };
174
+ },
175
+ attachLoader: (terms, ports) => {
176
+ if (terms.provider !== CLAUDE_AGENT_SDK_PROVIDER)
177
+ return terms;
178
+ const loader = ports.claudeAgentSdk;
179
+ return loader ? { ...terms, loader } : terms;
180
+ },
181
+ nativePolicyOwnership: () => null,
182
+ startLive: async ({ terms, signal, reviveTerms, onSyncCheckpoint, onIngress }) => {
183
+ if (terms.provider !== CLAUDE_AGENT_SDK_PROVIDER) {
184
+ throw new Error(`startLive expected ${CLAUDE_AGENT_SDK_PROVIDER}`);
185
+ }
186
+ const claudeTerms = terms;
187
+ const claudeOptions = {
188
+ model: claudeTerms.model,
189
+ executable: claudeTerms.executable,
190
+ effort: claudeTerms.effort,
191
+ env: claudeTerms.env,
192
+ signal,
193
+ permissionMode: claudeTerms.permissionMode,
194
+ settingSources: claudeTerms.settingSources,
195
+ allowDangerouslySkipPermissions: claudeTerms.allowDangerouslySkipPermissions,
196
+ disallowedTools: claudeTerms.disallowedTools,
197
+ systemPrompt: claudeTerms.systemPrompt,
198
+ onSyncCheckpoint,
199
+ onEvidence: claudeTerms.onEvidence,
200
+ onIngress,
201
+ initialTurn: claudeTerms.initialTurn,
202
+ loader: claudeTerms.loader,
203
+ };
204
+ const { startClaudeAgentSdk: start } = await import("./adapter.js");
205
+ if (reviveTerms) {
206
+ const session = admitResumeShape(claudeSessionSchema, reviveTerms.session, reviveTerms.resumePath);
207
+ return start(claudeTerms.prompt, claudeTerms.workdir, {
208
+ ...claudeOptions,
209
+ sessionId: session.sessionId,
210
+ });
211
+ }
212
+ return start(claudeTerms.prompt, claudeTerms.workdir, claudeOptions);
213
+ },
214
+ };
@@ -0,0 +1,2 @@
1
+ import { z } from "zod";
2
+ export const claudeSessionSchema = z.object({ sessionId: z.string().trim().min(1) });