@astrosheep/keiyaku 4.0.1 → 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 (245) hide show
  1. package/README.md +137 -5
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
  9. package/build/src/akuma/abort.d.ts +2 -0
  10. package/build/src/akuma/abort.js +50 -0
  11. package/build/src/akuma/akuma.d.ts +23 -14
  12. package/build/src/akuma/akuma.js +120 -104
  13. package/build/src/akuma/archetype.d.ts +7 -6
  14. package/build/src/akuma/archetype.js +68 -41
  15. package/build/src/akuma/body.d.ts +3 -5
  16. package/build/src/akuma/body.js +408 -213
  17. package/build/src/akuma/heart/facts.d.ts +25 -34
  18. package/build/src/akuma/heart/facts.js +18 -7
  19. package/build/src/akuma/heart/index.d.ts +39 -42
  20. package/build/src/akuma/heart/index.js +134 -93
  21. package/build/src/akuma/heart/rows.d.ts +9 -31
  22. package/build/src/akuma/heart/rows.js +26 -44
  23. package/build/src/akuma/heart/schema.d.ts +1 -1
  24. package/build/src/akuma/heart/schema.js +7 -15
  25. package/build/src/akuma/heart/soul.d.ts +8 -0
  26. package/build/src/akuma/heart/soul.js +136 -0
  27. package/build/src/akuma/heart/storage.d.ts +28 -14
  28. package/build/src/akuma/heart/storage.js +86 -26
  29. package/build/src/akuma/identity.d.ts +2 -2
  30. package/build/src/akuma/identity.js +9 -9
  31. package/build/src/akuma/index.d.ts +6 -1
  32. package/build/src/akuma/index.js +6 -0
  33. package/build/src/akuma/projection.d.ts +117 -38
  34. package/build/src/akuma/projection.js +208 -97
  35. package/build/src/akuma/provider-recipe.d.ts +24 -0
  36. package/build/src/akuma/provider-recipe.js +100 -0
  37. package/build/src/akuma/provider.d.ts +12 -4
  38. package/build/src/akuma/provider.js +117 -70
  39. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  40. package/build/src/akuma/providers/acp/core.js +159 -0
  41. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  42. package/build/src/akuma/providers/acp/events.js +73 -0
  43. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  44. package/build/src/akuma/providers/acp/index.js +94 -0
  45. package/build/src/akuma/providers/claude/events.js +66 -13
  46. package/build/src/akuma/providers/claude/index.d.ts +2 -1
  47. package/build/src/akuma/providers/claude/index.js +35 -21
  48. package/build/src/akuma/providers/codex-app-server/events.js +4 -1
  49. package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
  50. package/build/src/akuma/providers/codex-app-server/index.js +24 -31
  51. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  52. package/build/src/akuma/providers/grok-build/index.js +70 -0
  53. package/build/src/akuma/providers/index.d.ts +5 -3
  54. package/build/src/akuma/providers/index.js +24 -59
  55. package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
  56. package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
  57. package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
  58. package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
  59. package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
  60. package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
  61. package/build/src/akuma/providers/pi/events.js +49 -11
  62. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  63. package/build/src/akuma/providers/pi/index.js +50 -21
  64. package/build/src/akuma/publication.d.ts +3 -3
  65. package/build/src/akuma/publication.js +28 -40
  66. package/build/src/akuma/requests.d.ts +9 -7
  67. package/build/src/akuma/requests.js +92 -65
  68. package/build/src/alias/index.d.ts +2 -2
  69. package/build/src/alias/index.js +10 -10
  70. package/build/src/body/decode.js +7 -1
  71. package/build/src/body/region.d.ts +2 -0
  72. package/build/src/body/region.js +77 -7
  73. package/build/src/cli/accepted.d.ts +17 -13
  74. package/build/src/cli/accepted.js +72 -34
  75. package/build/src/cli/actor.js +3 -3
  76. package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
  77. package/build/src/cli/commands/akuma-invoke.js +14 -9
  78. package/build/src/cli/commands/akuma.d.ts +13 -3
  79. package/build/src/cli/commands/akuma.js +67 -34
  80. package/build/src/cli/commands/contract.d.ts +18 -5
  81. package/build/src/cli/commands/contract.js +9 -3
  82. package/build/src/cli/commands/task-invoke.d.ts +17 -4
  83. package/build/src/cli/commands/task-invoke.js +43 -20
  84. package/build/src/cli/commands/task-query.d.ts +5 -0
  85. package/build/src/cli/commands/task-query.js +247 -0
  86. package/build/src/cli/commands/task.d.ts +3 -1
  87. package/build/src/cli/commands/task.js +51 -13
  88. package/build/src/cli/coordinates.d.ts +18 -0
  89. package/build/src/cli/coordinates.js +120 -0
  90. package/build/src/cli/draft.d.ts +8 -0
  91. package/build/src/cli/draft.js +96 -0
  92. package/build/src/cli/invoke.d.ts +4 -3
  93. package/build/src/cli/invoke.js +160 -179
  94. package/build/src/cli/main.js +34 -6
  95. package/build/src/cli/parse.d.ts +9 -2
  96. package/build/src/cli/parse.js +29 -7
  97. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  98. package/build/src/cli/render/akuma-tool-command.js +144 -0
  99. package/build/src/cli/render/akuma-tool.d.ts +2 -2
  100. package/build/src/cli/render/akuma-tool.js +30 -4
  101. package/build/src/cli/render/akuma.d.ts +1 -0
  102. package/build/src/cli/render/akuma.js +211 -116
  103. package/build/src/cli/render/audit.d.ts +3 -0
  104. package/build/src/cli/render/audit.js +104 -0
  105. package/build/src/cli/render/contract.d.ts +3 -3
  106. package/build/src/cli/render/contract.js +192 -79
  107. package/build/src/cli/render/kanshi.js +263 -168
  108. package/build/src/cli/render/receipt.d.ts +19 -0
  109. package/build/src/cli/render/receipt.js +106 -0
  110. package/build/src/cli/render/refusal.d.ts +16 -2
  111. package/build/src/cli/render/refusal.js +88 -20
  112. package/build/src/cli/render/region.d.ts +2 -0
  113. package/build/src/cli/render/region.js +17 -0
  114. package/build/src/cli/render/task.d.ts +2 -1
  115. package/build/src/cli/render/task.js +223 -60
  116. package/build/src/cli/render/terminal.d.ts +7 -0
  117. package/build/src/cli/render/terminal.js +46 -0
  118. package/build/src/cli/render/text.js +6 -3
  119. package/build/src/cli/result.d.ts +115 -20
  120. package/build/src/cli/usage.d.ts +1 -0
  121. package/build/src/cli/usage.js +3 -0
  122. package/build/src/contract-worktree.d.ts +6 -5
  123. package/build/src/contract-worktree.js +95 -57
  124. package/build/src/coordination/durable-file.d.ts +4 -3
  125. package/build/src/coordination/durable-file.js +29 -25
  126. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  127. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  128. package/build/src/core/facts/fold.js +1 -6
  129. package/build/src/core/facts/gate.d.ts +1 -0
  130. package/build/src/core/facts/gate.js +1 -0
  131. package/build/src/core/verbs/amend.d.ts +1 -1
  132. package/build/src/core/verbs/amend.js +0 -11
  133. package/build/src/core/verbs/deliver.d.ts +1 -1
  134. package/build/src/core/verbs/deliver.js +1 -7
  135. package/build/src/core/verbs/placement.d.ts +1 -1
  136. package/build/src/core/verbs/placement.js +4 -1
  137. package/build/src/dispatch/index.d.ts +2 -2
  138. package/build/src/dispatch/index.js +17 -17
  139. package/build/src/git/admission.d.ts +1 -1
  140. package/build/src/git/admission.js +11 -11
  141. package/build/src/git/hooks.js +13 -13
  142. package/build/src/git/integration.d.ts +14 -15
  143. package/build/src/git/integration.js +80 -44
  144. package/build/src/git/observe.d.ts +5 -3
  145. package/build/src/git/observe.js +18 -12
  146. package/build/src/git/read-observation.js +9 -9
  147. package/build/src/git/reconcile.d.ts +2 -0
  148. package/build/src/git/reconcile.js +138 -95
  149. package/build/src/git/repository.d.ts +27 -19
  150. package/build/src/git/repository.js +155 -83
  151. package/build/src/git/scratch.d.ts +7 -3
  152. package/build/src/git/scratch.js +44 -37
  153. package/build/src/git/target-placement.d.ts +40 -4
  154. package/build/src/git/target-placement.js +221 -101
  155. package/build/src/git/tender.d.ts +6 -5
  156. package/build/src/git/tender.js +24 -43
  157. package/build/src/git/terminal-seal.d.ts +1 -1
  158. package/build/src/git/terminal-seal.js +7 -5
  159. package/build/src/git/workspace.d.ts +36 -4
  160. package/build/src/git/workspace.js +53 -18
  161. package/build/src/identity/selector.js +1 -1
  162. package/build/src/index.d.ts +3 -3
  163. package/build/src/index.js +1 -1
  164. package/build/src/kanshi/index.d.ts +2 -2
  165. package/build/src/kanshi/index.js +1 -1
  166. package/build/src/kanshi/read.d.ts +2 -1
  167. package/build/src/kanshi/read.js +118 -27
  168. package/build/src/kanshi/report.d.ts +50 -0
  169. package/build/src/kanshi/select.d.ts +5 -0
  170. package/build/src/kanshi/select.js +32 -0
  171. package/build/src/library/address.d.ts +12 -3
  172. package/build/src/library/address.js +77 -46
  173. package/build/src/library/akuma-creation.d.ts +6 -1
  174. package/build/src/library/akuma-creation.js +86 -13
  175. package/build/src/library/audit.d.ts +18 -0
  176. package/build/src/library/audit.js +44 -0
  177. package/build/src/library/bind.js +4 -4
  178. package/build/src/library/catalog.d.ts +1 -1
  179. package/build/src/library/catalog.js +5 -8
  180. package/build/src/library/contract.d.ts +5 -6
  181. package/build/src/library/contract.js +11 -35
  182. package/build/src/library/delivery.d.ts +2 -1
  183. package/build/src/library/fleet.d.ts +2 -2
  184. package/build/src/library/fleet.js +35 -71
  185. package/build/src/library/keiyaku.d.ts +3 -2
  186. package/build/src/library/keiyaku.js +1 -0
  187. package/build/src/library/mutation.d.ts +7 -6
  188. package/build/src/library/mutation.js +23 -25
  189. package/build/src/library/reconcile.d.ts +29 -0
  190. package/build/src/library/reconcile.js +179 -0
  191. package/build/src/library/region.d.ts +12 -0
  192. package/build/src/library/region.js +15 -1
  193. package/build/src/library/repo.d.ts +4 -16
  194. package/build/src/library/repo.js +13 -38
  195. package/build/src/protocol/attempt.js +6 -6
  196. package/build/src/protocol/bind.js +4 -4
  197. package/build/src/protocol/intent.d.ts +15 -2
  198. package/build/src/protocol/intent.js +21 -6
  199. package/build/src/protocol/operations.d.ts +73 -22
  200. package/build/src/protocol/operations.js +292 -88
  201. package/build/src/protocol/outcome.d.ts +9 -3
  202. package/build/src/protocol/outcome.js +3 -1
  203. package/build/src/protocol/placement.d.ts +15 -4
  204. package/build/src/protocol/placement.js +58 -25
  205. package/build/src/protocol/read/status.d.ts +8 -1
  206. package/build/src/protocol/read/status.js +61 -14
  207. package/build/src/runtime/proc/line-rpc.d.ts +3 -8
  208. package/build/src/runtime/proc/line-rpc.js +16 -43
  209. package/build/src/runtime/proc/run.d.ts +15 -29
  210. package/build/src/runtime/proc/run.js +113 -105
  211. package/build/src/runtime/proc/stdio.d.ts +18 -0
  212. package/build/src/runtime/proc/stdio.js +58 -0
  213. package/build/src/settings.d.ts +2 -2
  214. package/build/src/settings.js +8 -8
  215. package/build/src/settlement/fence.d.ts +0 -4
  216. package/build/src/settlement/fence.js +0 -9
  217. package/build/src/settlement/holder.d.ts +11 -1
  218. package/build/src/settlement/holder.js +25 -0
  219. package/build/src/settlement/settle.d.ts +1 -1
  220. package/build/src/settlement/settle.js +52 -89
  221. package/build/src/task/board.d.ts +3 -3
  222. package/build/src/task/board.js +6 -9
  223. package/build/src/task/compose.d.ts +1 -1
  224. package/build/src/task/compose.js +18 -10
  225. package/build/src/task/context.d.ts +3 -3
  226. package/build/src/task/context.js +14 -14
  227. package/build/src/task/document.d.ts +2 -1
  228. package/build/src/task/document.js +15 -5
  229. package/build/src/task/index.d.ts +19 -7
  230. package/build/src/task/index.js +42 -23
  231. package/build/src/task/operations.d.ts +15 -9
  232. package/build/src/task/operations.js +78 -48
  233. package/build/src/task/query.d.ts +67 -0
  234. package/build/src/task/query.js +279 -0
  235. package/build/src/task/store.d.ts +2 -2
  236. package/build/src/task/store.js +40 -25
  237. package/build/src/verification/execution.d.ts +4 -2
  238. package/build/src/verification/execution.js +9 -5
  239. package/build/src/workspace-place.d.ts +41 -0
  240. package/build/src/workspace-place.js +386 -0
  241. package/build/src/world.d.ts +13 -2
  242. package/build/src/world.js +81 -48
  243. package/package.json +3 -2
  244. package/build/src/protocol/read/audit.d.ts +0 -31
  245. package/build/src/protocol/read/audit.js +0 -55
