@astrosheep/keiyaku 2.9.3 → 2.9.4

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 (237) hide show
  1. package/build/.tsbuildinfo +1 -1
  2. package/build/agents/call-terms.js +13 -94
  3. package/build/agents/harness/activity-values.js +16 -0
  4. package/build/agents/harness/event-persistence.js +218 -0
  5. package/build/agents/harness/execution-handle.js +25 -222
  6. package/build/agents/harness/index.js +3 -1
  7. package/build/agents/harness/outcome.js +47 -4
  8. package/build/agents/harness/projection.js +42 -59
  9. package/build/agents/harness/provider-adapter.js +58 -0
  10. package/build/agents/harness/router.js +11 -187
  11. package/build/agents/harness/runtime.js +17 -4
  12. package/build/agents/harness/session.js +15 -0
  13. package/build/agents/launch-snapshot/model.js +15 -236
  14. package/build/agents/launch-snapshot/parse-helpers.js +114 -0
  15. package/build/agents/launch-snapshot/resolve.js +17 -43
  16. package/build/agents/opencode-sdk.js +45 -12
  17. package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
  18. package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
  19. package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
  20. package/build/agents/providers/codex-app-server/adapter.js +50 -53
  21. package/build/agents/providers/codex-app-server/events.js +67 -11
  22. package/build/agents/providers/codex-app-server/identity.js +1 -0
  23. package/build/agents/providers/codex-app-server/policy.js +29 -0
  24. package/build/agents/providers/codex-app-server/registration.js +248 -0
  25. package/build/agents/providers/codex-app-server/session-schema.js +6 -0
  26. package/build/agents/providers/codex-app-server/session.js +23 -17
  27. package/build/agents/providers/codex-app-server/terms.js +1 -0
  28. package/build/agents/providers/opencode-sdk/adapter.js +94 -50
  29. package/build/agents/providers/opencode-sdk/events.js +8 -4
  30. package/build/agents/providers/opencode-sdk/registration.js +135 -0
  31. package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
  32. package/build/agents/providers/opencode-sdk/session.js +21 -14
  33. package/build/agents/providers/opencode-sdk/terms.js +1 -0
  34. package/build/agents/providers/pi/adapter.js +36 -30
  35. package/build/agents/providers/pi/registration.js +145 -0
  36. package/build/agents/providers/pi/session-schema.js +6 -0
  37. package/build/agents/providers/pi/terms.js +1 -0
  38. package/build/agents/providers/registration.js +7 -0
  39. package/build/agents/providers/registry.js +76 -0
  40. package/build/agents/selector.js +2 -29
  41. package/build/agents/types.js +8 -0
  42. package/build/artifact-directories.js +22 -0
  43. package/build/cli/commands/akuma/akuma/handler.js +1 -1
  44. package/build/cli/commands/akuma/view/handler.js +5 -4
  45. package/build/cli/commands/akuma.js +6 -0
  46. package/build/cli/commands/contract/amend/handler.js +8 -2
  47. package/build/cli/commands/contract/arc/handler.js +7 -1
  48. package/build/cli/commands/contract/bind/handler.js +4 -3
  49. package/build/cli/commands/contract/bind/meta.js +34 -7
  50. package/build/cli/commands/contract/forfeit/handler.js +4 -4
  51. package/build/cli/commands/contract/log/handler.js +3 -3
  52. package/build/cli/commands/contract/petition/handler.js +4 -6
  53. package/build/cli/commands/contract/renew/handler.js +20 -6
  54. package/build/cli/commands/contract/renew/meta.js +5 -4
  55. package/build/cli/commands/metadata.js +58 -0
  56. package/build/cli/commands/projection/call/handler.js +6 -5
  57. package/build/cli/commands/projection/kill/handler.js +16 -32
  58. package/build/cli/commands/projection/shared.js +28 -0
  59. package/build/cli/commands/projection/status/handler.js +1 -1
  60. package/build/cli/commands/projection/tell/handler.js +14 -30
  61. package/build/cli/commands/projection/wait/handler.js +45 -22
  62. package/build/cli/commands/projection/wait/meta.js +7 -2
  63. package/build/cli/commands/registry.js +2 -54
  64. package/build/cli/commands/shared.js +10 -7
  65. package/build/cli/commands/skills/install/handler.js +2 -5
  66. package/build/cli/commands/skills/skills/handler.js +1 -1
  67. package/build/cli/commands/task/add/handler.js +5 -13
  68. package/build/cli/commands/task/catalog.js +2 -2
  69. package/build/cli/commands/task/done/handler.js +4 -8
  70. package/build/cli/commands/task/drop/handler.js +3 -6
  71. package/build/cli/commands/task/ls/handler.js +3 -5
  72. package/build/cli/commands/task/shared.js +14 -4
  73. package/build/cli/commands/task/{view → show}/handler.js +7 -8
  74. package/build/cli/commands/task/show/meta.js +8 -0
  75. package/build/cli/commands/task/start/handler.js +3 -6
  76. package/build/cli/commands/task/stop/handler.js +4 -8
  77. package/build/cli/commands/task/task/handler.js +1 -1
  78. package/build/cli/commands/task/update/handler.js +4 -8
  79. package/build/cli/completion.js +1 -1
  80. package/build/cli/flags.js +19 -3
  81. package/build/cli/help.js +4 -11
  82. package/build/cli/index.js +57 -83
  83. package/build/cli/missing-subcommand.js +7 -0
  84. package/build/cli/parse-flags.js +14 -5
  85. package/build/cli/parse-metadata.js +3 -3
  86. package/build/cli/parse-selectors.js +1 -1
  87. package/build/cli/parse.js +21 -0
  88. package/build/cli/projection-address.js +7 -12
  89. package/build/cli/render/address.js +41 -37
  90. package/build/cli/render/arc.js +24 -12
  91. package/build/cli/render/call.js +11 -5
  92. package/build/cli/render/errors.js +36 -1
  93. package/build/cli/render/format.js +4 -0
  94. package/build/cli/render/kanshi.js +6 -12
  95. package/build/cli/render/kill.js +9 -0
  96. package/build/cli/render/misc.js +55 -12
  97. package/build/cli/render/petition.js +20 -15
  98. package/build/cli/render/projection-activity.js +3 -0
  99. package/build/cli/render/shared.js +60 -21
  100. package/build/cli/render/skills.js +10 -0
  101. package/build/cli/render/status.js +37 -14
  102. package/build/cli/render/success-response.js +77 -0
  103. package/build/cli/render/task.js +54 -14
  104. package/build/cli/render/tell.js +5 -0
  105. package/build/cli/render/terminal-failure.js +58 -0
  106. package/build/cli/render/types.js +1 -0
  107. package/build/cli/render/wait.js +38 -36
  108. package/build/cli/types.js +1 -1
  109. package/build/config/akuma-loader.js +0 -5
  110. package/build/config/env-keys.js +1 -1
  111. package/build/config/provider-policy-ownership.js +3 -32
  112. package/build/config/settings/disease.js +8 -1
  113. package/build/config/settings/loader.js +11 -3
  114. package/build/config/settings/provider-instance-fields.js +51 -0
  115. package/build/config/settings/schema.js +6 -176
  116. package/build/core/addressing.js +66 -16
  117. package/build/core/amend.js +135 -18
  118. package/build/core/arc.js +19 -67
  119. package/build/core/bind.js +82 -35
  120. package/build/core/call/call.js +15 -9
  121. package/build/core/call/context.js +6 -51
  122. package/build/core/call/execution.js +21 -22
  123. package/build/core/call/prompt.js +14 -1
  124. package/build/core/command-markdown.js +45 -0
  125. package/build/core/context.js +13 -7
  126. package/build/core/contract-view.js +20 -3
  127. package/build/core/draft.js +123 -16
  128. package/build/core/forfeit.js +5 -2
  129. package/build/core/hints.js +1 -75
  130. package/build/core/identifier-slug.js +66 -0
  131. package/build/core/ids.js +25 -11
  132. package/build/core/ledger.js +20 -68
  133. package/build/core/markdown/parser.js +0 -68
  134. package/build/core/markdown/render.js +68 -0
  135. package/build/core/markdown/sections.js +2 -1
  136. package/build/core/outcome-base.js +4 -0
  137. package/build/core/projection/generation/database.js +2 -38
  138. package/build/core/projection/generation/model.js +42 -1
  139. package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
  140. package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +19 -49
  141. package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
  142. package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +5 -3
  143. package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
  144. package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +18 -3
  145. package/build/core/projection/generation/store.js +2 -2
  146. package/build/core/projection/generation/transitions.js +1 -1
  147. package/build/core/projection/index.js +27 -0
  148. package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
  149. package/build/core/{projection-alias.js → projection/projection-alias.js} +13 -13
  150. package/build/core/projection/projection-coordinate.js +61 -0
  151. package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
  152. package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +2 -57
  153. package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
  154. package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
  155. package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +1 -1
  156. package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
  157. package/build/core/{projection-status.js → projection/projection-status.js} +98 -25
  158. package/build/core/projection/projection-terminal-failure.js +104 -0
  159. package/build/core/projection/projection-wait.js +278 -0
  160. package/build/core/projection/projection-wake.js +203 -0
  161. package/build/core/provider-loader-ports.js +4 -0
  162. package/build/core/ref-log.js +65 -40
  163. package/build/core/registry.js +63 -10
  164. package/build/core/renew-session.js +128 -0
  165. package/build/core/renew.js +426 -99
  166. package/build/core/scope.js +143 -66
  167. package/build/core/seal.js +139 -35
  168. package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +8 -8
  169. package/build/core/{claim.js → settlement/claim.js} +32 -8
  170. package/build/core/settlement/index.js +19 -0
  171. package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +22 -18
  172. package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
  173. package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
  174. package/build/core/settlement/petition-io.js +1 -0
  175. package/build/core/{petition-preview.js → settlement/petition-preview.js} +1 -1
  176. package/build/core/{petition.js → settlement/petition.js} +12 -10
  177. package/build/core/settlement/queue-read-model.js +143 -0
  178. package/build/core/settlement/queue-seat-allocation.js +156 -0
  179. package/build/core/settlement/queue.js +6 -0
  180. package/build/core/settlement/settlement.js +295 -0
  181. package/build/core/{verdict.js → settlement/verdict.js} +9 -37
  182. package/build/core/status/board.js +24 -23
  183. package/build/core/status/ledger-batch.js +158 -0
  184. package/build/core/status/reconciliation.js +10 -4
  185. package/build/core/stored-agent-event.js +3 -0
  186. package/build/core/task/board.js +40 -4
  187. package/build/core/task/commands.js +30 -21
  188. package/build/core/task/index.js +12 -0
  189. package/build/core/task/settlement-git.js +157 -65
  190. package/build/core/task/settlement-policy.js +54 -24
  191. package/build/core/task/task-contract.js +370 -0
  192. package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
  193. package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
  194. package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
  195. package/build/core/{task-git-store.js → task/task-git-store.js} +90 -19
  196. package/build/core/task/task-repository.js +1 -0
  197. package/build/core/{task-store-repository.js → task/task-store-repository.js} +5 -4
  198. package/build/core/task/task-store.js +1 -0
  199. package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
  200. package/build/core/task/task.js +5 -0
  201. package/build/core/task/tree.js +37 -0
  202. package/build/core/task/validation.js +5 -2
  203. package/build/core/transcripts.js +15 -3
  204. package/build/core/worktree-path.js +43 -28
  205. package/build/flow-error.js +85 -39
  206. package/build/fs/path-coordinate.js +16 -0
  207. package/build/generated/version.js +3 -2
  208. package/build/git/branches.js +2 -1
  209. package/build/git/core.js +106 -2
  210. package/build/git/path-coordinate.js +17 -0
  211. package/build/git/refs.js +57 -0
  212. package/build/git/streaming-batch.js +301 -0
  213. package/build/git/worktree.js +65 -0
  214. package/build/index.js +3 -3
  215. package/build/keiyaku.js +2 -36
  216. package/package.json +4 -10
  217. package/skills/keiyaku/SKILL.md +3 -2
  218. package/skills/keiyaku-akuma/SKILL.md +9 -6
  219. package/skills/keiyaku-task/SKILL.md +1 -1
  220. package/skills/keiyaku-workflow/SKILL.md +23 -3
  221. package/build/agents/providers/codex-sdk.js +0 -329
  222. package/build/cli/commands/task/view/meta.js +0 -8
  223. package/build/core/command-io.js +0 -174
  224. package/build/core/path-coordinate.js +0 -27
  225. package/build/core/petition-claim.js +0 -117
  226. package/build/core/petition-run.js +0 -83
  227. package/build/core/projection-coordinate.js +0 -63
  228. package/build/core/projection-wait.js +0 -165
  229. package/build/core/projection-wake.js +0 -136
  230. package/build/core/queue.js +0 -343
  231. package/build/core/task-contract.js +0 -237
  232. package/build/core/task.js +0 -4
  233. /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
  234. /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
  235. /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
  236. /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
  237. /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
