@astrosheep/keiyaku 4.0.4 → 4.0.6

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 (233) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +15 -7
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -3
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +24 -4
  8. package/build/src/akuma/akuma.d.ts +2 -1
  9. package/build/src/akuma/akuma.js +27 -9
  10. package/build/src/akuma/allowed.d.ts +1 -1
  11. package/build/src/akuma/allowed.js +3 -10
  12. package/build/src/akuma/archetype.d.ts +3 -1
  13. package/build/src/akuma/archetype.js +11 -6
  14. package/build/src/akuma/body-turn.d.ts +64 -0
  15. package/build/src/akuma/body-turn.js +449 -0
  16. package/build/src/akuma/body.d.ts +4 -5
  17. package/build/src/akuma/body.js +9 -414
  18. package/build/src/akuma/heart/facts.d.ts +37 -9
  19. package/build/src/akuma/heart/facts.js +3 -1
  20. package/build/src/akuma/heart/index.d.ts +4 -13
  21. package/build/src/akuma/heart/index.js +14 -135
  22. package/build/src/akuma/heart/request-authority.d.ts +12 -0
  23. package/build/src/akuma/heart/request-authority.js +119 -0
  24. package/build/src/akuma/heart/request-rows.d.ts +16 -0
  25. package/build/src/akuma/heart/request-rows.js +88 -0
  26. package/build/src/akuma/heart/rows.d.ts +1 -28
  27. package/build/src/akuma/heart/rows.js +4 -138
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +11 -3
  30. package/build/src/akuma/heart/soul.js +0 -36
  31. package/build/src/akuma/heart/timeline.d.ts +1 -0
  32. package/build/src/akuma/heart/timeline.js +19 -0
  33. package/build/src/akuma/index.d.ts +1 -1
  34. package/build/src/akuma/nuke.d.ts +2 -0
  35. package/build/src/akuma/nuke.js +152 -0
  36. package/build/src/akuma/provider-recipe.js +1 -11
  37. package/build/src/akuma/provider.d.ts +4 -7
  38. package/build/src/akuma/providers/acp/config.d.ts +8 -0
  39. package/build/src/akuma/providers/acp/config.js +37 -0
  40. package/build/src/akuma/providers/acp/core.js +12 -2
  41. package/build/src/akuma/providers/acp/index.d.ts +1 -8
  42. package/build/src/akuma/providers/acp/index.js +2 -38
  43. package/build/src/akuma/providers/claude/index.d.ts +0 -4
  44. package/build/src/akuma/providers/claude/index.js +12 -3
  45. package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
  46. package/build/src/akuma/providers/codex-app-server/index.js +5 -2
  47. package/build/src/akuma/providers/grok-build/index.js +1 -2
  48. package/build/src/akuma/providers/index.d.ts +3 -2
  49. package/build/src/akuma/providers/index.js +36 -36
  50. package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
  51. package/build/src/akuma/providers/opencode-sdk/index.js +14 -4
  52. package/build/src/akuma/providers/opencode-sdk/session.d.ts +2 -2
  53. package/build/src/akuma/providers/opencode-sdk/session.js +2 -2
  54. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  55. package/build/src/akuma/providers/pi/index.js +29 -6
  56. package/build/src/akuma/request-serve.d.ts +88 -0
  57. package/build/src/akuma/request-serve.js +484 -0
  58. package/build/src/akuma/request-wire.d.ts +125 -0
  59. package/build/src/akuma/request-wire.js +383 -0
  60. package/build/src/akuma/requests.d.ts +28 -94
  61. package/build/src/akuma/requests.js +52 -562
  62. package/build/src/akuma-body.d.ts +7 -0
  63. package/build/src/akuma-body.js +69 -2
  64. package/build/src/alias/index.d.ts +1 -0
  65. package/build/src/alias/index.js +34 -1
  66. package/build/src/body/arc.js +4 -29
  67. package/build/src/body/decode.js +5 -39
  68. package/build/src/body/envelope.d.ts +7 -0
  69. package/build/src/body/envelope.js +37 -0
  70. package/build/src/cli/accepted.js +21 -9
  71. package/build/src/cli/commands/akuma-invoke.js +1 -0
  72. package/build/src/cli/commands/akuma.d.ts +1 -0
  73. package/build/src/cli/commands/akuma.js +13 -10
  74. package/build/src/cli/commands/contract.d.ts +28 -17
  75. package/build/src/cli/commands/contract.js +23 -17
  76. package/build/src/cli/commands/install.d.ts +2 -2
  77. package/build/src/cli/commands/install.js +6 -6
  78. package/build/src/cli/commands/nuke.d.ts +10 -0
  79. package/build/src/cli/commands/nuke.js +20 -0
  80. package/build/src/cli/commands/task-invoke.d.ts +15 -0
  81. package/build/src/cli/commands/task-invoke.js +144 -24
  82. package/build/src/cli/commands/task-query.d.ts +2 -2
  83. package/build/src/cli/commands/task-query.js +1 -2
  84. package/build/src/cli/commands/task.js +22 -22
  85. package/build/src/cli/coordinates.d.ts +6 -2
  86. package/build/src/cli/coordinates.js +12 -56
  87. package/build/src/cli/invoke.d.ts +5 -4
  88. package/build/src/cli/invoke.js +112 -58
  89. package/build/src/cli/main.d.ts +0 -2
  90. package/build/src/cli/main.js +4 -140
  91. package/build/src/cli/parse.d.ts +17 -4
  92. package/build/src/cli/parse.js +93 -15
  93. package/build/src/cli/render/akuma.js +111 -53
  94. package/build/src/cli/render/audit.js +2 -6
  95. package/build/src/cli/render/contract.js +61 -20
  96. package/build/src/cli/render/kanshi.js +15 -5
  97. package/build/src/cli/render/nuke.d.ts +3 -0
  98. package/build/src/cli/render/nuke.js +8 -0
  99. package/build/src/cli/render/receipt.js +28 -1
  100. package/build/src/cli/render/refusal.d.ts +2 -1
  101. package/build/src/cli/render/refusal.js +31 -0
  102. package/build/src/cli/render/terminal.d.ts +0 -2
  103. package/build/src/cli/render/terminal.js +0 -29
  104. package/build/src/cli/render/text.js +6 -1
  105. package/build/src/cli/result.d.ts +36 -9
  106. package/build/src/cli/runtime.d.ts +2 -0
  107. package/build/src/cli/runtime.js +140 -0
  108. package/build/src/cli/usage.d.ts +0 -2
  109. package/build/src/cli/usage.js +0 -4
  110. package/build/src/contract-worktree.d.ts +29 -14
  111. package/build/src/contract-worktree.js +131 -70
  112. package/build/src/core/facts/codec.js +9 -0
  113. package/build/src/core/facts/fold.js +13 -1
  114. package/build/src/core/facts/types.d.ts +8 -1
  115. package/build/src/core/subject.js +4 -3
  116. package/build/src/core/verbs/placement.d.ts +9 -1
  117. package/build/src/core/verbs/placement.js +24 -6
  118. package/build/src/core/verbs/reintegrate.d.ts +13 -0
  119. package/build/src/core/verbs/reintegrate.js +24 -0
  120. package/build/src/dispatch/index.d.ts +1 -1
  121. package/build/src/git/admission.d.ts +2 -1
  122. package/build/src/git/hooks.d.ts +2 -0
  123. package/build/src/git/hooks.js +34 -1
  124. package/build/src/git/integration.d.ts +9 -2
  125. package/build/src/git/integration.js +92 -1
  126. package/build/src/git/nuke.d.ts +2 -0
  127. package/build/src/git/nuke.js +97 -0
  128. package/build/src/git/observe.d.ts +2 -1
  129. package/build/src/git/observe.js +6 -5
  130. package/build/src/git/process.d.ts +28 -0
  131. package/build/src/git/process.js +94 -0
  132. package/build/src/git/read-observation.d.ts +2 -1
  133. package/build/src/git/read-observation.js +3 -2
  134. package/build/src/git/reconcile.d.ts +4 -1
  135. package/build/src/git/reconcile.js +42 -8
  136. package/build/src/git/repository.d.ts +2 -29
  137. package/build/src/git/repository.js +7 -118
  138. package/build/src/git/scratch.d.ts +1 -1
  139. package/build/src/git/scratch.js +1 -1
  140. package/build/src/git/target-placement.d.ts +3 -2
  141. package/build/src/git/target-placement.js +15 -14
  142. package/build/src/git/tender.d.ts +2 -1
  143. package/build/src/git/tender.js +4 -3
  144. package/build/src/git/terminal-seal.d.ts +2 -2
  145. package/build/src/git/terminal-seal.js +3 -6
  146. package/build/src/git/workspace.d.ts +4 -1
  147. package/build/src/git/workspace.js +1 -1
  148. package/build/src/index.d.ts +1 -2
  149. package/build/src/index.js +1 -1
  150. package/build/src/kanshi/read.js +5 -1
  151. package/build/src/library/address.js +7 -1
  152. package/build/src/library/akuma-creation.d.ts +1 -0
  153. package/build/src/library/akuma-creation.js +8 -1
  154. package/build/src/library/audit.d.ts +3 -1
  155. package/build/src/library/audit.js +2 -1
  156. package/build/src/library/bind.d.ts +2 -1
  157. package/build/src/library/bind.js +1 -1
  158. package/build/src/library/configuration.d.ts +1 -1
  159. package/build/src/library/configuration.js +52 -18
  160. package/build/src/library/contract.d.ts +59 -4
  161. package/build/src/library/contract.js +195 -34
  162. package/build/src/library/delivery.d.ts +4 -2
  163. package/build/src/library/fleet.d.ts +27 -7
  164. package/build/src/library/fleet.js +79 -39
  165. package/build/src/library/input.d.ts +0 -1
  166. package/build/src/library/input.js +0 -5
  167. package/build/src/library/keiyaku.d.ts +6 -2
  168. package/build/src/library/keiyaku.js +2 -0
  169. package/build/src/library/mutation.d.ts +3 -1
  170. package/build/src/library/mutation.js +3 -0
  171. package/build/src/library/nuke.d.ts +14 -0
  172. package/build/src/library/nuke.js +54 -0
  173. package/build/src/library/reconcile.d.ts +2 -1
  174. package/build/src/library/reconcile.js +8 -3
  175. package/build/src/library/refusal.d.ts +10 -1
  176. package/build/src/library/region.d.ts +1 -1
  177. package/build/src/library/repo.d.ts +4 -1
  178. package/build/src/library/repo.js +10 -4
  179. package/build/src/protocol/abandon.d.ts +9 -0
  180. package/build/src/protocol/abandon.js +15 -0
  181. package/build/src/protocol/amend.d.ts +16 -0
  182. package/build/src/protocol/amend.js +77 -0
  183. package/build/src/protocol/arc.d.ts +6 -0
  184. package/build/src/protocol/arc.js +12 -0
  185. package/build/src/protocol/attempt.d.ts +2 -1
  186. package/build/src/protocol/audit.d.ts +53 -0
  187. package/build/src/protocol/audit.js +147 -0
  188. package/build/src/protocol/bind.d.ts +1 -1
  189. package/build/src/protocol/completion.d.ts +42 -0
  190. package/build/src/protocol/completion.js +183 -0
  191. package/build/src/protocol/deliver.d.ts +49 -0
  192. package/build/src/protocol/deliver.js +261 -0
  193. package/build/src/protocol/intent.d.ts +2 -1
  194. package/build/src/protocol/intent.js +8 -2
  195. package/build/src/protocol/operations.d.ts +93 -202
  196. package/build/src/protocol/operations.js +23 -642
  197. package/build/src/protocol/placement.d.ts +12 -13
  198. package/build/src/protocol/placement.js +8 -19
  199. package/build/src/protocol/read/status.d.ts +17 -5
  200. package/build/src/protocol/read/status.js +57 -13
  201. package/build/src/protocol/reconcile.d.ts +35 -0
  202. package/build/src/protocol/reconcile.js +41 -0
  203. package/build/src/protocol/reintegrate.d.ts +31 -0
  204. package/build/src/protocol/reintegrate.js +74 -0
  205. package/build/src/protocol/review.d.ts +34 -0
  206. package/build/src/protocol/review.js +156 -0
  207. package/build/src/protocol/run.d.ts +1 -1
  208. package/build/src/runtime/proc/run.js +9 -5
  209. package/build/src/settlement/fence.d.ts +3 -1
  210. package/build/src/settlement/fence.js +24 -0
  211. package/build/src/settlement/holder.d.ts +1 -1
  212. package/build/src/settlement/settle.d.ts +1 -1
  213. package/build/src/settlement/settle.js +1 -2
  214. package/build/src/task/board.d.ts +0 -1
  215. package/build/src/task/board.js +0 -3
  216. package/build/src/task/compose.d.ts +2 -2
  217. package/build/src/task/compose.js +13 -11
  218. package/build/src/task/context.d.ts +14 -2
  219. package/build/src/task/context.js +30 -7
  220. package/build/src/task/index.d.ts +7 -6
  221. package/build/src/task/index.js +17 -145
  222. package/build/src/task/input.d.ts +18 -0
  223. package/build/src/task/input.js +189 -0
  224. package/build/src/task/mutation.d.ts +44 -0
  225. package/build/src/task/mutation.js +93 -0
  226. package/build/src/task/operations.d.ts +14 -6
  227. package/build/src/task/operations.js +57 -57
  228. package/build/src/task/store.d.ts +1 -0
  229. package/build/src/task/store.js +91 -3
  230. package/build/src/verification/execution.d.ts +1 -1
  231. package/build/src/workspace-place.d.ts +3 -4
  232. package/build/src/workspace-place.js +26 -15
  233. package/package.json +3 -3