@@ -1,116 +1,235 @@
1
+ import { noteEvent } from "../../provider.js";
1
2
  export const OPENCODE_EVENT_DISPOSITIONS = {
2
- "session.next.agent.switched": "dropped",
3
- "session.next.model.switched": "dropped",
4
- "session.next.moved": "dropped",
5
- "session.next.prompted": "dropped",
6
- "session.next.prompt.admitted": "dropped",
7
- "session.next.context.updated": "dropped",
8
- "session.next.synthetic": "dropped",
9
- "session.next.shell.started": "dropped",
10
- "session.next.shell.ended": "dropped",
11
- "session.next.step.started": "dropped",
12
- "session.next.step.ended": "dropped",
13
- "session.next.step.failed": "mapped",
14
- "session.next.text.started": "dropped",
15
- "session.next.text.ended": "mapped",
16
- "session.next.tool.input.started": "dropped",
17
- "session.next.tool.input.ended": "dropped",
18
- "session.next.tool.called": "mapped",
19
- "session.next.tool.progress": "dropped",
20
- "session.next.tool.success": "mapped",
21
- "session.next.tool.failed": "mapped",
22
- "session.next.reasoning.started": "dropped",
23
- "session.next.reasoning.ended": "mapped",
24
- "session.next.retried": "mapped",
25
- "session.next.compaction.started": "dropped",
26
- "session.next.compaction.ended": "dropped",
27
- "session.next.revert.staged": "dropped",
28
- "session.next.revert.cleared": "dropped",
29
- "session.next.revert.committed": "dropped",
3
+ "server.instance.disposed": "dropped",
4
+ "installation.updated": "dropped",
5
+ "installation.update-available": "dropped",
6
+ "lsp.client.diagnostics": "dropped",
7
+ "lsp.updated": "dropped",
8
+ "message.updated": "mapped",
9
+ "message.removed": "dropped",
10
+ "message.part.updated": "mapped",
11
+ "message.part.removed": "dropped",
12
+ "permission.updated": "dropped",
13
+ "permission.replied": "dropped",
14
+ "session.status": "dropped",
15
+ "session.idle": "dropped",
16
+ "session.compacted": "dropped",
17
+ "file.edited": "dropped",
18
+ "todo.updated": "mapped",
19
+ "command.executed": "dropped",
20
+ "session.created": "dropped",
21
+ "session.updated": "dropped",
22
+ "session.deleted": "dropped",
23
+ "session.diff": "dropped",
24
+ "session.error": "mapped",
25
+ "file.watcher.updated": "dropped",
26
+ "vcs.branch.updated": "dropped",
27
+ "tui.prompt.append": "dropped",
28
+ "tui.command.execute": "dropped",
29
+ "tui.toast.show": "dropped",
30
+ "pty.created": "dropped",
31
+ "pty.updated": "dropped",
32
+ "pty.exited": "dropped",
33
+ "pty.deleted": "dropped",
34
+ "server.connected": "dropped",
30
35
  };
