@astrosheep/keiyaku 4.0.0 → 4.0.2

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 (308) hide show
  1. package/README.md +133 -8
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +13 -5
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -32
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +134 -0
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +262 -46
  12. package/build/src/akuma/abort.d.ts +2 -0
  13. package/build/src/akuma/abort.js +50 -0
  14. package/build/src/akuma/akuma.d.ts +50 -33
  15. package/build/src/akuma/akuma.js +175 -127
  16. package/build/src/akuma/archetype.d.ts +14 -5
  17. package/build/src/akuma/archetype.js +85 -39
  18. package/build/src/akuma/body.d.ts +3 -5
  19. package/build/src/akuma/body.js +490 -183
  20. package/build/src/akuma/coordinate.d.ts +9 -0
  21. package/build/src/akuma/coordinate.js +22 -0
  22. package/build/src/akuma/heart/facts.d.ts +88 -45
  23. package/build/src/akuma/heart/facts.js +19 -8
  24. package/build/src/akuma/heart/index.d.ts +64 -55
  25. package/build/src/akuma/heart/index.js +172 -252
  26. package/build/src/akuma/heart/rows.d.ts +38 -83
  27. package/build/src/akuma/heart/rows.js +117 -155
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +61 -22
  30. package/build/src/akuma/heart/soul.d.ts +8 -0
  31. package/build/src/akuma/heart/soul.js +136 -0
  32. package/build/src/akuma/heart/storage.d.ts +47 -0
  33. package/build/src/akuma/heart/storage.js +224 -0
  34. package/build/src/akuma/heart/tells.d.ts +12 -0
  35. package/build/src/akuma/heart/tells.js +79 -0
  36. package/build/src/akuma/heart/timeline.d.ts +15 -0
  37. package/build/src/akuma/heart/timeline.js +86 -0
  38. package/build/src/akuma/identity.d.ts +2 -2
  39. package/build/src/akuma/identity.js +9 -9
  40. package/build/src/akuma/index.d.ts +10 -3
  41. package/build/src/akuma/index.js +7 -1
  42. package/build/src/akuma/projection.d.ts +176 -0
  43. package/build/src/akuma/projection.js +256 -0
  44. package/build/src/akuma/provider-recipe.d.ts +24 -0
  45. package/build/src/akuma/provider-recipe.js +100 -0
  46. package/build/src/akuma/provider.d.ts +67 -13
  47. package/build/src/akuma/provider.js +172 -105
  48. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  49. package/build/src/akuma/providers/acp/core.js +159 -0
  50. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  51. package/build/src/akuma/providers/acp/events.js +73 -0
  52. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  53. package/build/src/akuma/providers/acp/index.js +94 -0
  54. package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
  55. package/build/src/akuma/providers/claude/events.js +238 -0
  56. package/build/src/akuma/providers/claude/index.d.ts +47 -0
  57. package/build/src/akuma/providers/claude/index.js +279 -0
  58. package/build/src/akuma/providers/claude/input.d.ts +13 -0
  59. package/build/src/akuma/providers/claude/input.js +109 -0
  60. package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
  61. package/build/src/akuma/providers/codex-app-server/events.js +15 -12
  62. package/build/src/akuma/providers/codex-app-server/index.d.ts +15 -13
  63. package/build/src/akuma/providers/codex-app-server/index.js +77 -33
  64. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  65. package/build/src/akuma/providers/grok-build/index.js +70 -0
  66. package/build/src/akuma/providers/index.d.ts +5 -3
  67. package/build/src/akuma/providers/index.js +35 -56
  68. package/build/src/akuma/providers/opencode-sdk/events.d.ts +54 -0
  69. package/build/src/akuma/providers/opencode-sdk/events.js +235 -0
  70. package/build/src/akuma/providers/opencode-sdk/index.d.ts +33 -0
  71. package/build/src/akuma/providers/opencode-sdk/index.js +308 -0
  72. package/build/src/akuma/providers/opencode-sdk/session.d.ts +26 -0
  73. package/build/src/akuma/providers/opencode-sdk/session.js +63 -0
  74. package/build/src/akuma/providers/pi/events.d.ts +33 -0
  75. package/build/src/akuma/providers/pi/events.js +166 -0
  76. package/build/src/akuma/providers/pi/index.d.ts +11 -0
  77. package/build/src/akuma/providers/pi/index.js +191 -0
  78. package/build/src/akuma/publication.d.ts +3 -3
  79. package/build/src/akuma/publication.js +28 -40
  80. package/build/src/akuma/requests.d.ts +9 -6
  81. package/build/src/akuma/requests.js +95 -65
  82. package/build/src/alias/index.d.ts +4 -3
  83. package/build/src/alias/index.js +12 -13
  84. package/build/src/body/decode.js +7 -1
  85. package/build/src/body/region.d.ts +2 -0
  86. package/build/src/body/region.js +77 -7
  87. package/build/src/body/render.js +2 -1
  88. package/build/src/body/shape.js +7 -1
  89. package/build/src/body/verification.js +19 -4
  90. package/build/src/cli/accepted.d.ts +18 -12
  91. package/build/src/cli/accepted.js +73 -34
  92. package/build/src/cli/actor.js +3 -3
  93. package/build/src/cli/commands/akuma-invoke.d.ts +44 -19
  94. package/build/src/cli/commands/akuma-invoke.js +101 -52
  95. package/build/src/cli/commands/akuma.d.ts +27 -9
  96. package/build/src/cli/commands/akuma.js +151 -80
  97. package/build/src/cli/commands/contract.d.ts +155 -0
  98. package/build/src/cli/commands/contract.js +20 -0
  99. package/build/src/cli/commands/install.js +2 -0
  100. package/build/src/cli/commands/task-invoke.d.ts +19 -4
  101. package/build/src/cli/commands/task-invoke.js +65 -17
  102. package/build/src/cli/commands/task-query.d.ts +5 -0
  103. package/build/src/cli/commands/task-query.js +247 -0
  104. package/build/src/cli/commands/task.d.ts +3 -1
  105. package/build/src/cli/commands/task.js +52 -14
  106. package/build/src/cli/coordinates.d.ts +18 -0
  107. package/build/src/cli/coordinates.js +120 -0
  108. package/build/src/cli/draft.d.ts +8 -0
  109. package/build/src/cli/draft.js +96 -0
  110. package/build/src/cli/invoke.d.ts +9 -3
  111. package/build/src/cli/invoke.js +287 -108
  112. package/build/src/cli/main.js +54 -7
  113. package/build/src/cli/parse.d.ts +21 -117
  114. package/build/src/cli/parse.js +79 -84
  115. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  116. package/build/src/cli/render/akuma-tool-command.js +144 -0
  117. package/build/src/cli/render/akuma-tool.d.ts +4 -2
  118. package/build/src/cli/render/akuma-tool.js +35 -5
  119. package/build/src/cli/render/akuma.d.ts +3 -1
  120. package/build/src/cli/render/akuma.js +247 -212
  121. package/build/src/cli/render/audit.d.ts +3 -0
  122. package/build/src/cli/render/audit.js +104 -0
  123. package/build/src/cli/render/catalog.d.ts +2 -0
  124. package/build/src/cli/render/catalog.js +16 -0
  125. package/build/src/cli/render/contract.d.ts +3 -3
  126. package/build/src/cli/render/contract.js +200 -54
  127. package/build/src/cli/render/kanshi.js +272 -129
  128. package/build/src/cli/render/receipt.d.ts +19 -0
  129. package/build/src/cli/render/receipt.js +106 -0
  130. package/build/src/cli/render/refusal.d.ts +16 -2
  131. package/build/src/cli/render/refusal.js +88 -3
  132. package/build/src/cli/render/region.d.ts +2 -0
  133. package/build/src/cli/render/region.js +17 -0
  134. package/build/src/cli/render/task.d.ts +2 -1
  135. package/build/src/cli/render/task.js +223 -60
  136. package/build/src/cli/render/terminal.d.ts +20 -0
  137. package/build/src/cli/render/terminal.js +121 -0
  138. package/build/src/cli/render/text.js +11 -3
  139. package/build/src/cli/result.d.ts +126 -19
  140. package/build/src/cli/usage.d.ts +1 -0
  141. package/build/src/cli/usage.js +3 -0
  142. package/build/src/contract-worktree.d.ts +44 -0
  143. package/build/src/contract-worktree.js +251 -0
  144. package/build/src/coordination/durable-file.d.ts +5 -1
  145. package/build/src/coordination/durable-file.js +57 -10
  146. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  147. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  148. package/build/src/core/facts/codec.js +23 -4
  149. package/build/src/core/facts/eligibility.d.ts +1 -10
  150. package/build/src/core/facts/eligibility.js +0 -49
  151. package/build/src/core/facts/fold.js +1 -6
  152. package/build/src/core/facts/gate.d.ts +1 -0
  153. package/build/src/core/facts/gate.js +1 -0
  154. package/build/src/core/facts/observation.d.ts +3 -0
  155. package/build/src/core/facts/observation.js +12 -0
  156. package/build/src/core/facts/types.d.ts +10 -3
  157. package/build/src/core/subject.js +2 -2
  158. package/build/src/core/verbs/amend.d.ts +1 -1
  159. package/build/src/core/verbs/amend.js +3 -18
  160. package/build/src/core/verbs/bind.js +2 -16
  161. package/build/src/core/verbs/deliver.d.ts +1 -1
  162. package/build/src/core/verbs/deliver.js +14 -4
  163. package/build/src/core/verbs/placement.d.ts +1 -1
  164. package/build/src/core/verbs/placement.js +7 -9
  165. package/build/src/dispatch/index.d.ts +5 -3
  166. package/build/src/dispatch/index.js +30 -21
  167. package/build/src/duration.d.ts +10 -0
  168. package/build/src/duration.js +22 -0
  169. package/build/src/git/admission.d.ts +2 -2
  170. package/build/src/git/admission.js +33 -23
  171. package/build/src/git/hooks.d.ts +15 -0
  172. package/build/src/git/hooks.js +70 -18
  173. package/build/src/git/identity.d.ts +5 -1
  174. package/build/src/git/identity.js +23 -4
  175. package/build/src/git/integration.d.ts +48 -0
  176. package/build/src/git/integration.js +250 -0
  177. package/build/src/git/observe.d.ts +29 -15
  178. package/build/src/git/observe.js +185 -76
  179. package/build/src/git/read-observation.d.ts +41 -0
  180. package/build/src/git/read-observation.js +361 -0
  181. package/build/src/git/reconcile.d.ts +17 -5
  182. package/build/src/git/reconcile.js +305 -109
  183. package/build/src/git/repository.d.ts +41 -18
  184. package/build/src/git/repository.js +220 -114
  185. package/build/src/git/scratch.d.ts +17 -0
  186. package/build/src/git/scratch.js +73 -0
  187. package/build/src/git/target-placement.d.ts +92 -0
  188. package/build/src/git/target-placement.js +375 -0
  189. package/build/src/git/tender.d.ts +49 -0
  190. package/build/src/git/tender.js +63 -0
  191. package/build/src/git/terminal-seal.d.ts +24 -0
  192. package/build/src/git/terminal-seal.js +89 -0
  193. package/build/src/git/tree.d.ts +2 -2
  194. package/build/src/git/tree.js +4 -0
  195. package/build/src/git/workspace.d.ts +53 -0
  196. package/build/src/git/workspace.js +139 -0
  197. package/build/src/identity/selector.d.ts +6 -0
  198. package/build/src/identity/selector.js +19 -0
  199. package/build/src/index.d.ts +4 -2
  200. package/build/src/index.js +2 -1
  201. package/build/src/kanshi/index.d.ts +2 -2
  202. package/build/src/kanshi/index.js +1 -1
  203. package/build/src/kanshi/read.d.ts +7 -3
  204. package/build/src/kanshi/read.js +245 -45
  205. package/build/src/kanshi/report.d.ts +81 -6
  206. package/build/src/kanshi/select.d.ts +5 -0
  207. package/build/src/kanshi/select.js +33 -1
  208. package/build/src/library/address.d.ts +57 -0
  209. package/build/src/library/address.js +165 -0
  210. package/build/src/library/akuma-creation.d.ts +16 -7
  211. package/build/src/library/akuma-creation.js +96 -22
  212. package/build/src/library/audit.d.ts +18 -0
  213. package/build/src/library/audit.js +44 -0
  214. package/build/src/library/bind.d.ts +21 -0
  215. package/build/src/library/bind.js +56 -0
  216. package/build/src/library/catalog.d.ts +58 -0
  217. package/build/src/library/catalog.js +69 -0
  218. package/build/src/library/configuration.d.ts +6 -15
  219. package/build/src/library/configuration.js +14 -17
  220. package/build/src/library/contract.d.ts +23 -49
  221. package/build/src/library/contract.js +171 -185
  222. package/build/src/library/delivery.d.ts +24 -0
  223. package/build/src/library/delivery.js +21 -0
  224. package/build/src/library/fleet.d.ts +65 -0
  225. package/build/src/library/fleet.js +153 -0
  226. package/build/src/library/input.d.ts +3 -0
  227. package/build/src/library/input.js +19 -0
  228. package/build/src/library/keiyaku.d.ts +18 -3
  229. package/build/src/library/keiyaku.js +12 -1
  230. package/build/src/library/mutation.d.ts +39 -0
  231. package/build/src/library/mutation.js +37 -0
  232. package/build/src/library/reconcile.d.ts +29 -0
  233. package/build/src/library/reconcile.js +179 -0
  234. package/build/src/library/refusal.d.ts +21 -0
  235. package/build/src/library/refusal.js +29 -0
  236. package/build/src/library/region.d.ts +14 -1
  237. package/build/src/library/region.js +18 -4
  238. package/build/src/library/repo.d.ts +4 -13
  239. package/build/src/library/repo.js +14 -24
  240. package/build/src/protocol/attempt.d.ts +16 -3
  241. package/build/src/protocol/attempt.js +41 -10
  242. package/build/src/protocol/bind.d.ts +9 -2
  243. package/build/src/protocol/bind.js +48 -40
  244. package/build/src/protocol/intent.d.ts +57 -20
  245. package/build/src/protocol/intent.js +55 -79
  246. package/build/src/protocol/operations.d.ts +152 -43
  247. package/build/src/protocol/operations.js +482 -166
  248. package/build/src/protocol/outcome.d.ts +14 -3
  249. package/build/src/protocol/outcome.js +11 -3
  250. package/build/src/protocol/placement.d.ts +41 -0
  251. package/build/src/protocol/placement.js +147 -0
  252. package/build/src/protocol/read/documents.d.ts +2 -2
  253. package/build/src/protocol/read/documents.js +4 -4
  254. package/build/src/protocol/read/status.d.ts +18 -5
  255. package/build/src/protocol/read/status.js +73 -13
  256. package/build/src/protocol/run.d.ts +49 -7
  257. package/build/src/protocol/run.js +53 -25
  258. package/build/src/runtime/proc/line-rpc.d.ts +4 -8
  259. package/build/src/runtime/proc/line-rpc.js +22 -28
  260. package/build/src/runtime/proc/run.d.ts +23 -21
  261. package/build/src/runtime/proc/run.js +123 -89
  262. package/build/src/runtime/proc/stdio.d.ts +18 -0
  263. package/build/src/runtime/proc/stdio.js +58 -0
  264. package/build/src/settings.d.ts +7 -1
  265. package/build/src/settings.js +32 -17
  266. package/build/src/settlement/fence.d.ts +5 -0
  267. package/build/src/settlement/fence.js +14 -0
  268. package/build/src/settlement/holder.d.ts +35 -4
  269. package/build/src/settlement/holder.js +127 -28
  270. package/build/src/settlement/settle.d.ts +9 -1
  271. package/build/src/settlement/settle.js +74 -37
  272. package/build/src/task/board.d.ts +23 -5
  273. package/build/src/task/board.js +17 -10
  274. package/build/src/task/compose.d.ts +2 -2
  275. package/build/src/task/compose.js +18 -10
  276. package/build/src/task/context.d.ts +3 -3
  277. package/build/src/task/context.js +15 -20
  278. package/build/src/task/document.d.ts +2 -1
  279. package/build/src/task/document.js +15 -5
  280. package/build/src/task/index.d.ts +27 -15
  281. package/build/src/task/index.js +57 -35
  282. package/build/src/task/operations.d.ts +38 -13
  283. package/build/src/task/operations.js +80 -46
  284. package/build/src/task/query.d.ts +67 -0
  285. package/build/src/task/query.js +279 -0
  286. package/build/src/task/store.d.ts +5 -7
  287. package/build/src/task/store.js +43 -28
  288. package/build/src/verification/declaration.d.ts +1 -0
  289. package/build/src/verification/execution.d.ts +51 -0
  290. package/build/src/verification/execution.js +108 -0
  291. package/build/src/workspace-place.d.ts +41 -0
  292. package/build/src/workspace-place.js +386 -0
  293. package/build/src/world.d.ts +24 -0
  294. package/build/src/world.js +136 -0
  295. package/package.json +8 -4
  296. package/build/src/akuma/activity.d.ts +0 -66
  297. package/build/src/akuma/activity.js +0 -139
  298. package/build/src/akuma/providers/claude.js +0 -305
  299. package/build/src/context-root.d.ts +0 -4
  300. package/build/src/context-root.js +0 -15
  301. package/build/src/git/delivery.d.ts +0 -20
  302. package/build/src/git/delivery.js +0 -109
  303. package/build/src/git/verification.d.ts +0 -14
  304. package/build/src/git/verification.js +0 -56
  305. package/build/src/protocol/read/audit.d.ts +0 -25
  306. package/build/src/protocol/read/audit.js +0 -39
  307. package/build/src/verification/producer.d.ts +0 -23
  308. package/build/src/verification/producer.js +0 -54