@@ -182,6 +182,11 @@ async function startCodex(execution, input) {
182
182
  events,
183
183
  completion,
184
184
  abort: () => abortTurn(server, state, finish),
185
+ forceDispose: async () => {
186
+ if (!state.settled)
187
+ settle({ kind: "failed", diagnostic: "codex app-server force-disposed" });
188
+ await server.close(true);
189
+ },
185
190
  tell: (tell) => steerTurn(server, state, tell),
186
191
  };
187
192
  }
@@ -190,7 +195,6 @@ export function createCodexAppServerProvider(input = "codex") {
190
195
  ? { name: "codex-app-server", kind: "codex-app-server", executable: input }
191
196
  : input;
192
197
  return {
193
- confinement: ({ cwd }) => ({ kind: "declared", writableRoots: [cwd] }),
194
198
  admitOptions(options) {
195
199
  return {
196
200
  kind: "admitted",
@@ -203,4 +207,3 @@ export function createCodexAppServerProvider(input = "codex") {
203
207
  resume: (input) => startCodex(execution, input),
204
208
  };
205
209
  }
206
- export const codexAppServerProvider = createCodexAppServerProvider();
@@ -10,7 +10,7 @@ function object(value) {
10
10
  }
11
11
  function nativeName(update) {
12
12
  const wire = update;
13
- return nonblank(update.name) ?? nonblank(wire.toolName);
13
+ return nonblank(update.name) ?? nonblank(update.title) ?? nonblank(wire.toolName);
14
14
  }
15
15
  function readCall(name, input) {
16
16
  if (name !== "read_file" && name !== "hashline_read")
@@ -132,7 +132,6 @@ export function createGrokBuildProvider(execution, dependencies = {}) {
132
132
  }));
133
133
  };
134
134
  return {
135
- confinement: () => ({ kind: "unconfined" }),
136
135
  admitOptions: optionAdmission,
137
136
  start: async (input) => await drive(input),
138
137
  resume: async (input) => await drive(input),
@@ -1,6 +1,7 @@
1
1
  import type { ProviderAdapter } from "../provider.js";
2
2
  import { type ProviderExecution } from "../provider-recipe.js";
3
- export declare function resolveProviderExecution(input: unknown): Readonly<{
3
+ export declare function decodeProviderExecution(input: unknown): ProviderExecution;
4
+ export declare function resolveProviderExecution(input: unknown): Promise<Readonly<{
4
5
  execution: ProviderExecution;
5
6
  adapter: ProviderAdapter;
6
- }>;
7
+ }>>;
@@ -1,50 +1,50 @@
1
1
  import { decodeProviderRecipe } from "../provider-recipe.js";
2
- import { createAcpProvider, decodeAcpConfig } from "./acp/index.js";
3
- import { claudeProvider, createClaudeProvider } from "./claude/index.js";
4
- import { createCodexAppServerProvider } from "./codex-app-server/index.js";
5
- import { createGrokBuildProvider } from "./grok-build/index.js";
6
- import { createOpencodeProvider } from "./opencode-sdk/index.js";
7
- import { createPiProvider } from "./pi/index.js";
8
- const PROVIDERS = {
9
- claude: claudeProvider,
10
- };
11
- function providerConfig(execution) {
12
- const { config, kind } = execution;
13
- if (kind === "claude-agent-sdk" && config !== undefined)
14
- throw new TypeError("provider execution config is unsupported by claude-agent-sdk");
15
- if (kind === "opencode-sdk" && config !== undefined)
16
- throw new TypeError("provider execution config is unsupported by opencode-sdk");
17
- if (kind === "acp")
18
- return decodeAcpConfig(config);
19
- return config;
2
+ import { decodeAcpConfig } from "./acp/config.js";
3
+ export function decodeProviderExecution(input) {
4
+ const decoded = decodeProviderRecipe(input);
5
+ if ((decoded.kind === "claude-agent-sdk" || decoded.kind === "opencode-sdk") && decoded.config !== undefined) {
6
+ throw new TypeError(`provider execution config is unsupported by ${decoded.kind}`);
7
+ }
8
+ if (decoded.kind === "pi") {
9
+ if (decoded.executable !== undefined || decoded.config !== undefined) {
10
+ throw new TypeError("Pi provider does not support executable or config");
11
+ }
12
+ if (decoded.env !== undefined && Object.keys(decoded.env).length > 0) {
13
+ throw new TypeError("env injection not supported for provider pi");
14
+ }
15
+ }
16
+ if (decoded.kind === "grok-build" && decoded.config !== undefined) {
17
+ throw new TypeError("Grok Build does not support execution config");
18
+ }
19
+ const config = decoded.kind === "acp" ? decodeAcpConfig(decoded.config) : decoded.config;
20
+ return Object.freeze({
21
+ name: decoded.name,
22
+ kind: decoded.kind,
23
+ ...(decoded.executable === undefined ? {} : { executable: decoded.executable }),
24
+ ...(config === undefined ? {} : { config }),
25
+ ...(decoded.env === undefined ? {} : { env: decoded.env }),
26
+ });
20
27
  }
21
- function adapterFor(execution) {
28
+ async function adapterFor(execution) {
22
29
  if (execution.kind === "acp")
23
- return createAcpProvider(execution);
30
+ return (await import("./acp/index.js")).createAcpProvider(execution);
24
31
  if (execution.kind === "claude-agent-sdk") {
32
+ const { claudeProvider, createClaudeProvider } = await import("./claude/index.js");
25
33
  return execution.executable === undefined && execution.env === undefined
26
- ? PROVIDERS.claude
34
+ ? claudeProvider
27
35
  : createClaudeProvider(async () => await import("@anthropic-ai/claude-agent-sdk"), execution);
28
36
  }
29
37
  if (execution.kind === "codex-app-server")
30
- return createCodexAppServerProvider(execution);
38
+ return (await import("./codex-app-server/index.js")).createCodexAppServerProvider(execution);
31
39
  if (execution.kind === "grok-build")
32
- return createGrokBuildProvider(execution);
40
+ return (await import("./grok-build/index.js")).createGrokBuildProvider(execution);
33
41
  if (execution.kind === "opencode-sdk")
34
- return createOpencodeProvider(execution);
42
+ return (await import("./opencode-sdk/index.js")).createOpencodeProvider(execution);
35
43
  if (execution.kind === "pi")
36
- return createPiProvider(execution);
44
+ return (await import("./pi/index.js")).createPiProvider(execution);
37
45
  throw new TypeError(`unknown Akuma provider kind ${execution.kind}`);
38
46
  }
39
- export function resolveProviderExecution(input) {
40
- const decoded = decodeProviderRecipe(input);
41
- const config = providerConfig(decoded);
42
- const execution = Object.freeze({
43
- name: decoded.name,
44
- kind: decoded.kind,
45
- ...(decoded.executable === undefined ? {} : { executable: decoded.executable }),
46
- ...(config === undefined ? {} : { config }),
47
- ...(decoded.env === undefined ? {} : { env: decoded.env }),
48
- });
49
- return Object.freeze({ execution, adapter: adapterFor(execution) });
47
+ export async function resolveProviderExecution(input) {
48
+ const execution = decodeProviderExecution(input);
49
+ return Object.freeze({ execution, adapter: await adapterFor(execution) });
50
50
  }
@@ -1,33 +1,7 @@
1
- import { type ProviderAdapter, type Session } from "../../provider.js";
2
- import type { ResumeCoordinate } from "../../heart/index.js";
3
- import type { ProviderExecution, ProviderOptions } from "../../provider-recipe.js";
1
+ import { type ProviderAdapter } from "../../provider.js";
2
+ import type { ProviderExecution } from "../../provider-recipe.js";
4
3
  import { type OpencodeSdkLoader } from "./session.js";
5
4
  export type OpencodeProviderTestOptions = Readonly<{
6
5
  loader?: OpencodeSdkLoader;
7
6
  }>;
8
7
  export declare function createOpencodeProvider(input?: ProviderExecution | OpencodeProviderTestOptions): ProviderAdapter;
9
- export declare const opencodeProvider: Readonly<{
10
- confinement(input: Readonly<{
11
- cwd: string;
12
- options: ProviderOptions;
13
- }>): import("../../heart/facts.js").Confinement;
14
- admitOptions(options: ProviderOptions): import("../../provider.js").ProviderOptionAdmission;
15
- fork?(input: Readonly<{
16
- session: ResumeCoordinate;
17
- at: string;
18
- cwd: string;
19
- }>): Promise<Readonly<{
20
- session: ResumeCoordinate;
21
- }>>;
22
- start(input: import("../../provider.js").DriveInput & Readonly<{
23
- session: Readonly<{
24
- kind: "fresh";
25
- }>;
26
- }>): Promise<Session>;
27
- resume?(input: import("../../provider.js").DriveInput & Readonly<{
28
- session: Readonly<{
29
- kind: "resume";
30
- coordinate: ResumeCoordinate;
31
- }>;
32
- }>): Promise<Session>;
33
- }>;
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { abortable } from "../../abort.js";
3
- import { AgentEventChannel } from "../../provider.js";
3
+ import { AKUMA_REQUESTS_ENV, AgentEventChannel, } from "../../provider.js";
4
4
  import { createEventState, mapEvent } from "./events.js";
5
5
  import { coordinate, loadOpencode, OPENCODE_SDK_PROVIDER, parseModel } from "./session.js";
6
6
  function object(value) {
@@ -195,6 +195,11 @@ function terminalSettlement(events, close) {
195
195
  });
196
196
  return { completion, finish };
197
197
  }
198
+ async function forceDisposeOpencode(abortController, close, finish) {
199
+ abortController.abort();
200
+ await close();
201
+ await finish({ kind: "failed", diagnostic: "OpenCode session force-disposed" });
202
+ }
198
203
  async function drive(execution, input, loader) {
199
204
  admit(input.options);
200
205
  const signal = input.signal ?? new AbortController().signal;
@@ -205,7 +210,13 @@ async function drive(execution, input, loader) {
205
210
  const abortSetup = () => abortController.abort(signal.reason);
206
211
  signal.addEventListener("abort", abortSetup, { once: true });
207
212
  signal.throwIfAborted();
208
- const runtime = await abortable(loadOpencode(execution, input.cwd, abortController.signal, loader), abortController.signal, async (late) => await late.close());
213
+ const runtime = await abortable(loadOpencode({
214
+ ...execution,
215
+ env: {
216
+ ...execution.env,
217
+ ...(input.requests === undefined ? {} : { [AKUMA_REQUESTS_ENV]: input.requests.dir }),
218
+ },
219
+ }, input.cwd, abortController.signal, loader), abortController.signal, async (late) => await late.close());
209
220
  let closing;
210
221
  let iterator;
211
222
  const closeOnce = () => {
@@ -250,6 +261,7 @@ async function drive(execution, input, loader) {
250
261
  void session.abort({ path: { id: sessionId }, query: { directory: input.cwd }, throwOnError: true }).catch(() => undefined);
251
262
  await finish({ kind: "failed", diagnostic: "OpenCode session interrupted" });
252
263
  },
264
+ forceDispose: () => forceDisposeOpencode(abortController, closeOnce, finish),
253
265
  };
254
266
  }
255
267
  catch (error) {
@@ -263,7 +275,6 @@ export function createOpencodeProvider(input = { name: OPENCODE_SDK_PROVIDER, ki
263
275
  const execution = "kind" in input ? input : { name: OPENCODE_SDK_PROVIDER, kind: "opencode-sdk" };
264
276
  const loader = "loader" in input ? input.loader : undefined;
265
277
  return {
266
- confinement: ({ cwd }) => ({ kind: "declared", writableRoots: [cwd] }),
267
278
  admitOptions(options) {
268
279
  try {
269
280
  admit(options);
@@ -305,4 +316,3 @@ export function createOpencodeProvider(input = { name: OPENCODE_SDK_PROVIDER, ki
305
316
  },
306
317
  };
307
318
  }
308
- export const opencodeProvider = createOpencodeProvider();
@@ -1,9 +1,9 @@
1
- import { type OpencodeClient } from "@opencode-ai/sdk";
1
+ import type { OpencodeClient } from "@opencode-ai/sdk";
2
2
  import type { ResumeCoordinate } from "../../heart/index.js";
3
3
  import type { ProviderExecution } from "../../provider-recipe.js";
4
4
  export type OpencodeSdkSession = Pick<OpencodeClient["session"], "create" | "get" | "fork" | "abort" | "promptAsync" | "messages">;
5
5
  export type OpencodeSdkEvent = Pick<OpencodeClient["event"], "subscribe">;
6
- export type OpencodeSdkLoader = (cwd: string) => Promise<Readonly<{
6
+ export type OpencodeSdkLoader = (cwd: string, execution: ProviderExecution) => Promise<Readonly<{
7
7
  client: {
8
8
  session: OpencodeSdkSession;
9
9
  event: OpencodeSdkEvent;
@@ -1,7 +1,6 @@
1
1
  import net from "node:net";
2
2
  import { abortable } from "../../abort.js";
3
3
  import { spawnDetachedProcess } from "../../../runtime/proc/run.js";
4
- import { createOpencodeClient } from "@opencode-ai/sdk";
5
4
  export const OPENCODE_SDK_PROVIDER = "opencode-sdk";
6
5
  export function parseModel(model) {
7
6
  const slash = model.indexOf("/");
@@ -40,7 +39,7 @@ async function availablePort() {
40
39
  }
41
40
  export async function loadOpencode(execution, cwd, signal, loader) {
42
41
  if (loader) {
43
- const loaded = await loader(cwd);
42
+ const loaded = await loader(cwd, execution);
44
43
  return { client: loaded.client, close: async () => { await loaded.close?.(); } };
45
44
  }
46
45
  const port = await availablePort();
@@ -50,6 +49,7 @@ export async function loadOpencode(execution, cwd, signal, loader) {
50
49
  env: { ...process.env, ...execution.env },
51
50
  log: `${cwd}/.opencode.log`,
52
51
  });
52
+ const { createOpencodeClient } = await import("@opencode-ai/sdk");
53
53
  const client = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}`, directory: cwd });
54
54
  try {
55
55
  await waitReady(client, cwd, signal);
@@ -1,4 +1,4 @@
1
- import { createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager, type CreateAgentSessionOptions } from "@earendil-works/pi-coding-agent";
1
+ import type { createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager, CreateAgentSessionOptions } from "@earendil-works/pi-coding-agent";
2
2
  import type { ProviderExecution } from "../../provider-recipe.js";
3
3
  import { type ProviderAdapter } from "../../provider.js";
4
4
  export type PiSdk = Readonly<{
@@ -1,9 +1,8 @@
1
- import { createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager, } from "@earendil-works/pi-coding-agent";
2
1
  import { abortable } from "../../abort.js";
3
- import { AgentEventChannel } from "../../provider.js";
2
+ import { AKUMA_REQUESTS_ENV, AgentEventChannel, } from "../../provider.js";
4
3
  import { piTerminalFailure, translatePiEvent } from "./events.js";
5
4
  const PI_THINKING_LEVELS = new Set(["minimal", "low", "medium", "high", "xhigh", "max"]);
6
- const MODEL_PATTERN = /^[^/\s]+\/[^/\s]+$/u;
5
+ const MODEL_PATTERN = /^[^/\s]+\/[^\s]+$/u;
7
6
  function diagnostic(error) { return error instanceof Error ? error.message : String(error); }
8
7
  function admitPiOptions(options) {
9
8
  if (options.network !== undefined)
@@ -41,6 +40,14 @@ async function piCreateOptions(sdk, input) {
41
40
  : "sessionFile" in input.session.coordinate
42
41
  ? sdk.SessionManager.open(input.session.coordinate.sessionFile)
43
42
  : (() => { throw new Error("Pi resume requires sessionFile"); })();
43
+ const customTools = input.requests === undefined || input.options.readonly === true
44
+ ? undefined
45
+ : [(await import("@earendil-works/pi-coding-agent")).createBashToolDefinition(input.cwd, {
46
+ spawnHook: (context) => ({
47
+ ...context,
48
+ env: { ...context.env, [AKUMA_REQUESTS_ENV]: input.requests.dir },
49
+ }),
50
+ })];
44
51
  return {
45
52
  cwd: input.cwd,
46
53
  sessionManager,
@@ -48,12 +55,19 @@ async function piCreateOptions(sdk, input) {
48
55
  ...(resourceLoader === undefined ? {} : { resourceLoader }),
49
56
  ...(input.options.effort === undefined ? {} : { thinkingLevel: input.options.effort }),
50
57
  ...(input.options.readonly === undefined ? {} : { tools: ["read", "grep", "find", "ls"] }),
58
+ ...(customTools === undefined ? {} : { customTools }),
51
59
  };
52
60
  }
53
61
  async function createPiSession(sdk, input, signal) {
54
62
  const setup = piCreateOptions(sdk, input).then(async (options) => await sdk.createAgentSession(options));
55
63
  return await abortable(setup, signal, (created) => created.session.dispose());
56
64
  }
65
+ function forceDisposePi(dispose, settle, setAborting) {
66
+ setAborting();
67
+ dispose();
68
+ settle({ kind: "failed", diagnostic: "Pi session force-disposed" });
69
+ return Promise.resolve();
70
+ }
57
71
  async function drivePi(sdk, input, signal) {
58
72
  const created = await createPiSession(sdk, input, signal);
59
73
  const native = created.session;
@@ -147,6 +161,7 @@ async function drivePi(sdk, input, signal) {
147
161
  })();
148
162
  return abortRequest;
149
163
  },
164
+ forceDispose: () => forceDisposePi(dispose, settle, () => { aborting = true; }),
150
165
  };
151
166
  }
152
167
  function piSessionFile(coordinate) {
@@ -162,8 +177,17 @@ async function forkPi(sdk, input) {
162
177
  throw new Error("Pi fork did not create a distinct child session file");
163
178
  return { session: { sessionFile: child } };
164
179
  }
165
- const defaultSdk = { createAgentSession, DefaultResourceLoader, getAgentDir, ModelRuntime, SessionManager };
166
- export function createPiProvider(execution = { name: "pi", kind: "pi" }, load = async () => defaultSdk) {
180
+ async function loadPiSdk() {
181
+ const sdk = await import("@earendil-works/pi-coding-agent");
182
+ return {
183
+ createAgentSession: sdk.createAgentSession,
184
+ DefaultResourceLoader: sdk.DefaultResourceLoader,
185
+ getAgentDir: sdk.getAgentDir,
186
+ ModelRuntime: sdk.ModelRuntime,
187
+ SessionManager: sdk.SessionManager,
188
+ };
189
+ }
190
+ export function createPiProvider(execution = { name: "pi", kind: "pi" }, load = loadPiSdk) {
167
191
  if (execution.executable !== undefined || execution.config !== undefined) {
168
192
  throw new TypeError("Pi provider does not support executable or config");
169
193
  }
@@ -176,7 +200,6 @@ export function createPiProvider(execution = { name: "pi", kind: "pi" }, load =
176
200
  return drivePi(await abortable(load(), signal), input, signal);
177
201
  };
178
202
  return {
179
- confinement: ({ cwd }) => ({ kind: "declared", writableRoots: [cwd] }),
180
203
  admitOptions: admitPiOptions,
181
204
  start: drive,
182
205
  resume: async (input) => {
@@ -0,0 +1,88 @@
1
+ import { type KillEvidence, type Soul } from "./heart/index.js";
2
+ import { type AkuId, type AkumaPaths } from "./identity.js";
3
+ import { type TaskMutationRequest } from "../task/mutation.js";
4
+ export type RequestChildLaunch = Readonly<{
5
+ paths: AkumaPaths;
6
+ seed: Omit<Soul, "createdAt">;
7
+ initialBody: string;
8
+ }>;
9
+ type UpstreamCall = Readonly<{
10
+ signal: AbortSignal;
11
+ }>;
12
+ type RequesterCall = UpstreamCall & Readonly<{
13
+ requester: AkuId;
14
+ }>;
15
+ type ContractCall = RequesterCall & Readonly<{
16
+ repoRoot: string;
17
+ contractId: string;
18
+ }>;
19
+ export type UpstreamExecutionPort = Readonly<{
20
+ wait(input: UpstreamCall & Readonly<{
21
+ targets: readonly AkuId[];
22
+ completion: "any" | "all";
23
+ timeoutMs?: number;
24
+ }>): Promise<unknown>;
25
+ tell(input: UpstreamCall & Readonly<{
26
+ target: AkuId;
27
+ body: string;
28
+ tellId: string;
29
+ recordedAt: string;
30
+ }>): Promise<unknown>;
31
+ kill(input: Readonly<{
32
+ targets: readonly AkuId[];
33
+ signal: AbortSignal;
34
+ }>): Promise<Readonly<{
35
+ result: unknown;
36
+ service: readonly Readonly<{
37
+ id: AkuId;
38
+ evidence: KillEvidence;
39
+ }>[];
40
+ }>>;
41
+ deliver(input: ContractCall & Readonly<{
42
+ message?: string;
43
+ includeDirty: boolean;
44
+ materializeConflict: boolean;
45
+ }>): Promise<Readonly<{
46
+ result: unknown;
47
+ deliveryFactId?: string;
48
+ }>>;
49
+ review(input: ContractCall & Readonly<{
50
+ verdict: "satisfied" | "unsatisfied";
51
+ summary?: string;
52
+ }>): Promise<Readonly<{
53
+ result: unknown;
54
+ reviewFactId?: string;
55
+ }>>;
56
+ task(input: RequesterCall & Readonly<{
57
+ world: string;
58
+ request: TaskMutationRequest;
59
+ }>): Promise<unknown>;
60
+ }>;
61
+ type PumpInput = Readonly<{
62
+ paths: AkumaPaths;
63
+ parent: Soul;
64
+ bodySequence: number;
65
+ now(): string;
66
+ spawn(launch: RequestChildLaunch): Promise<void>;
67
+ upstream?: UpstreamExecutionPort;
68
+ signal: AbortSignal;
69
+ }>;
70
+ export declare class BodyRequestPump {
71
+ private readonly input;
72
+ readonly directory: string;
73
+ readonly failure: Promise<never>;
74
+ private readonly closeSignal;
75
+ private readonly executionSignal;
76
+ private readonly handled;
77
+ private readonly running;
78
+ private readonly cancelBody;
79
+ private admissionClosed;
80
+ private constructor();
81
+ static open(input: PumpInput): Promise<BodyRequestPump>;
82
+ private run;
83
+ close(): Promise<void>;
84
+ stopAdmission(): void;
85
+ }
86
+ export declare function clearBodyRequestTransport(paths: AkumaPaths): Promise<void>;
87
+ export declare function settleBodyRequests(paths: AkumaPaths, parent: Soul, now: () => string, signal?: AbortSignal): Promise<"settled" | "pending">;
88
+ export {};