36
+ // OpenCode may emit these server-side metadata events before the generated
37
+ // SDK union catches up. They are all non-narrative and therefore remain drop
38
+ // dispositions; genuinely new execution events still use the unknown arm.
39
+ const RUNTIME_DROPPED_EVENT_KINDS = new Set([
40
+ "plugin.added",
41
+ "catalog.updated",
42
+ "reference.updated",
43
+ "integration.updated",
44
+ "server.heartbeat",
45
+ "message.part.delta",
46
+ ]);
31
47
  function object(value) {
32
- return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
48
+ return value !== null && typeof value === "object" && !Array.isArray(value)
49
+ ? value : undefined;
50
+ }
51
+ function text(value) {
52
+ return typeof value === "string" && value.length > 0 ? value : undefined;
53
+ }
54
+ function diagnostic(value) {
55
+ const data = object(value);
56
+ const nested = object(data?.data);
57
+ return text(nested?.message) ?? text(data?.message) ?? "OpenCode session failed";
58
+ }
59
+ function positiveLine(value) {
60
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 1 ? value : undefined;
61
+ }
62
+ function runCall(name, value) {
63
+ return name === "bash" || name === "shell"
64
+ ? { kind: "run", command: text(value?.command) ?? name }
65
+ : undefined;
66
+ }
67
+ function readCall(name, value) {
68
+ if (name !== "read")
69
+ return undefined;
70
+ const path = text(value?.filePath) ?? text(value?.path);
71
+ if (path === undefined)
72
+ return undefined;
73
+ const offset = positiveLine(value?.offset);
74
+ const limit = positiveLine(value?.limit);
75
+ return {
76
+ kind: "read",
77
+ path,
78
+ ...(offset === undefined ? {} : { offset }),
79
+ ...(limit === undefined ? {} : { limit }),
80
+ };
81
+ }
82
+ function searchCall(name, value) {
83
+ if (name !== "grep" && name !== "glob" && name !== "search")
84
+ return undefined;
85
+ const query = text(value?.pattern) ?? text(value?.query);
86
+ if (query === undefined)
87
+ return undefined;
88
+ const path = text(value?.path) ?? text(value?.filePath);
89
+ const glob = text(value?.glob);
90
+ const scope = name === "glob" ? "files" : "content";
91
+ return {
92
+ kind: "search",
93
+ query,
94
+ scope,
95
+ ...(path === undefined ? {} : { path }),
96
+ ...(scope === "content" && glob !== undefined ? { glob } : {}),
97
+ };
33
98
  }