@@ -0,0 +1,100 @@
1
+ function record(value) {
2
+ return value !== null && typeof value === "object" && !Array.isArray(value)
3
+ ? value
4
+ : null;
5
+ }
6
+ function snapshot(value) {
7
+ if (Array.isArray(value))
8
+ return Object.freeze(value.map(snapshot));
9
+ const object = record(value);
10
+ if (object === null)
11
+ return value;
12
+ return Object.freeze(Object.fromEntries(Object.entries(object).map(([key, item]) => [key, snapshot(item)])));
13
+ }
14
+ function optionText(options, field, blank) {
15
+ const selected = options[field];
16
+ if (selected === undefined)
17
+ return undefined;
18
+ if (typeof selected !== "string" || (blank === "refuse" && selected.trim().length === 0)) {
19
+ throw new TypeError(`provider option ${field} must be ${blank === "allow" ? "a string" : "a nonblank string"}`);
20
+ }
21
+ return selected;
22
+ }
23
+ export function decodeProviderOptions(value) {
24
+ const options = record(value);
25
+ if (options === null)
26
+ throw new TypeError("provider options must be an object");
27
+ const allowed = ["effort", "model", "network", "readonly", "systemPrompt"];
28
+ const unknown = Object.keys(options).find((key) => !allowed.includes(key));
29
+ if (unknown !== undefined)
30
+ throw new TypeError(`provider options have unknown field ${unknown}`);
31
+ const model = optionText(options, "model", "refuse");
32
+ const effort = optionText(options, "effort", "refuse");
33
+ if (options.readonly !== undefined && options.readonly !== true) {
34
+ throw new TypeError("provider option readonly must be true");
35
+ }
36
+ const network = options.network;
37
+ if (network !== undefined && network !== "disabled" && network !== "enabled") {
38
+ throw new TypeError("provider option network must be disabled, enabled");
39
+ }
40
+ const systemPrompt = optionText(options, "systemPrompt", "allow");
41
+ return Object.freeze({
42
+ ...(model === undefined ? {} : { model }),
43
+ ...(effort === undefined ? {} : { effort }),
44
+ ...(options.readonly === undefined ? {} : { readonly: true }),
45
+ ...(network === undefined ? {} : { network }),
46
+ ...(systemPrompt === undefined ? {} : { systemPrompt }),
47
+ });
48
+ }
49
+ export function decodeReadonlyRestraint(value) {
50
+ const restraint = record(value);
51
+ if (restraint === null)
52
+ throw new TypeError("readonly restraint must be an object");
53
+ const keys = Object.keys(restraint).sort();
54
+ if (restraint.enforcement === "native" && keys.length === 1 && keys[0] === "enforcement") {
55
+ return Object.freeze({ enforcement: "native" });
56
+ }
57
+ if (restraint.enforcement === "none"
58
+ && keys.length === 2 && keys[0] === "diagnostic" && keys[1] === "enforcement"
59
+ && typeof restraint.diagnostic === "string" && restraint.diagnostic.trim().length > 0) {
60
+ return Object.freeze({ enforcement: "none", diagnostic: restraint.diagnostic });
61
+ }
62
+ throw new TypeError("readonly restraint must be native or none with a diagnostic");
63
+ }
64
+ function providerKind(value) {
65
+ return value === "acp" || value === "claude-agent-sdk" || value === "codex-app-server" || value === "grok-build"
66
+ || value === "opencode-sdk" || value === "pi";
67
+ }
68
+ export function decodeProviderRecipe(input) {
69
+ const value = record(input);
70
+ if (value === null)
71
+ throw new TypeError("provider execution must be an object");
72
+ const allowed = ["config", "env", "executable", "kind", "name"];
73
+ const unknown = Object.keys(value).find((key) => !allowed.includes(key));
74
+ if (unknown !== undefined)
75
+ throw new TypeError(`provider execution has unknown field ${unknown}`);
76
+ if (typeof value.name !== "string" || value.name.trim().length === 0) {
77
+ throw new TypeError("provider execution name must be a nonblank string");
78
+ }
79
+ if (!providerKind(value.kind))
80
+ throw new TypeError("provider execution has unknown kind");
81
+ if (value.executable !== undefined && (typeof value.executable !== "string" || value.executable.trim().length === 0)) {
82
+ throw new TypeError("provider execution executable must be a nonblank string");
83
+ }
84
+ const config = value.config === undefined ? undefined : record(value.config);
85
+ if (config === null)
86
+ throw new TypeError("provider execution config must be an object");
87
+ const env = value.env === undefined ? undefined : record(value.env);
88
+ if (env === null)
89
+ throw new TypeError("provider execution env must be an object");
90
+ if (env !== undefined && Object.values(env).some((item) => typeof item !== "string")) {
91
+ throw new TypeError("provider execution env must contain only string values");
92
+ }
93
+ return Object.freeze({
94
+ name: value.name,
95
+ kind: value.kind,
96
+ ...(value.executable === undefined ? {} : { executable: value.executable }),
97
+ ...(config === undefined ? {} : { config: snapshot(config) }),
98
+ ...(env === undefined ? {} : { env: Object.freeze({ ...env }) }),
99
+ });
100
+ }
@@ -1,17 +1,25 @@
1
- import type { Confinement, ProviderOptions, ResumeCoordinate } from "./heart/index.js";
2
- export type { ProviderOptions, ResumeCoordinate } from "./heart/index.js";
1
+ import type { Confinement } from "./heart/index.js";
2
+ import { decodeResumeCoordinate, encodeResumeCoordinate, type ResumeCoordinate } from "./coordinate.js";
3
+ import type { ProviderOptions, ReadonlyRestraint } from "./provider-recipe.js";
4
+ export type { ResumeCoordinate } from "./coordinate.js";
3
5
  export declare const AKUMA_REQUESTS_ENV = "AKUMA_REQUESTS";