@@ -1,329 +0,0 @@
1
- import { z } from "zod";
2
- import { Codex, } from "@openai/codex-sdk";
3
- import { CODEX_MODEL_REASONING_EFFORT_CONFIG_KEY } from "../../keiyaku.js";
4
- import { appendDebugBlock, appendDebugLog } from "../../telemetry/debug-log.js";
5
- import { SUBAGENT_SESSION_VERSION } from "../session.js";
6
- import { createProjectionDriver } from "../harness/execution-handle.js";
7
- import { boundActivityExcerpt } from "../harness/activity-values.js";
8
- import { buildSubagentEnv, emitProviderEvidence, sha256Utf8 } from "../harness/runtime.js";
9
- import { coerceString } from "../harness/runtime.js";
10
- import { AGENT_PLAN_ITEM_TEXT_MAX_CHARS, AGENT_PLAN_MAX_ITEMS, AGENT_THOUGHT_TEXT_MAX_CHARS, } from "../harness/events.js";
11
- import { appendEventType, renderEventTypeSummary } from "./event-type-tail.js";
12
- /** Identity-only opacity boundary for Codex SDK ThreadOptions modelReasoningEffort. */
13
- function toCodexSdkModelReasoningEffort(effort) {
14
- return effort;
15
- }
16
- function withCodexSdkModelReasoningEffort(threadOptions) {
17
- const raw = threadOptions.modelReasoningEffort;
18
- if (typeof raw !== "string")
19
- return threadOptions;
20
- return {
21
- ...threadOptions,
22
- modelReasoningEffort: toCodexSdkModelReasoningEffort(raw),
23
- };
24
- }
25
- let codexConstructor = Codex;
26
- function getCodexConstructor(override) {
27
- if (override)
28
- return override;
29
- return codexConstructor;
30
- }
31
- /** @deprecated Use CodexSdkOptions.codexConstructor instead. */
32
- export function setCodexSdkConstructorForTests(constructor) {
33
- codexConstructor = constructor;
34
- }
35
- /** @deprecated Use CodexSdkOptions.codexConstructor instead. */
36
- export function resetCodexSdkConstructorForTests() {
37
- codexConstructor = Codex;
38
- }
39
- export const codexThreadSchema = z.object({ threadId: z.string().trim().min(1) });
40
- const CODEX_EVENT_THREAD_STARTED = "thread.started";
41
- const CODEX_EVENT_TURN_STARTED = "turn.started";
42
- const CODEX_EVENT_TURN_FAILED = "turn.failed";
43
- const CODEX_EVENT_ERROR = "error";
44
- const CODEX_EVENT_ITEM_STARTED = "item.started";
45
- const CODEX_EVENT_ITEM_COMPLETED = "item.completed";
46
- const CODEX_EVENT_ITEM_UPDATED = "item.updated";
47
- const CODEX_EVENT_TURN_COMPLETED = "turn.completed";
48
- const CODEX_SDK_PROVIDER = "codex-sdk";
49
- const CODEX_SDK_ACKNOWLEDGED_UNPERSISTED = new Set([CODEX_EVENT_THREAD_STARTED]);
50
- const CODEX_SDK_MAPPED = new Set([
51
- CODEX_EVENT_TURN_STARTED,
52
- CODEX_EVENT_TURN_COMPLETED,
53
- CODEX_EVENT_TURN_FAILED,
54
- CODEX_EVENT_ERROR,
55
- CODEX_EVENT_ITEM_STARTED,
56
- CODEX_EVENT_ITEM_UPDATED,
57
- CODEX_EVENT_ITEM_COMPLETED,
58
- ]);
59
- function codexSdkIngressDisposition(type) {
60
- if (CODEX_SDK_ACKNOWLEDGED_UNPERSISTED.has(type))
61
- return "acknowledged-unpersisted";
62
- if (CODEX_SDK_MAPPED.has(type))
63
- return "mapped";
64
- return "unknown";
65
- }
66
- function extractAgentMessage(event) {
67
- if (event.type !== CODEX_EVENT_ITEM_COMPLETED && event.type !== CODEX_EVENT_ITEM_UPDATED) {
68
- return undefined;
69
- }
70
- if (event.item.type !== "agent_message")
71
- return undefined;
72
- const text = coerceString(event.item.text);
73
- if (!text)
74
- return undefined;
75
- return { id: event.item.id, text };
76
- }
77
- function codexActivityCall(item) {
78
- switch (item.type) {
79
- case "command_execution": return { kind: "run", command: item.command };
80
- case "file_change": return {
81
- kind: "fileChange",
82
- changes: item.changes.map((change) => ({ op: change.kind, path: change.path })),
83
- };
84
- case "mcp_tool_call": return { kind: "other", display: `${item.server}.${item.tool}` };
85
- case "web_search": return { kind: "search", query: item.query };
86
- }
87
- }
88
- function codexMcpResultMessage(item) {
89
- if (item.error?.message)
90
- return boundActivityExcerpt(item.error.message);
91
- const text = item.result?.content.flatMap((block) => (block.type === "text" && typeof block.text === "string" ? [block.text] : [])).join("\n");
92
- return text ? boundActivityExcerpt(text) : undefined;
93
- }
94
- function codexActivityResult(item) {
95
- switch (item.type) {
96
- case "command_execution": return {
97
- status: item.status === "failed" || (item.exit_code !== undefined && item.exit_code !== 0) ? "error" : "ok",
98
- ...(item.aggregated_output ? { message: boundActivityExcerpt(item.aggregated_output) } : {}),
99
- ...(item.exit_code === undefined ? {} : { exitCode: item.exit_code }),
100
- };
101
- case "file_change": return { status: item.status === "failed" ? "error" : "ok" };
102
- case "mcp_tool_call": {
103
- const message = codexMcpResultMessage(item);
104
- return { status: item.status === "failed" ? "error" : "ok", ...(message ? { message } : {}) };
105
- }
106
- case "web_search": return { status: "ok" };
107
- }
108
- }
109
- function emitCodexSemanticEvent(builder, event) {
110
- if (event.type === CODEX_EVENT_TURN_STARTED) {
111
- builder.emit({ type: "turn", phase: "started" });
112
- return;
113
- }
114
- if (event.type === CODEX_EVENT_TURN_COMPLETED) {
115
- builder.emit({
116
- type: "usage",
117
- inputTokens: event.usage.input_tokens,
118
- outputTokens: event.usage.output_tokens,
119
- cachedInputTokens: event.usage.cached_input_tokens,
120
- });
121
- builder.emit({ type: "turn", phase: "completed" });
122
- return;
123
- }
124
- if (event.type !== CODEX_EVENT_ITEM_STARTED &&
125
- event.type !== CODEX_EVENT_ITEM_UPDATED &&
126
- event.type !== CODEX_EVENT_ITEM_COMPLETED) {
127
- return;
128
- }
129
- if (event.item.type === "reasoning" &&
130
- (event.type === CODEX_EVENT_ITEM_UPDATED || event.type === CODEX_EVENT_ITEM_COMPLETED)) {
131
- const truncated = event.item.text.length > AGENT_THOUGHT_TEXT_MAX_CHARS;
132
- builder.emit({
133
- type: "thought",
134
- id: event.item.id,
135
- text: event.item.text.slice(0, AGENT_THOUGHT_TEXT_MAX_CHARS),
136
- final: event.type === CODEX_EVENT_ITEM_COMPLETED,
137
- ...(truncated ? { truncated: true } : {}),
138
- });
139
- return;
140
- }
141
- if (event.item.type === "todo_list") {
142
- builder.emit({
143
- type: "plan",
144
- id: event.item.id,
145
- items: event.item.items.slice(0, AGENT_PLAN_MAX_ITEMS).map((item) => ({
146
- text: item.text.slice(0, AGENT_PLAN_ITEM_TEXT_MAX_CHARS),
147
- done: item.completed,
148
- })),
149
- });
150
- return;
151
- }
152
- if (event.item.type !== "command_execution" &&
153
- event.item.type !== "file_change" &&
154
- event.item.type !== "mcp_tool_call" &&
155
- event.item.type !== "web_search") {
156
- return;
157
- }
158
- const phase = event.type === CODEX_EVENT_ITEM_STARTED
159
- ? "started"
160
- : event.type === CODEX_EVENT_ITEM_UPDATED
161
- ? "updated"
162
- : "completed";
163
- builder.emit({
164
- type: "activity",
165
- phase,
166
- id: event.item.id,
167
- tool: event.item.type,
168
- call: codexActivityCall(event.item),
169
- ...(phase === "started" ? {} : { result: codexActivityResult(event.item) }),
170
- });
171
- }
172
- /** @deprecated Use the codex-app-server adapter. */
173
- export async function startCodexSdk(prompt, cwd, options) {
174
- const threadId = options.threadId?.trim();
175
- const recordedEventTypes = [];
176
- let totalEventCount = 0;
177
- let activeAbort;
178
- let runReturned = false;
179
- appendDebugLog(`startCodexSdk: executable=${options.executable ?? "codex"} model=${options.model ?? "default"} ${CODEX_MODEL_REASONING_EFFORT_CONFIG_KEY}=${String(options.config?.[CODEX_MODEL_REASONING_EFFORT_CONFIG_KEY] ?? "default")} mode=${threadId ? "resume" : "fresh"}`, { cwd, section: CODEX_SDK_PROVIDER });
180
- return createProjectionDriver({
181
- steerMode: "replay",
182
- initialTurn: options.initialTurn,
183
- onIngress: options.onIngress,
184
- async abort(mode) {
185
- activeAbort?.abort();
186
- if (mode === "force" && !runReturned) {
187
- throw new Error("codex-sdk cannot guarantee forced termination");
188
- }
189
- },
190
- async run(builder) {
191
- activeAbort = new AbortController();
192
- const linked = options.signal ?? builder.signal;
193
- const onOuterAbort = () => activeAbort?.abort();
194
- linked.addEventListener("abort", onOuterAbort, { once: true });
195
- if (linked.aborted)
196
- onOuterAbort();
197
- builder.signal.addEventListener("abort", onOuterAbort, { once: true });
198
- try {
199
- const env = buildSubagentEnv();
200
- const codexOptions = {
201
- codexPathOverride: options.executable,
202
- profile: options.profile,
203
- config: options.config,
204
- env,
205
- };
206
- const sdk = new (getCodexConstructor(options.codexConstructor))(codexOptions);
207
- const threadOptions = withCodexSdkModelReasoningEffort(options.threadOptions);
208
- const thread = threadId ? sdk.resumeThread(threadId, threadOptions) : sdk.startThread(threadOptions);
209
- const streamed = await thread.runStreamed(prompt, { signal: activeAbort.signal });
210
- const eventIterator = streamed.events[Symbol.asyncIterator]();
211
- // The SDK iterable is lazy: its first next() starts the native run.
212
- // Record outbound bytes immediately before that crossing, then ack only
213
- // after it settles (including a legitimate no-event completion).
214
- if (options.onEvidence) {
215
- emitProviderEvidence(options.onEvidence, {
216
- type: "outbound",
217
- provider: CODEX_SDK_PROVIDER,
218
- direction: "input",
219
- kind: "replay-prompt",
220
- ...sha256Utf8(prompt),
221
- }, (text) => builder.emit({ type: "diagnostic", text }));
222
- }
223
- const firstEvent = await eventIterator.next();
224
- if (options.onEvidence) {
225
- emitProviderEvidence(options.onEvidence, {
226
- type: "ack",
227
- provider: CODEX_SDK_PROVIDER,
228
- fence: { kind: "ordinal", ordinal: 0 },
229
- outbound: "run",
230
- }, (text) => builder.emit({ type: "diagnostic", text }));
231
- }
232
- const events = async function* () {
233
- if (!firstEvent.done)
234
- yield firstEvent.value;
235
- while (true) {
236
- const next = await eventIterator.next();
237
- if (next.done)
238
- return;
239
- yield next.value;
240
- }
241
- };
242
- let resumeToken;
243
- let lastAgentMessage;
244
- let turnFailedMessage;
245
- let streamErrorMessage;
246
- for await (const event of events()) {
247
- if (activeAbort.signal.aborted) {
248
- throw Object.assign(new Error(`${CODEX_SDK_PROVIDER} exec cancelled by client`), { name: "AbortError" });
249
- }
250
- totalEventCount += 1;
251
- appendEventType(recordedEventTypes, event.type);
252
- builder.ingress(CODEX_SDK_PROVIDER, event.type, event, codexSdkIngressDisposition(event.type), () => {
253
- if (event.type === CODEX_EVENT_THREAD_STARTED) {
254
- resumeToken = event.thread_id;
255
- if (options.onEvidence)
256
- emitProviderEvidence(options.onEvidence, { type: "session", provider: CODEX_SDK_PROVIDER, threadId: resumeToken }, (text) => builder.emit({ type: "diagnostic", text }));
257
- }
258
- else if (event.type === CODEX_EVENT_TURN_STARTED && !resumeToken) {
259
- builder.emit({
260
- type: "fail",
261
- message: `${CODEX_SDK_PROVIDER} exec emitted turn.started before thread.started with thread_id`,
262
- });
263
- throw new Error(`${CODEX_SDK_PROVIDER} exec emitted turn.started before thread.started with thread_id`);
264
- }
265
- else if (event.type === CODEX_EVENT_TURN_FAILED) {
266
- turnFailedMessage = coerceString(event.error.message) ?? `${CODEX_SDK_PROVIDER} turn failed`;
267
- }
268
- else if (event.type === CODEX_EVENT_ERROR) {
269
- streamErrorMessage = coerceString(event.message) ?? `${CODEX_SDK_PROVIDER} stream error`;
270
- builder.emit({ type: "diagnostic", text: `${streamErrorMessage}\n` });
271
- }
272
- emitCodexSemanticEvent(builder, event);
273
- const message = extractAgentMessage(event);
274
- if (message) {
275
- lastAgentMessage = message.text;
276
- builder.emit({ type: "message", id: message.id, text: message.text });
277
- }
278
- });
279
- }
280
- if (turnFailedMessage) {
281
- builder.emit({ type: "diagnostic", text: turnFailedMessage });
282
- builder.emit({ type: "fail", message: turnFailedMessage });
283
- throw new Error(turnFailedMessage);
284
- }
285
- if (streamErrorMessage && !lastAgentMessage) {
286
- builder.emit({ type: "fail", message: streamErrorMessage });
287
- throw new Error(streamErrorMessage);
288
- }
289
- if (!resumeToken) {
290
- appendDebugLog(`Missing required codex event: ${CODEX_EVENT_THREAD_STARTED} with thread_id.`, {
291
- cwd,
292
- section: CODEX_SDK_PROVIDER,
293
- });
294
- appendDebugBlock("codex-sdk stdout event types", renderEventTypeSummary(recordedEventTypes, totalEventCount), {
295
- cwd,
296
- section: CODEX_SDK_PROVIDER,
297
- });
298
- builder.emit({
299
- type: "fail",
300
- message: `${CODEX_SDK_PROVIDER} exec succeeded but did not emit a ${CODEX_EVENT_THREAD_STARTED} event with thread_id`,
301
- });
302
- throw new Error(`${CODEX_SDK_PROVIDER} exec succeeded but did not emit a ${CODEX_EVENT_THREAD_STARTED} event with thread_id`);
303
- }
304
- const finalMessage = lastAgentMessage ?? "";
305
- const session = {
306
- provider: "codex-sdk",
307
- version: SUBAGENT_SESSION_VERSION,
308
- handle: { threadId: resumeToken },
309
- };
310
- if (options.onEvidence)
311
- emitProviderEvidence(options.onEvidence, { type: "checkpoint", provider: CODEX_SDK_PROVIDER, fence: { kind: "ordinal", ordinal: 1 }, source: "response" }, (text) => builder.emit({ type: "diagnostic", text }));
312
- builder.emit({
313
- type: "done",
314
- finalMessage,
315
- session,
316
- });
317
- return { finalMessage, session };
318
- }
319
- catch (error) {
320
- appendDebugLog(`startCodexSdk error: ${error instanceof Error ? `${error.name}: ${error.message}` : String(error)}`, { cwd, section: CODEX_SDK_PROVIDER });
321
- throw error;
322
- }
323
- finally {
324
- runReturned = true;
325
- linked.removeEventListener("abort", onOuterAbort);
326
- }
327
- },
328
- });
329
- }
@@ -1,8 +0,0 @@
1
- export const meta = {
2
- command: "task view",
3
- summary: "View one task",
4
- usage: ["keiyaku task view [-C|--cwd DIR] ID [--json]"],
5
- stdin: "none",
6
- flags: ["cwd", "json"],
7
- purpose: "Read one task from the working-tree board.",
8
- };
@@ -1,174 +0,0 @@
1
- import { ACTOR_IDENTITY } from "../keiyaku.js";
2
- import { FlowError } from "../flow-error.js";
3
- import { parseMarkdownListSection, parseMarkdownStructure } from "./markdown/sections.js";
4
- import { KeiyakuParseError } from "./markdown/types.js";
5
- import { normalizeSectionTitle } from "./markdown/titles.js";
6
- import { isBlankScopePatternLine, normalizeScopePattern, ScopePatternError } from "./scope.js";
7
- function amendScopeHeading(name) {
8
- return `## Scope ${name[0].toUpperCase()}${name.slice(1)}`;
9
- }
10
- function sourceLines(markdown) {
11
- const lines = [];
12
- let start = 0;
13
- while (start < markdown.length) {
14
- const newline = markdown.indexOf("\n", start);
15
- const end = newline === -1 ? markdown.length : newline;
16
- const next = newline === -1 ? markdown.length : newline + 1;
17
- const raw = markdown.slice(start, end);
18
- lines.push({ text: raw.endsWith("\r") ? raw.slice(0, -1) : raw, start, end, next });
19
- start = next;
20
- }
21
- return lines;
22
- }
23
- function amendHeading(line) {
24
- const match = line.match(/^ {0,3}(#{1,2})(?!#)[ \t]+(.+)$/);
25
- if (!match)
26
- return null;
27
- const level = match[1].length;
28
- const title = normalizeSectionTitle(match[2]);
29
- if (level !== 2)
30
- return { level };
31
- if (title === "scope add")
32
- return { level, name: "add" };
33
- return { level };
34
- }
35
- function amendFence(line) {
36
- const match = line.match(/^ {0,3}(`{3,}|~{3,})/);
37
- if (!match)
38
- return null;
39
- const marker = match[1];
40
- return { delimiter: marker[0], length: marker.length };
41
- }
42
- function parseAmendScopeSections(markdown) {
43
- const lines = sourceLines(markdown);
44
- const sections = {};
45
- let active;
46
- let fence;
47
- let frontMatterEnd = -1;
48
- if (lines[0]?.text.trim() === "---") {
49
- for (let index = 1; index < lines.length; index += 1) {
50
- if (lines[index].text.trim() === "---") {
51
- frontMatterEnd = index;
52
- break;
53
- }
54
- }
55
- }
56
- const finishActive = (end) => {
57
- if (!active)
58
- return;
59
- sections[active.name] = { ...active, end };
60
- active = undefined;
61
- };
62
- for (let index = 0; index < lines.length; index += 1) {
63
- const line = lines[index];
64
- if (index <= frontMatterEnd)
65
- continue;
66
- const marker = amendFence(line.text);
67
- if (fence) {
68
- if (marker && marker.delimiter === fence.delimiter && marker.length >= fence.length) {
69
- fence = undefined;
70
- }
71
- continue;
72
- }
73
- if (marker) {
74
- fence = marker;
75
- continue;
76
- }
77
- const heading = amendHeading(line.text);
78
- if (!heading)
79
- continue;
80
- finishActive(line.start);
81
- if (!heading.name)
82
- continue;
83
- if (sections[heading.name]) {
84
- throw new FlowError("INVALID_KEIYAKU_DRAFT", `amend input may contain ${amendScopeHeading(heading.name)} at most once`);
85
- }
86
- active = { name: heading.name, start: line.start, contentStart: line.next };
87
- }
88
- finishActive(markdown.length);
89
- let prose = markdown;
90
- for (const section of Object.values(sections).sort((left, right) => right.start - left.start)) {
91
- prose = `${prose.slice(0, section.start)}${prose.slice(section.end)}`;
92
- }
93
- return { sections, prose };
94
- }
95
- function scopePatterns(markdown, section) {
96
- const patterns = markdown
97
- .slice(section.contentStart, section.end)
98
- .split(/\r?\n/)
99
- .filter((line) => !isBlankScopePatternLine(line))
100
- .map((pattern) => {
101
- try {
102
- // Do not trim() here: gitignore treats trailing `\ ` as a significant space.
103
- return normalizeScopePattern(pattern);
104
- }
105
- catch (error) {
106
- if (error instanceof ScopePatternError) {
107
- throw new FlowError("INVALID_KEIYAKU_DRAFT", error.message);
108
- }
109
- throw error;
110
- }
111
- });
112
- if (patterns.length === 0) {
113
- throw new FlowError("INVALID_KEIYAKU_DRAFT", `amend input has an empty ${amendScopeHeading(section.name)} section`);
114
- }
115
- return patterns;
116
- }
117
- export function buildAmendInput(markdown, cwd, contractId, contractAddressSource) {
118
- const { sections, prose } = parseAmendScopeSections(markdown);
119
- const add = sections.add ? scopePatterns(markdown, sections.add) : [];
120
- if (!prose.trim()) {
121
- throw new FlowError("EMPTY_PARAM", "amendment cannot be empty");
122
- }
123
- return {
124
- cwd,
125
- ...(contractId ? { contractId } : {}),
126
- ...(contractAddressSource ? { contractAddressSource } : {}),
127
- amendment: prose,
128
- ...(sections.add ? { scopeDelta: { add } } : {}),
129
- };
130
- }
131
- export function defaultActorClock(nowMs = Date.now()) {
132
- return { actor: ACTOR_IDENTITY, nowMs };
133
- }
134
- export function parseCommandMarkdown(content) {
135
- try {
136
- const parsed = parseMarkdownStructure(content);
137
- const sections = new Map();
138
- for (const [key, lines] of parsed.sections.entries()) {
139
- sections.set(key, lines.join("\n").trim());
140
- }
141
- return { title: parsed.title, sections };
142
- }
143
- catch (error) {
144
- if (error instanceof KeiyakuParseError) {
145
- throw new FlowError("INVALID_KEIYAKU_DRAFT", error.message, { cause: error });
146
- }
147
- throw error;
148
- }
149
- }
150
- export function requireMarkdownTextSection(parts, name) {
151
- const normalized = normalizeSectionTitle(name);
152
- const value = parts.sections.get(normalized)?.trim();
153
- if (!value) {
154
- throw new FlowError("INVALID_KEIYAKU_DRAFT", `missing required section: ## ${name}`);
155
- }
156
- return value;
157
- }
158
- export function requireMarkdownListSection(parts, name) {
159
- const text = requireMarkdownTextSection(parts, name);
160
- const items = parseMarkdownListSection(text)
161
- .map((item) => item.trim())
162
- .filter((item) => item.length > 0);
163
- if (items.length === 0) {
164
- throw new FlowError("INVALID_KEIYAKU_DRAFT", `missing required section: ## ${name}`);
165
- }
166
- return items;
167
- }
168
- export function requireMarkdownTitle(parts) {
169
- const title = parts.title?.trim();
170
- if (!title) {
171
- throw new FlowError("INVALID_KEIYAKU_DRAFT", "missing required title: # Title");
172
- }
173
- return title;
174
- }
@@ -1,27 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as fsPromises from "node:fs/promises";
3
- import * as path from "node:path";
4
- /**
5
- * Git for Windows may emit native, slash-normalized, or MSYS drive paths.
6
- * Keep one host-native spelling before using a coordinate as a filesystem cwd.
7
- */
8
- export function normalizeGitPath(raw, platform = process.platform) {
9
- const value = raw.trim();
10
- if (platform !== "win32")
11
- return path.normalize(value);
12
- const msysDrive = value.match(/^\/([A-Za-z])(?:\/|$)(.*)$/);
13
- if (msysDrive)
14
- return path.win32.normalize(`${msysDrive[1].toUpperCase()}:/${msysDrive[2]}`);
15
- const normalized = path.win32.normalize(value);
16
- return normalized.replace(/^([a-z]):/, (_, drive) => `${drive.toUpperCase()}:`);
17
- }
18
- export function gitCommonRootPath(raw, platform = process.platform) {
19
- const paths = platform === "win32" ? path.win32 : path.posix;
20
- return paths.dirname(normalizeGitPath(raw, platform));
21
- }
22
- export async function resolveGitCommonRoot(raw) {
23
- return await fsPromises.realpath(gitCommonRootPath(raw));
24
- }
25
- export function resolveGitCommonRootSync(raw) {
26
- return fs.realpathSync(gitCommonRootPath(raw));
27
- }
@@ -1,117 +0,0 @@
1
- import { FlowError } from "../flow-error.js";
2
- import { readContractLog } from "./log.js";
3
- import { petitionContract } from "./petition.js";
4
- import { verdictContract } from "./verdict.js";
5
- import { nextReviewResponseNumber } from "./transcripts.js";
6
- import { buildClaimGatePipeline, } from "./petition-claim-gates.js";
7
- import { assertHeadUnchanged } from "./petition-head-guard.js";
8
- async function throwClaimGateFailure(failure, input, context, dependencies) {
9
- const { cwd, contractId } = context;
10
- void contractId;
11
- void dependencies;
12
- if (failure.reviewHeadBeforeWrite) {
13
- await assertHeadUnchanged(cwd, failure.reviewHeadBeforeWrite, "claim review");
14
- }
15
- throw new FlowError(failure.code, failure.message, {
16
- hints: failure.hints,
17
- review: failure.review,
18
- });
19
- }
20
- async function runClaimGatePipelineOrThrow(input, context, dependencies) {
21
- const { verificationCommands } = await dependencies.resolveClaimGateConfig(context.cwd);
22
- let review;
23
- let reviewHeadBeforeWrite;
24
- let reviewerActor;
25
- for (const gate of buildClaimGatePipeline()) {
26
- const result = await gate.evaluate({
27
- cwd: context.cwd,
28
- contractId: context.contractId,
29
- input,
30
- verificationCommands,
31
- baseBranch: dependencies.baseBranch,
32
- reviewNumber: dependencies.reviewNumber,
33
- });
34
- if (result.review) {
35
- review = result.review;
36
- reviewHeadBeforeWrite = result.reviewHeadBeforeWrite;
37
- }
38
- if (result.reviewerActor)
39
- reviewerActor = result.reviewerActor;
40
- if (!result.pass) {
41
- await throwClaimGateFailure(result, input, context, dependencies);
42
- }
43
- }
44
- return { review, reviewHeadBeforeWrite, reviewerActor };
45
- }
46
- function maxArc(entries) {
47
- return entries.filter((entry) => entry.kind === "arc").length;
48
- }
49
- function cleanupWarnings(cleanup) {
50
- return [
51
- ...(cleanup.worktreeRemoveFailure
52
- ? [`Could not remove contract worktree ${cleanup.worktreeRemoveFailure.path}: ${cleanup.worktreeRemoveFailure.reason}`]
53
- : []),
54
- ...(cleanup.branchDeleteFailure
55
- ? [`Could not delete contract branch ${cleanup.branchDeleteFailure.name}: ${cleanup.branchDeleteFailure.reason}`]
56
- : []),
57
- ];
58
- }
59
- export async function claimKeiyaku(input, context, dependencies) {
60
- const { cwd, baseBranch, contractId } = context;
61
- const claimResult = "dangerouslyBypassGates" in input && input.dangerouslyBypassGates
62
- ? { review: undefined, reviewHeadBeforeWrite: undefined, bypassedByArchitect: true }
63
- : {
64
- ...(await runClaimGatePipelineOrThrow(input, { cwd, contractId }, {
65
- ...dependencies,
66
- baseBranch,
67
- reviewNumber: await nextReviewResponseNumber(cwd),
68
- })),
69
- bypassedByArchitect: false,
70
- };
71
- if (claimResult.review && claimResult.reviewHeadBeforeWrite) {
72
- await assertHeadUnchanged(cwd, claimResult.reviewHeadBeforeWrite, "claim review");
73
- }
74
- const oath = String(input.oath ?? "").trim();
75
- if (!oath) {
76
- throw new FlowError("OATH_MISSING", "Oath missing.");
77
- }
78
- const petition = await petitionContract({
79
- cwd,
80
- contractId,
81
- actor: "keiyaku",
82
- nowMs: Date.now(),
83
- intent: "claim",
84
- oath,
85
- waivePaths: input.waivePaths,
86
- });
87
- const log = await readContractLog({ cwd, contractId });
88
- const verdict = await verdictContract({
89
- cwd,
90
- contractId,
91
- actor: claimResult.reviewerActor ?? "keiyaku",
92
- nowMs: Date.now(),
93
- result: "approved",
94
- summary: claimResult.review?.findings?.trim() || "礼成",
95
- });
96
- if (!verdict.claimed) {
97
- throw new FlowError("INTERNAL_STATE", `approved verdict for ${contractId} did not produce an engine claim`);
98
- }
99
- const cleanup = verdict.claimed.cleanup ?? { absent: ["worktree", "branch"] };
100
- const warnings = [...(verdict.claimed.warnings ?? []), ...cleanupWarnings(cleanup)];
101
- return {
102
- status: "success",
103
- result: "merged",
104
- arc: maxArc(log.entries),
105
- currentBranch: baseBranch,
106
- baseBranch,
107
- commit: verdict.claimed.mergeCommit,
108
- mergedInto: baseBranch,
109
- ...(cleanup.deletedBranch ? { deletedBranch: cleanup.deletedBranch } : {}),
110
- cleanup,
111
- diff: `Merged contract ${contractId} with merge-tree/commit-tree CAS.`,
112
- ...(petition.sealed ? { sealed: petition.sealed } : {}),
113
- ...(warnings.length > 0
114
- ? { meta: { warnings } }
115
- : {}),
116
- };
117
- }