34
- function text(value) { return typeof value === "string" && value.length > 0 ? value : undefined; }
35
- function diagnostic(value) { const v = object(value); return text(v?.message) ?? text(v?.error) ?? "OpenCode session failed"; }
36
99
  function callFor(name, input) {
37
100
  const value = object(input);
38
- if (name === "shell")
39
- return { kind: "run", command: text(value?.command) ?? "shell" };
40
- if (name === "read")
41
- return { kind: "read", path: text(value?.path) ?? "file" };
42
- if (name === "grep" || name === "search")
43
- return { kind: "search", query: text(value?.query) ?? "search" };
101
+ const lower = name.toLowerCase();
102
+ if (lower === "bash" || lower === "shell")
103
+ return runCall(lower, value);
104
+ if (lower === "read")
105
+ return readCall(lower, value);
106
+ if (lower === "grep" || lower === "glob" || lower === "search")
107
+ return searchCall(lower, value);
44
108
  return { kind: "other", display: name };
45
109
  }
46
- function resultFor(value, failed) {
47
- return { status: failed ? "error" : "ok", ...(failed ? { message: diagnostic(value) } : {}) };
110
+ function belongs(part, state) {
111
+ return state.sessionId === undefined || part.sessionID === state.sessionId;
112
+ }
113
+ function mapTextPart(part, events, state, thought) {
114
+ const id = text(part.id);
115
+ const time = object(part.time);
116
+ const content = text(part.text);
117
+ const seen = thought ? state.reasoningParts : state.assistantParts;
118
+ if (!belongs(part, state) || id === undefined || content === undefined || time?.end === undefined || seen.has(id))
119
+ return;
120
+ seen.add(id);
121
+ if (thought)
122
+ events.emit({ type: "thought", text: content });
123
+ else
124
+ events.emit({ type: "assistant", text: content });
125
+ }
126
+ function resultFor(state, failed) {
127
+ const exit = object(state.metadata)?.exit;
128
+ const exitCode = typeof exit === "number" && Number.isInteger(exit) ? exit : undefined;
129
+ if (failed) {
130
+ return { status: "error", message: text(state.error) ?? "OpenCode tool failed", ...(exitCode === undefined ? {} : { exitCode }) };
131
+ }
132
+ return { status: exitCode !== undefined && exitCode !== 0 ? "error" : "ok", ...(exitCode === undefined ? {} : { exitCode }) };
133
+ }
134
+ function mapToolPart(part, events, state) {
135
+ if (!belongs(part, state))
136
+ return;
137
+ const id = text(part.callID);
138
+ const name = text(part.tool);
139
+ const toolState = object(part.state);
140
+ if (id === undefined || name === undefined || toolState === undefined)
141
+ return;
142
+ if ((toolState.status === "pending" || toolState.status === "running")
143
+ && !state.tools.has(id) && !state.completedTools.has(id)) {
144
+ const call = callFor(name, toolState.input);
145
+ if (call === undefined)
146
+ return;
147
+ const observed = { name, call };
148
+ state.tools.set(id, observed);
149
+ events.emit({ type: "tool", phase: "started", id, ...observed });
150
+ return;
151
+ }
152
+ if ((toolState.status !== "completed" && toolState.status !== "error") || state.completedTools.has(id))
153
+ return;
154
+ const started = state.tools.get(id);
155
+ const call = started?.call ?? callFor(name, toolState.input);
156
+ if (call === undefined)
157
+ return;
158
+ const observed = started ?? { name, call };
159
+ if (!state.tools.has(id)) {
160
+ state.tools.set(id, observed);
161
+ events.emit({ type: "tool", phase: "started", id, ...observed });
162
+ }
163
+ state.completedTools.add(id);
164
+ events.emit({
165
+ type: "tool",
166
+ phase: "completed",
167
+ id,
168
+ ...observed,
169
+ result: resultFor(toolState, toolState.status === "error"),
170
+ });
171
+ }
172
+ function mapPart(part, events, state) {
173
+ if (part.type === "text")
174
+ return mapTextPart(part, events, state, false);
175
+ if (part.type === "reasoning")
176
+ return mapTextPart(part, events, state, true);
177
+ if (part.type === "tool")
178
+ mapToolPart(part, events, state);
179
+ }
180
+ function mapSessionError(properties, events, state) {
181
+ if (state.sessionId !== undefined && properties.sessionID !== state.sessionId)
182
+ return;
183
+ state.failure = diagnostic(properties.error);
184
+ events.emit(noteEvent(state.failure));
185
+ }
186
+ function mapTodo(properties, events, state) {
187
+ if (properties.sessionID !== state.sessionId || !Array.isArray(properties.todos))
188
+ return;
189
+ const summary = properties.todos.flatMap((value) => {
190
+ const todo = object(value);
191
+ const content = text(todo?.content);
192
+ return content === undefined ? [] : [`${text(todo?.status) ?? "todo"}: ${content}`];
193
+ }).join("; ");
194
+ if (summary.length > 0)
195
+ events.emit(noteEvent(summary));
196
+ }
197
+ function ignoredEvent(type) {
198
+ return typeof type === "string"
199
+ && (OPENCODE_EVENT_DISPOSITIONS[type] === "dropped" || RUNTIME_DROPPED_EVENT_KINDS.has(type));
48
200
  }
49
201
  export function mapEvent(value, events, state) {
50
202
  const event = object(value);
51
- const eventId = text(event?.id);
52
- if (eventId !== undefined && state.seen.has(eventId))
203
+ if (event === undefined)
53
204
  return;
54
- if (eventId !== undefined)
55
- state.seen.add(eventId);
56
- const kind = text(event?.type) ?? "unknown";
57
- const data = object(event?.data) ?? event ?? {};
58
- switch (kind) {
59
- case "session.next.text.ended": {
60
- const value = text(data.text);
61
- if (value !== undefined) {
62
- state.answer.push(value);
63
- events.emit({ type: "assistant", text: value });
64
- }
65
- return;
66
- }
67
- case "session.next.reasoning.ended": {
68
- const value = text(data.text);
69
- if (value !== undefined)
70
- events.emit({ type: "thought", text: value });
71
- return;
72
- }
73
- case "session.next.tool.called": {
74
- const id = text(data.callID);
75
- if (id === undefined) {
76
- events.emit({ type: "unknown", kind: `${kind}/missing-id` });
77
- return;
78
- }
79
- const observed = { name: text(data.tool) ?? "tool", call: callFor(text(data.tool) ?? "tool", data.input) };
80
- state.tools.set(id, observed);
81
- events.emit({ type: "tool", phase: "started", id, ...observed });
82
- return;
83
- }
84
- case "session.next.tool.success":
85
- case "session.next.tool.failed": {
86
- const id = text(data.callID);
87
- if (id === undefined) {
88
- events.emit({ type: "unknown", kind: `${kind}/missing-id` });
89
- return;
90
- }
91
- const started = state.tools.get(id);
92
- const failed = kind.endsWith("failed");
93
- if (started === undefined) {
94
- events.emit({ type: "unknown", kind: `${kind}/orphan` });
95
- return;
96
- }
97
- state.tools.delete(id);
98
- events.emit({ type: "tool", phase: "completed", id, ...started, result: resultFor(data.error, failed) });
99
- return;
100
- }
101
- case "session.next.step.failed":
102
- state.failure = diagnostic(data.error);
103
- events.emit({ type: "note", text: state.failure });
104
- return;
105
- case "session.next.retried":
106
- events.emit({ type: "note", text: "Retrying" });
107
- return;
108
- default: {
109
- const disposition = OPENCODE_EVENT_DISPOSITIONS[kind];
110
- if (disposition === "dropped")
111
- return;
112
- events.emit({ type: "unknown", kind });
205
+ const properties = object(event.properties) ?? {};
206
+ if (event.type === "message.part.updated") {
207
+ const part = object(properties.part);
208
+ if (part !== undefined)
209
+ mapPart(part, events, state);
210
+ return;
211
+ }
212
+ if (event.type === "message.updated") {
213
+ const info = object(properties.info);
214
+ if (info !== undefined && info.sessionID === state.sessionId && info.role === "assistant" && info.error !== undefined) {
215
+ state.failure = diagnostic(info.error);
113
216
  }
217
+ return;
114
218
  }
219
+ if (event.type === "session.error")
220
+ return mapSessionError(properties, events, state);
221
+ if (event.type === "todo.updated")
222
+ return mapTodo(properties, events, state);
223
+ if (ignoredEvent(event.type))
224
+ return;
225
+ events.emit({ type: "unknown", kind: typeof event.type === "string" ? event.type : "unknown" });
226
+ }
227
+ export function createEventState(sessionId) {
228
+ return {
229
+ ...(sessionId === undefined ? {} : { sessionId }),
230
+ assistantParts: new Set(),
231
+ reasoningParts: new Set(),
232
+ tools: new Map(),
233
+ completedTools: new Set(),
234
+ };
115
235
  }
116
- export function createEventState() { return { tools: new Map(), answer: [], seen: new Set() }; }
@@ -1,5 +1,6 @@
1
- import { type ProviderAdapter, type ProviderOptions, type Session } from "../../provider.js";
2
- import type { ProviderExecution, ResumeCoordinate } from "../../heart/index.js";
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";
3
4
  import { type OpencodeSdkLoader } from "./session.js";
4
5
  export type OpencodeProviderTestOptions = Readonly<{
5
6
  loader?: OpencodeSdkLoader;