4
6
  export declare const AGENT_EVENT_TEXT_LIMIT = 16384;
5
7
  export declare const AGENT_THOUGHT_TEXT_LIMIT = 4000;
8
+ export type SearchScope = "content" | "files" | "web";
6
9
  export type ToolCall = Readonly<{
7
10
  kind: "run";
8
11
  command: string;
9
12
  }> | Readonly<{
10
13
  kind: "read";
11
14
  path: string;
15
+ offset?: number;
16
+ limit?: number;
12
17
  }> | Readonly<{
13
18
  kind: "search";
14
19
  query: string;
20
+ scope?: SearchScope;
21
+ path?: string;
22
+ glob?: string;
15
23
  }> | Readonly<{
16
24
  kind: "fileChange";
17
25
  changes: readonly Readonly<{
@@ -36,6 +44,7 @@ export type ToolEvent = Readonly<{
36
44
  id: string;
37
45
  name: string;
38
46
  call: ToolCall;
47
+ truncated?: true;
39
48
  }> & (Readonly<{
40
49
  phase: "started";
41
50
  result?: never;
@@ -49,17 +58,21 @@ export type AgentEvent = Readonly<{
49
58
  }> | Readonly<{
50
59
  type: "assistant";
51
60
  text: string;
61
+ truncated?: true;
52
62
  }> | Readonly<{
53
63
  type: "thought";
54
64
  text: string;
65
+ truncated?: true;
55
66
  }> | ToolEvent | Readonly<{
56
67
  type: "note";
57
68
  text: string;
69
+ truncated?: true;
58
70
  }> | Readonly<{
59
71
  type: "unknown";
60
72
  kind: string;
73
+ truncated?: true;
61
74
  }>;
62
- export declare function decodeProviderOptions(value: unknown): ProviderOptions;
75
+ export { decodeResumeCoordinate, encodeResumeCoordinate };
63
76
  export declare function decodeAgentEvent(value: unknown): AgentEvent;
64
77
  export declare function encodeAgentEvent(event: AgentEvent): unknown;
65
78
  export declare function boundedEventText(value: string): string;
@@ -81,19 +94,58 @@ export declare class AgentEventChannel implements AsyncIterable<AgentEvent> {
81
94
  export type TurnResult = Readonly<{
82
95
  kind: "answered";
83
96
  answer: string;
84
- historyId: string;
97
+ historyId?: string;
85
98
  }> | Readonly<{
86
99
  kind: "failed";
87
100
  diagnostic: string;
88
101
  }>;
89
- export type Drive = Readonly<{
102
+ export type ProviderFence = string;
103
+ export type TellReceipt = Readonly<{
104
+ evidence: "exact";
105
+ tellId: string;
106
+ kind: string;
107
+ }> | Readonly<{
108
+ evidence: "fence";
109
+ fence: ProviderFence;
110
+ kind: string;
111
+ }>;
112
+ export type TellSubmission = Readonly<{
113
+ kind: "accepted";
114
+ fence: ProviderFence;
115
+ }> | Readonly<{
116
+ kind: "turn-ended";
117
+ }>;
118
+ export type Session = Readonly<{
119
+ admission: Readonly<{
120
+ fence: ProviderFence;
121
+ }>;
90
122
  events: AsyncIterable<AgentEvent>;
123
+ receipts?: AsyncIterable<TellReceipt>;
91
124
  completion: Promise<TurnResult>;
125
+ /** Fulfills after every adapter-owned OS child or native session is disposed. */
92
126
  abort(): Promise<void>;
127
+ tell?(tell: Readonly<{
128
+ id: string;
129
+ text: string;
130
+ }>): Promise<TellSubmission>;
131
+ }>;
132
+ export type DriveInput = Readonly<{
133
+ body: string;
134
+ launchTells: readonly Readonly<{
135
+ id: string;
136
+ text: string;
137
+ }>[];
138
+ cwd: string;
139
+ options: ProviderOptions;
140
+ signal: AbortSignal;
141
+ requests?: Readonly<{
142
+ dir: string;
143
+ }>;
93
144
  }>;
94
145
  export type ProviderOptionAdmission = Readonly<{
95
146
  kind: "admitted";
96
147
  options: ProviderOptions;
148
+ readonly?: ReadonlyRestraint;
97
149
  }> | Readonly<{
98
150
  kind: "refused";
99
151
  diagnostic: string;
@@ -111,13 +163,15 @@ export type ProviderAdapter = Readonly<{
111
163
  }>): Promise<Readonly<{
112
164
  session: ResumeCoordinate;
113
165
  }>>;
114
- start(input: Readonly<{
115
- prompt: string;
116
- cwd: string;
117
- options: ProviderOptions;
118
- session?: ResumeCoordinate;
119
- requests?: Readonly<{
120
- dir: string;
166
+ start(input: DriveInput & Readonly<{
167
+ session: Readonly<{
168
+ kind: "fresh";
169
+ }>;
170
+ }>): Promise<Session>;
171
+ resume?(input: DriveInput & Readonly<{
172
+ session: Readonly<{
173
+ kind: "resume";
174
+ coordinate: ResumeCoordinate;
121
175
  }>;
122
- }>): Promise<Drive>;
176
+ }>): Promise<Session>;
123
177
  }>;
@@ -1,3 +1,4 @@
1
+ import { decodeResumeCoordinate, encodeResumeCoordinate } from "./coordinate.js";
1
2
  export const AKUMA_REQUESTS_ENV = "AKUMA_REQUESTS";
2
3
  export const AGENT_EVENT_TEXT_LIMIT = 16_384;
3
4
  export const AGENT_THOUGHT_TEXT_LIMIT = 4_000;
@@ -14,82 +15,111 @@ function object(value) {
14
15
  ? value
15
16
  : null;
16
17
  }
17
- function optionText(options, field, blank) {
18
- const selected = options[field];
19
- if (selected === undefined)
18
+ export { decodeResumeCoordinate, encodeResumeCoordinate };
19
+ function eventType(value) {
20
+ return typeof value === "string" && Object.hasOwn(AGENT_EVENT_TYPES, value);
21
+ }
22
+ const SEARCH_SCOPES = {
23
+ content: true,
24
+ files: true,
25
+ web: true,
26
+ };
27
+ function decodePositiveLine(value) {
28
+ if (value === undefined)
20
29
  return undefined;
21
- if (typeof selected !== "string" || (blank === "refuse" && selected.trim().length === 0)) {
22
- throw new TypeError(`provider option ${field} must be ${blank === "allow" ? "a string" : "a nonblank string"}`);
23
- }
24
- return selected;
30
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 1 ? value : null;
25
31
  }
26
- function optionEnum(options, field, allowed) {
27
- const selected = options[field];
28
- if (selected === undefined)
32
+ function decodeOptionalText(value) {
33
+ if (value === undefined)
29
34
  return undefined;
30
- if (typeof selected !== "string" || !allowed.includes(selected)) {
31
- throw new TypeError(`provider option ${field} must be ${allowed.join(", ")}`);
32
- }
33
- return selected;
34
- }
35
- export function decodeProviderOptions(value) {
36
- const options = object(value);
37
- if (options === null)
38
- throw new TypeError("provider options must be an object");
39
- const allowed = ["access", "effort", "model", "network", "systemPrompt"];
40
- const unknown = Object.keys(options).find((key) => !allowed.includes(key));
41
- if (unknown !== undefined)
42
- throw new TypeError(`provider options have unknown field ${unknown}`);
43
- const model = optionText(options, "model", "refuse");
44
- const effort = optionText(options, "effort", "refuse");
45
- const access = optionEnum(options, "access", ["read", "write", "auto"]);
46
- const network = optionEnum(options, "network", ["disabled", "enabled"]);
47
- const systemPrompt = optionText(options, "systemPrompt", "allow");
48
- return Object.freeze({
49
- ...(model === undefined ? {} : { model }),
50
- ...(effort === undefined ? {} : { effort }),
51
- ...(access === undefined ? {} : { access }),
52
- ...(network === undefined ? {} : { network }),
53
- ...(systemPrompt === undefined ? {} : { systemPrompt }),
54
- });
35
+ return typeof value === "string" ? value : null;
55
36
  }
56
- function eventType(value) {
57
- return typeof value === "string" && Object.hasOwn(AGENT_EVENT_TYPES, value);
37
+ function decodeSearchScope(value) {
38
+ if (value === undefined)
39
+ return undefined;
40
+ return typeof value === "string" && Object.hasOwn(SEARCH_SCOPES, value) ? value : null;
41
+ }
42
+ function decodeRunCall(call) {
43
+ return typeof call.command === "string" ? { kind: "run", command: call.command } : null;
44
+ }
45
+ function decodeReadCall(call) {
46
+ if (typeof call.path !== "string")
47
+ return null;
48
+ const offset = decodePositiveLine(call.offset);
49
+ const limit = decodePositiveLine(call.limit);
50
+ if (offset === null || limit === null)
51
+ return null;
52
+ return {
53
+ kind: "read",
54
+ path: call.path,
55
+ ...(offset === undefined ? {} : { offset }),
56
+ ...(limit === undefined ? {} : { limit }),
57
+ };
58
+ }
59
+ function decodeSearchCall(call) {
60
+ if (typeof call.query !== "string")
61
+ return null;
62
+ const scope = decodeSearchScope(call.scope);
63
+ const path = decodeOptionalText(call.path);
64
+ const glob = decodeOptionalText(call.glob);
65
+ if (scope === null || path === null || glob === null)
66
+ return null;
67
+ return {
68
+ kind: "search",
69
+ query: call.query,
70
+ ...(scope === undefined ? {} : { scope }),
71
+ ...(path === undefined ? {} : { path }),
72
+ ...(glob === undefined ? {} : { glob }),
73
+ };
74
+ }
75
+ function decodeNonnegativeCount(value) {
76
+ return Number.isSafeInteger(value) && value >= 0 ? value : null;
77
+ }
78
+ function decodeDiffstat(value) {
79
+ if (value === undefined)
80
+ return undefined;
81
+ const diffstat = object(value);
82
+ if (diffstat === null)
83
+ return null;
84
+ const added = decodeNonnegativeCount(diffstat.added);
85
+ const removed = decodeNonnegativeCount(diffstat.removed);
86
+ return added === null || removed === null ? null : { added, removed };
87
+ }
88
+ function decodeFileChangeMember(value) {
89
+ const change = object(value);
90
+ if (change === null || (change.op !== "add" && change.op !== "update" && change.op !== "delete")
91
+ || typeof change.path !== "string")
92
+ return null;
93
+ const diffstat = decodeDiffstat(change.diffstat);
94
+ if (diffstat === null)
95
+ return null;
96
+ return {
97
+ op: change.op,
98
+ path: change.path,
99
+ ...(diffstat === undefined ? {} : { diffstat }),
100
+ };
101
+ }
102
+ function decodeFileChangeCall(call) {
103
+ if (!Array.isArray(call.changes))
104
+ return null;
105
+ const changes = call.changes.map(decodeFileChangeMember);
106
+ return changes.every((change) => change !== null) ? { kind: "fileChange", changes } : null;
107
+ }
108
+ function decodeOtherCall(call) {
109
+ return typeof call.display === "string" ? { kind: "other", display: call.display } : null;
58
110
  }
59
111
  function decodeToolCall(value) {
60
112
  const call = object(value);
61
- if (call?.kind === "run" && typeof call.command === "string")
62
- return { kind: "run", command: call.command };
63
- if (call?.kind === "read" && typeof call.path === "string")
64
- return { kind: "read", path: call.path };
65
- if (call?.kind === "search" && typeof call.query === "string")
66
- return { kind: "search", query: call.query };
67
- if (call?.kind === "fileChange" && Array.isArray(call.changes)) {
68
- const changes = call.changes.map((value) => {
69
- const change = object(value);
70
- if (change === null || (change.op !== "add" && change.op !== "update" && change.op !== "delete")
71
- || typeof change.path !== "string")
72
- return null;
73
- const rawDiffstat = change.diffstat;
74
- const op = change.op;
75
- if (rawDiffstat === undefined)
76
- return { op, path: change.path };
77
- const diffstat = object(rawDiffstat);
78
- if (diffstat === null || !Number.isSafeInteger(diffstat.added) || !Number.isSafeInteger(diffstat.removed)
79
- || diffstat.added < 0 || diffstat.removed < 0)
80
- return null;
81
- return {
82
- op,
83
- path: change.path,
84
- diffstat: { added: diffstat.added, removed: diffstat.removed },
85
- };
86
- });
87
- if (changes.every((change) => change !== null))
88
- return { kind: "fileChange", changes };
113
+ if (call === null)
114
+ return null;
115
+ switch (call.kind) {
116
+ case "run": return decodeRunCall(call);
117
+ case "read": return decodeReadCall(call);
118
+ case "search": return decodeSearchCall(call);
119
+ case "fileChange": return decodeFileChangeCall(call);
120
+ case "other": return decodeOtherCall(call);
121
+ default: return null;
89
122
  }
90
- if (call?.kind === "other" && typeof call.display === "string")
91
- return { kind: "other", display: call.display };
92
- return null;
93
123
  }
94
124
  function decodeToolResult(value) {
95
125
  const result = object(value);
@@ -106,27 +136,34 @@ function decodeToolResult(value) {
106
136
  };
107
137
  }
108
138
  function decodeToolEvent(event) {
139
+ if (event.truncated !== undefined && event.truncated !== true)
140
+ return null;
109
141
  if (typeof event.id !== "string" || typeof event.name !== "string")
110
142
  return null;
111
143
  const call = decodeToolCall(event.call);
112
144
  if (call !== null && event.phase === "started" && event.result === undefined) {
113
- return { type: "tool", phase: "started", id: event.id, name: event.name, call };
145
+ return { type: "tool", phase: "started", id: event.id, name: event.name, call,
146
+ ...(event.truncated === true ? { truncated: true } : {}) };
114
147
  }
115
148
  const result = decodeToolResult(event.result);
116
149
  if (call !== null && event.phase === "completed" && result !== null) {
117
- return { type: "tool", phase: "completed", id: event.id, name: event.name, call, result };
150
+ return { type: "tool", phase: "completed", id: event.id, name: event.name, call, result,
151
+ ...(event.truncated === true ? { truncated: true } : {}) };
118
152
  }
119
153
  return null;
120
154
  }
121
155
  function decodeTypedEvent(type, event) {
156
+ if (type !== "session" && event.truncated !== undefined && event.truncated !== true)
157
+ return null;
158
+ const truncated = event.truncated === true ? { truncated: true } : {};
122
159
  switch (type) {
123
160
  case "assistant":
124
- case "thought": return typeof event.text === "string" ? { type, text: event.text } : null;
125
- case "note": return typeof event.text === "string" ? { type, text: event.text } : null;
126
- case "unknown": return typeof event.kind === "string" ? { type, kind: event.kind } : null;
161
+ case "thought": return typeof event.text === "string" ? { type, text: event.text, ...truncated } : null;
162
+ case "note": return typeof event.text === "string" ? { type, text: event.text, ...truncated } : null;
163
+ case "unknown": return typeof event.kind === "string" ? { type, kind: event.kind, ...truncated } : null;
127
164
  case "session": {
128
- const coordinate = object(event.coordinate);
129
- return typeof coordinate?.sessionId === "string" ? { type, coordinate: { sessionId: coordinate.sessionId } } : null;
165
+ const coordinate = decodeResumeCoordinate(event.coordinate);
166
+ return coordinate === null ? null : { type, coordinate };
130
167
  }
131
168
  case "tool": return decodeToolEvent(event);
132
169
  default: return type;
@@ -143,50 +180,80 @@ export function decodeAgentEvent(value) {
143
180
  }
144
181
  function boundedToolCall(call) {
145
182
  switch (call.kind) {
146
- case "run": return { kind: call.kind, command: boundedEventText(call.command) };
147
- case "read": return { kind: call.kind, path: boundedEventText(call.path) };
148
- case "search": return { kind: call.kind, query: boundedEventText(call.query) };
183
+ case "run": return { value: { kind: call.kind, command: boundedEventText(call.command) }, truncated: call.command.length > AGENT_EVENT_TEXT_LIMIT };
184
+ case "read": return {
185
+ value: {
186
+ kind: call.kind,
187
+ path: boundedEventText(call.path),
188
+ ...(call.offset === undefined ? {} : { offset: call.offset }),
189
+ ...(call.limit === undefined ? {} : { limit: call.limit }),
190
+ },
191
+ truncated: call.path.length > AGENT_EVENT_TEXT_LIMIT,
192
+ };
193
+ case "search": return {
194
+ value: {
195
+ kind: call.kind,
196
+ query: boundedEventText(call.query),
197
+ ...(call.scope === undefined ? {} : { scope: call.scope }),
198
+ ...(call.path === undefined ? {} : { path: boundedEventText(call.path) }),
199
+ ...(call.glob === undefined ? {} : { glob: boundedEventText(call.glob) }),
200
+ },
201
+ truncated: call.query.length > AGENT_EVENT_TEXT_LIMIT
202
+ || (call.path !== undefined && call.path.length > AGENT_EVENT_TEXT_LIMIT)
203
+ || (call.glob !== undefined && call.glob.length > AGENT_EVENT_TEXT_LIMIT),
204
+ };
149
205
  case "fileChange": return {
150
- kind: call.kind,
151
- changes: call.changes.map((change) => ({
152
- ...change,
153
- path: boundedEventText(change.path),
154
- })),
206
+ value: {
207
+ kind: call.kind,
208
+ changes: call.changes.map((change) => ({ ...change, path: boundedEventText(change.path) })),
209
+ },
210
+ truncated: call.changes.some((change) => change.path.length > AGENT_EVENT_TEXT_LIMIT),
155
211
  };
156
- case "other": return { kind: call.kind, display: boundedEventText(call.display) };
212
+ case "other": return { value: { kind: call.kind, display: boundedEventText(call.display) }, truncated: call.display.length > AGENT_EVENT_TEXT_LIMIT };
157
213
  default: return call;
158
214
  }
159
215
  }
160
216
  function boundedToolResult(result) {
161
217
  return {
162
- status: result.status,
163
- ...(result.message === undefined ? {} : { message: boundedEventText(result.message) }),
164
- ...(result.exitCode === undefined ? {} : { exitCode: result.exitCode }),
218
+ value: {
219
+ status: result.status,
220
+ ...(result.message === undefined ? {} : { message: boundedEventText(result.message) }),
221
+ ...(result.exitCode === undefined ? {} : { exitCode: result.exitCode }),
222
+ },
223
+ truncated: result.message !== undefined && result.message.length > AGENT_EVENT_TEXT_LIMIT,
165
224
  };
166
225
  }
167
226
  export function encodeAgentEvent(event) {
227
+ const marked = (value, changed) => ({
228
+ ...value,
229
+ ...(changed || ("truncated" in event && event.truncated === true) ? { truncated: true } : {}),
230
+ });
168
231
  switch (event.type) {
169
- case "session": return { type: event.type, coordinate: { sessionId: event.coordinate.sessionId } };
170
- case "assistant": return { type: event.type, text: boundedEventText(event.text) };
171
- case "thought": return { type: event.type, text: boundedThoughtText(event.text) };
172
- case "note": return { type: event.type, text: boundedEventText(event.text) };
173
- case "unknown": return { type: event.type, kind: boundedEventText(event.kind) };
174
- case "tool": return event.phase === "started"
175
- ? {
232
+ case "session": return { type: event.type, coordinate: encodeResumeCoordinate(event.coordinate) };
233
+ case "assistant": return marked({ type: event.type, text: boundedEventText(event.text) }, event.text.length > AGENT_EVENT_TEXT_LIMIT);
234
+ case "thought": return marked({ type: event.type, text: boundedThoughtText(event.text) }, event.text.length > AGENT_THOUGHT_TEXT_LIMIT);
235
+ case "note": return marked({ type: event.type, text: boundedEventText(event.text) }, event.text.length > AGENT_EVENT_TEXT_LIMIT);
236
+ case "unknown": return marked({ type: event.type, kind: boundedEventText(event.kind) }, event.kind.length > AGENT_EVENT_TEXT_LIMIT);
237
+ case "tool": {
238
+ const call = boundedToolCall(event.call);
239
+ const name = boundedEventText(event.name);
240
+ const result = event.phase === "completed" ? boundedToolResult(event.result) : undefined;
241
+ return marked(event.phase === "started" ? {
176
242
  type: event.type,
177
243
  id: event.id,
178
244
  phase: event.phase,
179
- name: boundedEventText(event.name),
180
- call: boundedToolCall(event.call),
245
+ name,
246
+ call: call.value,
181
247
  }
182
- : {
183
- type: event.type,
184
- id: event.id,
185
- phase: event.phase,
186
- name: boundedEventText(event.name),
187
- call: boundedToolCall(event.call),
188
- result: boundedToolResult(event.result),
189
- };
248
+ : {
249
+ type: event.type,
250
+ id: event.id,
251
+ phase: event.phase,
252
+ name,
253
+ call: call.value,
254
+ result: result.value,
255
+ }, name !== event.name || call.truncated || result?.truncated === true);
256
+ }
190
257
  default: return event;
191
258
  }
192
259
  }
@@ -197,7 +264,7 @@ export function boundedThoughtText(value) {
197
264
  return value.slice(0, AGENT_THOUGHT_TEXT_LIMIT);
198
265
  }
199
266
  export function noteEvent(note) {
200
- return { type: "note", text: boundedEventText(note.replace(/\s+/g, " ").trim()) };
267
+ return { type: "note", text: note.replace(/\s+/g, " ").trim() };
201
268
  }
202
269
  export function unknownEvent(kind) {
203
270
  return { type: "unknown", kind };
@@ -0,0 +1,19 @@
1
+ import * as acp from "@agentclientprotocol/sdk";
2
+ import { spawnStdioProcess } from "../../../runtime/proc/stdio.js";
3
+ import { type ProviderAdapter, type Session } from "../../provider.js";
4
+ export type AcpStartInput = Parameters<ProviderAdapter["start"]>[0] | Parameters<NonNullable<ProviderAdapter["resume"]>>[0];
5
+ export type AcpDependencies = Readonly<{
6
+ spawnProcess?: typeof spawnStdioProcess;
7
+ }>;
8
+ export type AcpLiveSession = Readonly<{
9
+ session: Session;
10
+ agent: acp.ClientContext;
11
+ sessionId: string;
12
+ open(): boolean;
13
+ }>;
14
+ type AcpLaunch = Readonly<{
15
+ argv: readonly [string, ...string[]];
16
+ env?: Readonly<Record<string, string>>;
17
+ }>;
18
+ export declare function startAcpSession(launch: AcpLaunch, input: AcpStartInput, dependencies?: AcpDependencies): Promise<AcpLiveSession>;
19
+ export {};