@astrosheep/keiyaku 2.8.4 → 2.9.0

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 (229) hide show
  1. package/README.md +35 -15
  2. package/build/.tsbuildinfo +1 -1
  3. package/build/agents/{call-terms_v2.js → call-terms.js} +12 -8
  4. package/build/agents/harness/control-types.js +1 -0
  5. package/build/agents/harness/execution-handle.js +23 -3
  6. package/build/agents/harness/index.js +6 -607
  7. package/build/agents/harness/outcome.js +141 -0
  8. package/build/agents/harness/projection.js +310 -0
  9. package/build/agents/harness/router.js +201 -0
  10. package/build/agents/harness/runtime.js +2 -1
  11. package/build/agents/{launch-snapshot_v2.js → launch-snapshot/model.js} +69 -74
  12. package/build/agents/launch-snapshot/resolve.js +72 -0
  13. package/build/agents/opencode-sdk.js +24 -3
  14. package/build/agents/providers/{claude-agent-sdk.js → claude-agent-sdk/adapter.js} +46 -368
  15. package/build/agents/providers/claude-agent-sdk/events.js +218 -0
  16. package/build/agents/providers/claude-agent-sdk/session.js +158 -0
  17. package/build/agents/providers/codex-app-server/adapter.js +347 -0
  18. package/build/agents/providers/codex-app-server/events.js +352 -0
  19. package/build/agents/providers/codex-app-server/session.js +266 -0
  20. package/build/agents/providers/codex-sdk.js +23 -5
  21. package/build/agents/providers/opencode-sdk/adapter.js +344 -0
  22. package/build/agents/providers/opencode-sdk/events.js +354 -0
  23. package/build/agents/providers/opencode-sdk/session.js +180 -0
  24. package/build/agents/providers/pi/adapter.js +269 -0
  25. package/build/agents/providers/pi/checkpoint.js +41 -0
  26. package/build/agents/providers/pi/events.js +282 -0
  27. package/build/agents/{selector_v2.js → selector.js} +8 -6
  28. package/build/cli/commands/akuma/akuma/handler.js +4 -0
  29. package/build/cli/commands/akuma/akuma/meta.js +16 -0
  30. package/build/cli/commands/akuma/catalog.js +8 -0
  31. package/build/cli/commands/akuma/list/handler.js +15 -0
  32. package/build/cli/commands/akuma/list/meta-ls.js +9 -0
  33. package/build/cli/commands/akuma/view/handler.js +34 -0
  34. package/build/cli/commands/akuma/view/meta.js +8 -0
  35. package/build/cli/commands/akuma.js +1 -1
  36. package/build/cli/commands/contract/amend/handler.js +10 -0
  37. package/build/cli/commands/contract/amend/meta.js +12 -0
  38. package/build/cli/commands/contract/arc/handler.js +9 -0
  39. package/build/cli/commands/contract/arc/meta.js +26 -0
  40. package/build/cli/commands/contract/bind/handler.js +23 -0
  41. package/build/cli/commands/contract/bind/meta.js +30 -0
  42. package/build/cli/commands/contract/catalog.js +16 -0
  43. package/build/cli/commands/contract/forfeit/handler.js +13 -0
  44. package/build/cli/commands/contract/forfeit/meta.js +12 -0
  45. package/build/cli/commands/contract/log/handler.js +12 -0
  46. package/build/cli/commands/contract/log/meta.js +12 -0
  47. package/build/cli/commands/contract/petition/handler.js +26 -0
  48. package/build/cli/commands/contract/petition/meta.js +23 -0
  49. package/build/cli/commands/contract/renew/handler.js +10 -0
  50. package/build/cli/commands/contract/renew/meta.js +17 -0
  51. package/build/cli/commands/projection/call/handler.js +39 -0
  52. package/build/cli/commands/projection/call/meta.js +9 -0
  53. package/build/cli/commands/projection/catalog.js +14 -0
  54. package/build/cli/commands/projection/kill/handler.js +35 -0
  55. package/build/cli/commands/projection/kill/meta.js +11 -0
  56. package/build/cli/commands/projection/revive/handler.js +53 -0
  57. package/build/cli/commands/projection/revive/meta.js +9 -0
  58. package/build/cli/commands/projection/status/handler.js +23 -0
  59. package/build/cli/commands/projection/status/meta.js +9 -0
  60. package/build/cli/commands/projection/tell/handler.js +34 -0
  61. package/build/cli/commands/projection/tell/meta.js +9 -0
  62. package/build/cli/commands/projection/wait/handler.js +21 -0
  63. package/build/cli/commands/projection/wait/meta.js +11 -0
  64. package/build/cli/commands/registry.js +100 -0
  65. package/build/cli/commands/shared.js +71 -0
  66. package/build/cli/commands/skills/catalog.js +6 -0
  67. package/build/cli/commands/skills/install/handler.js +10 -0
  68. package/build/cli/commands/skills/install/meta.js +9 -0
  69. package/build/cli/commands/skills/skills/handler.js +4 -0
  70. package/build/cli/commands/skills/skills/meta.js +10 -0
  71. package/build/cli/commands/system/catalog.js +8 -0
  72. package/build/cli/commands/system/completion/handler.js +10 -0
  73. package/build/cli/commands/system/completion/meta.js +9 -0
  74. package/build/cli/commands/system/dump-env/handler.js +3 -0
  75. package/build/cli/commands/system/dump-env/meta.js +10 -0
  76. package/build/cli/commands/system/guide/handler.js +4 -0
  77. package/build/cli/commands/system/guide/meta.js +9 -0
  78. package/build/cli/commands/task/add/handler.js +21 -0
  79. package/build/cli/commands/task/add/meta.js +8 -0
  80. package/build/cli/commands/task/catalog.js +22 -0
  81. package/build/cli/commands/task/doctor/handler.js +4 -0
  82. package/build/cli/commands/task/doctor/meta.js +8 -0
  83. package/build/cli/commands/task/done/handler.js +17 -0
  84. package/build/cli/commands/task/done/meta.js +8 -0
  85. package/build/cli/commands/task/drop/handler.js +6 -0
  86. package/build/cli/commands/task/drop/meta.js +8 -0
  87. package/build/cli/commands/task/ls/handler.js +13 -0
  88. package/build/cli/commands/task/ls/meta.js +8 -0
  89. package/build/cli/commands/task/shared.js +131 -0
  90. package/build/cli/commands/task/start/handler.js +6 -0
  91. package/build/cli/commands/task/start/meta.js +8 -0
  92. package/build/cli/commands/task/stop/handler.js +17 -0
  93. package/build/cli/commands/task/stop/meta.js +8 -0
  94. package/build/cli/commands/task/task/handler.js +5 -0
  95. package/build/cli/commands/task/task/meta.js +11 -0
  96. package/build/cli/commands/task/update/handler.js +18 -0
  97. package/build/cli/commands/task/update/meta.js +8 -0
  98. package/build/cli/commands/task/view/handler.js +14 -0
  99. package/build/cli/commands/task/view/meta.js +8 -0
  100. package/build/cli/completion.js +26 -27
  101. package/build/cli/flags.js +79 -2
  102. package/build/cli/help.js +27 -49
  103. package/build/cli/index.js +121 -374
  104. package/build/cli/output-stream-error-policy.js +17 -0
  105. package/build/cli/parse.js +159 -72
  106. package/build/cli/projection-address.js +5 -0
  107. package/build/cli/render/arc.js +1 -1
  108. package/build/cli/render/errors.js +4 -3
  109. package/build/cli/render/format.js +14 -0
  110. package/build/cli/render/kanshi.js +106 -0
  111. package/build/cli/render/petition.js +24 -1
  112. package/build/cli/render/projection-activity.js +5 -1
  113. package/build/cli/render/shared.js +2 -2
  114. package/build/cli/render/status.js +79 -13
  115. package/build/cli/render/task.js +113 -0
  116. package/build/cli/render/wait.js +23 -3
  117. package/build/cli/types.js +1 -1
  118. package/build/config/{akuma-loader_v2.js → akuma-loader.js} +2 -2
  119. package/build/config/env.js +9 -4
  120. package/build/config/settings/disease.js +26 -0
  121. package/build/config/settings/knobs.js +8 -0
  122. package/build/config/settings/loader.js +244 -0
  123. package/build/config/settings/schema.js +276 -0
  124. package/build/core/addressing.js +1 -1
  125. package/build/core/amend.js +3 -3
  126. package/build/core/arc.js +5 -4
  127. package/build/core/bind-workspace.js +123 -0
  128. package/build/core/bind.js +75 -155
  129. package/build/core/call/call.js +224 -0
  130. package/build/core/call/context.js +238 -0
  131. package/build/core/call/execution.js +217 -0
  132. package/build/core/call/prompt.js +42 -0
  133. package/build/core/call/reference.js +24 -0
  134. package/build/core/call-persist.js +1 -1
  135. package/build/core/claim-delivery.js +247 -0
  136. package/build/core/claim.js +39 -277
  137. package/build/core/context.js +2 -1
  138. package/build/core/{render.js → contract-view.js} +12 -140
  139. package/build/core/draft.js +107 -9
  140. package/build/core/entry.js +9 -1
  141. package/build/core/execution-coordinate.js +4 -20
  142. package/build/core/execution-pact.js +16 -31
  143. package/build/core/forfeit.js +35 -22
  144. package/build/core/hints.js +2 -2
  145. package/build/core/log.js +2 -2
  146. package/build/core/petition-claim-gates.js +8 -6
  147. package/build/core/petition-preview.js +97 -0
  148. package/build/core/petition-run.js +3 -2
  149. package/build/core/petition.js +39 -26
  150. package/build/core/projection/generation/database.js +306 -0
  151. package/build/core/projection/generation/identity.js +84 -0
  152. package/build/core/projection/generation/model.js +201 -0
  153. package/build/core/projection/generation/store.js +73 -0
  154. package/build/core/projection/generation/transitions.js +258 -0
  155. package/build/core/projection/heart.js +0 -307
  156. package/build/core/projection/tell/database.js +109 -0
  157. package/build/core/projection/tell/model.js +97 -0
  158. package/build/core/{projection-tells.js → projection/tell/store.js} +3 -158
  159. package/build/core/projection-activity.js +23 -2
  160. package/build/core/projection-core.js +2 -1
  161. package/build/core/projection-execution-observer.js +259 -0
  162. package/build/core/projection-generation-continuation.js +1 -1
  163. package/build/core/projection-generation-execution.js +90 -20
  164. package/build/core/projection-generation-launcher.js +1 -1
  165. package/build/core/projection-generation-runner.js +198 -4
  166. package/build/core/projection-identity.js +1 -1
  167. package/build/core/projection-kill.js +50 -17
  168. package/build/core/projection-life-observer.js +1 -1
  169. package/build/core/projection-life-protocol.js +10 -0
  170. package/build/core/projection-mint.js +1 -1
  171. package/build/core/projection-status.js +45 -32
  172. package/build/core/projection-wait.js +12 -2
  173. package/build/core/projection-wake.js +5 -2
  174. package/build/core/{queue_v2.js → queue.js} +2 -1
  175. package/build/core/registry.js +1 -1
  176. package/build/core/renew.js +7 -7
  177. package/build/core/response-artifact-catalog-sqlite.js +112 -0
  178. package/build/core/response-artifact-catalog.js +7 -0
  179. package/build/core/seal.js +44 -16
  180. package/build/core/status/board.js +286 -0
  181. package/build/core/status/drift.js +99 -0
  182. package/build/core/status/lifecycle.js +84 -0
  183. package/build/core/status/reconciliation.js +131 -0
  184. package/build/core/stored-agent-event.js +28 -4
  185. package/build/core/target-ref.js +10 -0
  186. package/build/core/task/board.js +175 -0
  187. package/build/core/task/commands.js +211 -0
  188. package/build/core/task/document.js +189 -0
  189. package/build/core/task/model.js +1 -0
  190. package/build/core/task/settlement-git.js +207 -0
  191. package/build/core/task/settlement-policy.js +82 -0
  192. package/build/core/task/source-board.js +84 -0
  193. package/build/core/task/source-model.js +1 -0
  194. package/build/core/task/validation.js +44 -0
  195. package/build/core/task-contract.js +224 -0
  196. package/build/core/task-doctor.js +14 -0
  197. package/build/core/task-git-actor.js +38 -0
  198. package/build/core/task-git-runtime.js +34 -0
  199. package/build/core/task-git-store.js +375 -0
  200. package/build/core/task-repository.js +1 -0
  201. package/build/core/task-store-repository.js +86 -0
  202. package/build/core/task-store.js +1 -0
  203. package/build/core/task-worktree.js +51 -0
  204. package/build/core/task.js +4 -0
  205. package/build/core/transcripts.js +138 -56
  206. package/build/core/validation.js +17 -0
  207. package/build/core/verdict.js +2 -2
  208. package/build/core/worktree-path.js +24 -6
  209. package/build/flow-error.js +3 -2
  210. package/build/generated/version.js +1 -1
  211. package/build/git/commits.js +3 -0
  212. package/build/git/diff/parsers.js +0 -94
  213. package/build/index.js +2 -0
  214. package/build/keiyaku-constants.js +2 -0
  215. package/build/keiyaku.js +4 -3
  216. package/package.json +3 -2
  217. package/skills/keiyaku/SKILL.md +1 -1
  218. package/skills/keiyaku-akuma/SKILL.md +11 -6
  219. package/build/agents/harness/pump.js +0 -158
  220. package/build/agents/providers/codex-app-server.js +0 -864
  221. package/build/agents/providers/opencode-sdk.js +0 -363
  222. package/build/agents/providers/pi.js +0 -557
  223. package/build/config/settings.js +0 -533
  224. package/build/core/call.js +0 -686
  225. package/build/core/projection/generation.js +0 -412
  226. package/build/core/projection/identity.js +0 -81
  227. package/build/core/projection/mint.js +0 -174
  228. package/build/core/projection-generation-store.js +0 -707
  229. package/build/core/status.js +0 -539
package/build/keiyaku.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import * as path from "path";
2
+ import { ACTOR_IDENTITY, SETTINGS_PATH_SEGMENTS } from "./keiyaku-constants.js";
3
+ export { ACTOR_IDENTITY } from "./keiyaku-constants.js";
2
4
  export const KEIYAKU_FILE = path.join(".keiyaku", "KEIYAKU.md");
3
5
  export const KEIYAKU_DRAFT_DIR = path.join(".keiyaku", "draft");
4
6
  export const RESPONSE_HISTORY_DIR = path.join(".keiyaku", "response");
@@ -13,7 +15,6 @@ export const TOOL_NAMES = {
13
15
  status: "status",
14
16
  help: "help",
15
17
  };
16
- export const ACTOR_IDENTITY = "Akuma";
17
18
  export const ACTOR_IDENTITY_PLURAL = `${ACTOR_IDENTITY}s`;
18
19
  function formatArtifactDirectory(directory) {
19
20
  return `\`${directory}/\``;
@@ -35,7 +36,7 @@ export const DRAFT_ARTIFACT_NOTICE = buildArtifactNotice(KEIYAKU_ARTIFACT_DIRS[0
35
36
  export const RESPONSE_ARTIFACT_NOTICE = buildArtifactNotice(KEIYAKU_ARTIFACT_DIRS[1]);
36
37
  export const KEIYAKU_BRANCH_PREFIX = "keiyaku/";
37
38
  export const BASE_RULES_FILE = path.join(".keiyaku", "base-rules.md");
38
- export const SETTINGS_FILE = path.join(".keiyaku", "settings.json");
39
+ export const SETTINGS_FILE = path.join(...SETTINGS_PATH_SEGMENTS);
39
40
  export const SUBAGENT_PROVIDERS = [
40
41
  "codex-sdk",
41
42
  "codex-app-server",
@@ -50,7 +51,7 @@ export const CODEX_MODEL_REASONING_EFFORT_CONFIG_KEY = "model_reasoning_effort";
50
51
  export const BUILTIN_AGENT_NAMES = ["akuma-codex", "akuma-claude"];
51
52
  export const DEFAULT_AGENT_NAME = "akuma-codex";
52
53
  export const BUILTIN_AGENT_PROFILES = {
53
- "akuma-codex": { provider: "codex-sdk", description: "Default Codex SDK Akuma." },
54
+ "akuma-codex": { provider: "codex-sdk", description: "Deprecated Codex SDK Akuma; use codex-app-server." },
54
55
  "akuma-claude": { provider: "claude-agent-sdk", description: "Default Claude Agent SDK Akuma." },
55
56
  };
56
57
  export const CLAUDE_PERMISSION_MODES = ["default", "acceptEdits", "bypassPermissions", "plan", "dontAsk", "auto"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/keiyaku",
3
- "version": "2.8.4",
3
+ "version": "2.9.0",
4
4
  "description": "CLI for running iterative keiyaku workflows with Codex subagents.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -51,8 +51,9 @@
51
51
  "@earendil-works/pi-coding-agent": "^0.80.10",
52
52
  "@modelcontextprotocol/sdk": "^1.29.0",
53
53
  "@openai/codex-sdk": "^0.113.0",
54
- "@opencode-ai/sdk": "1.17.20",
54
+ "@opencode-ai/sdk": "1.18.3",
55
55
  "simple-git": "^3.21.0",
56
+ "yaml": "^2.9.0",
56
57
  "zod": "4.3.6"
57
58
  },
58
59
  "devDependencies": {
@@ -19,7 +19,7 @@ Akuma call/tell/wait/revive lifecycle is owned by the `keiyaku-akuma` skill. Loa
19
19
 
20
20
  ## Basic Flow
21
21
 
22
- For committed delivery work, bind the contract, open an arc before implementation, commit delivery work, amend when the governing contract changes, renew when the base drifts, and petition only after the delivery is ready for settlement. Opening another arc seals the current one; petition also seals an open arc, so no extra closing arc is needed.
22
+ The small/default workflow is bind, commit delivery work, then petition. Bind supplies derived default intent a0. Arc is optional for multiple intent iterations: the first explicit arc seals a0, and a later arc seals the current explicit arc. Renew when the base drifts; renew and petition seal the current a0 or open explicit arc. After an explicit arc closes, loose commits require another arc before renew or petition. Amend when the governing contract changes.
23
23
 
24
24
  Use `status` to inspect the Kanshi board and `forfeit` to archive abandoned work. Consult command help for their syntax and flags.
25
25
 
@@ -7,7 +7,7 @@ allowed-tools: Bash(keiyaku *)
7
7
  # Keiyaku Akuma
8
8
 
9
9
  ```bash
10
- keiyaku akuma list
10
+ keiyaku akuma ls
11
11
  keiyaku <command> --help
12
12
  ```
13
13
 
@@ -23,17 +23,22 @@ Contract work = `keiyaku` skill. This skill = helpers only.
23
23
  ## Daily path
24
24
 
25
25
  ```bash
26
- keiyaku call NAME "task..." # launch + foreground join (no CLI --timeout)
26
+ keiyaku call NAME "task..." # required literal BODY; launch + foreground join
27
27
  keiyaku call NAME --detach "task..." # return after launch; keep projection id
28
+ keiyaku call NAME - < prompt.md # only literal `-` opens stdin
28
29
  keiyaku wait <projection-id> # join until terminal; prints activity list
29
30
  keiyaku wait <projection-id> --timeout 5m # bounded join; timeout keeps projection alive
30
- keiyaku tell <projection-id> "more..." # mailbox only; does not wait
31
+ keiyaku tell <projection-id> "more..." # required literal BODY; mailbox only
32
+ keiyaku tell <projection-id> - < direction.md # explicit stdin body; `-` is never delivered
33
+ keiyaku tell <projection-id> --wait 5m "more..." # no mandatory `--` before BODY
31
34
  keiyaku wait <projection-id> --timeout 10m # after tell, rejoin to see progress/outcome
32
35
  keiyaku status # board + compact activity summary; rediscover ids
33
- keiyaku revive ARTIFACT_ID # new life from saved answer
36
+ keiyaku revive ARTIFACT_ID # omit body → default continuation
37
+ keiyaku revive ARTIFACT_ID "continue..." # literal BODY
38
+ keiyaku revive ARTIFACT_ID - < cont.md # explicit `-` stdin; blank fails
34
39
  ```
35
40
 
36
- Long prompt: `keiyaku call NAME - < prompt.md`
41
+ Long body: `keiyaku call NAME - < prompt.md` or `keiyaku tell PROJECTION - < direction.md`. Never omit call/tell body and hope for piped stdin.
37
42
 
38
43
  ## Timeouts (do not confuse)
39
44
 
@@ -72,4 +77,4 @@ Lost the outer handle → `status` to find projection id → `wait` for the list
72
77
  - `--bare` — skip contract attachment only (call only)
73
78
  - `--effort LEVEL` — override opaque provider-native effort value (call, revive, tell); must match profile allowlist when set
74
79
 
75
- Profiles: `keiyaku akuma list|show`; user `<KEIYAKU_HOME>/akuma/`, project `.keiyaku/akuma/`.
80
+ Profiles: `keiyaku akuma ls|view`; user `<KEIYAKU_HOME>/akuma/`, project `.keiyaku/akuma/`.
@@ -1,158 +0,0 @@
1
- import { claimAllInbox, claimFencedTells, listTellIds, markTellSubmitted, markTellConsumed, readTellSubmitted, readTellOriginal, isTellCausallyConsumed, appendGenerationEvent, } from "../../core/projection-core.js";
2
- import { prepareAgentEventForPersistence, } from "./execution-handle.js";
3
- const OPERATOR_PROMPT_MARKER = "[Operator prompt]\n";
4
- function frameTellBodies(projectionDirectory, tellIds) {
5
- const originals = tellIds.map((tellId) => readTellOriginal(projectionDirectory, "inflight", tellId));
6
- const frames = originals
7
- .map((original, index) => `--- tell ${tellIds[index]} ---\n${original.text}`)
8
- .join("\n\n");
9
- const effort = originals.reduce((value, original) => original.effort ?? value, undefined);
10
- return { frames, ...(effort ? { effort } : {}) };
11
- }
12
- function operatorBodyForContinuation(prompt, tellFrames, sessionContinuation) {
13
- if (!sessionContinuation)
14
- return `${prompt}\n\n${tellFrames}`;
15
- const markerAt = prompt.indexOf(OPERATOR_PROMPT_MARKER);
16
- if (markerAt >= 0) {
17
- return `${prompt.slice(0, markerAt + OPERATOR_PROMPT_MARKER.length)}${tellFrames}`;
18
- }
19
- return tellFrames;
20
- }
21
- /** Tier-2 boundary snapshot. No tells leaves prompt byte-identical. */
22
- export function snapshotReplayPrompt(projectionDirectory, prompt, tellFence, executionId, options = {}) {
23
- const tellIds = claimFencedTells(projectionDirectory, tellFence, executionId);
24
- if (tellIds.length === 0)
25
- return { prompt, tellIds };
26
- const { frames, effort } = frameTellBodies(projectionDirectory, tellIds);
27
- const nextPrompt = operatorBodyForContinuation(prompt, frames, options.sessionContinuation === true);
28
- return { prompt: nextPrompt, tellIds, ...(effort ? { effort } : {}) };
29
- }
30
- /** Tier-2 has no steer acknowledgement: actual driver start is its ordinal-zero submission point. */
31
- export function markReplayStarted(projectionDirectory, executionId, tellIds) {
32
- for (const tellId of tellIds) {
33
- if (listTellIds(projectionDirectory, "inflight").includes(tellId)) {
34
- markTellSubmitted(projectionDirectory, tellId, { executionId, fence: { kind: "ordinal", ordinal: 0 } });
35
- }
36
- }
37
- }
38
- /** A successful replay terminal is checkpoint ordinal one; failures intentionally do not consume. */
39
- export function markReplayCompleted(projectionDirectory, executionId) {
40
- for (const tellId of listTellIds(projectionDirectory, "submitted")) {
41
- const submitted = readTellSubmitted(projectionDirectory, tellId);
42
- if (submitted.executionId === executionId && submitted.fence && isTellCausallyConsumed(submitted.fence, { kind: "ordinal", ordinal: 1 })) {
43
- markTellConsumed(projectionDirectory, tellId);
44
- }
45
- }
46
- }
47
- /**
48
- * Tier-2's only submission acknowledgement. A created driver is deliberately
49
- * insufficient: observe the first provider event, or a successful completion
50
- * from a provider that emitted no events.
51
- */
52
- export function createReplayRunStartGate(projectionDirectory, executionId, tellIds) {
53
- let started = false;
54
- const start = () => {
55
- if (started)
56
- return;
57
- markReplayStarted(projectionDirectory, executionId, tellIds);
58
- started = true;
59
- };
60
- return { observeProviderEvent: start, observeSuccessfulCompletion: start };
61
- }
62
- /**
63
- * Supervisor pump: iterates handle.events, forwards to publicChannel,
64
- * persists public events and checks the tell ledger at checkpoints.
65
- */
66
- export async function pumpSupervisor(handle, projectionDirectory, executionId, publicChannel, callbacks = {}, dependencies = {}) {
67
- let persistenceEnabled = true;
68
- let persistenceDiagnosticQueued = false;
69
- const pendingDiagnostics = [];
70
- const appendEvent = dependencies.appendGenerationEvent ?? appendGenerationEvent;
71
- const dispatch = (event, persist = true) => {
72
- if (persist && persistenceEnabled) {
73
- try {
74
- appendEvent(projectionDirectory, executionId, prepareAgentEventForPersistence(event));
75
- }
76
- catch (error) {
77
- persistenceEnabled = false;
78
- if (!persistenceDiagnosticQueued) {
79
- persistenceDiagnosticQueued = true;
80
- pendingDiagnostics.push({
81
- text: `event persistence degraded: ${String(error)}`,
82
- persist: false,
83
- });
84
- }
85
- }
86
- }
87
- publicChannel.push(event);
88
- callbacks.onEvent?.(event);
89
- };
90
- try {
91
- for await (const event of handle.events) {
92
- dispatch(event);
93
- }
94
- }
95
- catch (error) {
96
- if (error instanceof Error && error.code === "PROJECTION_STATE_ERROR") {
97
- const event = handle.mintEvent({
98
- type: "fail",
99
- code: "PROJECTION_STATE_ERROR",
100
- message: error.message,
101
- });
102
- if (event)
103
- dispatch(event);
104
- }
105
- else {
106
- const event = handle.mintEvent({
107
- type: "diagnostic",
108
- text: `pump error: ${String(error)}`,
109
- });
110
- if (event)
111
- dispatch(event);
112
- }
113
- }
114
- for (const pending of pendingDiagnostics) {
115
- const event = handle.mintEvent({ type: "diagnostic", text: pending.text });
116
- if (event)
117
- dispatch(event, pending.persist);
118
- }
119
- }
120
- /**
121
- * Build an onSyncCheckpoint callback that claims all inbox tells
122
- * and delivers them via the given SteerControl.
123
- * Intended for use inside adapter start() calls as the onSyncCheckpoint callback.
124
- */
125
- export function buildSyncCheckpointCallback(projectionDirectory, executionId) {
126
- const submitting = new Set();
127
- return (control, checkpoint) => {
128
- claimAllInbox(projectionDirectory);
129
- for (const tellId of listTellIds(projectionDirectory, "inflight")) {
130
- if (submitting.has(tellId))
131
- continue;
132
- submitting.add(tellId);
133
- const original = readTellOriginal(projectionDirectory, "inflight", tellId);
134
- const originalText = original.text;
135
- const tell = {
136
- id: tellId,
137
- text: `--- tell ${tellId} ---\n${originalText}`,
138
- ...(original.effort ? { effort: original.effort } : {}),
139
- };
140
- void control.enqueue(tell)
141
- .then((ack) => {
142
- if (!ack)
143
- throw new Error("provider enqueue resolved without TellSubmitAck");
144
- markTellSubmitted(projectionDirectory, tellId, { executionId, fence: ack.fence });
145
- })
146
- .catch(() => {
147
- // Leave in inflight for the next checkpoint.
148
- })
149
- .finally(() => submitting.delete(tellId));
150
- }
151
- for (const tellId of listTellIds(projectionDirectory, "submitted")) {
152
- const submitted = readTellSubmitted(projectionDirectory, tellId);
153
- if (submitted.executionId === executionId && submitted.fence && isTellCausallyConsumed(submitted.fence, checkpoint.fence)) {
154
- markTellConsumed(projectionDirectory, tellId);
155
- }
156
- }
157
- };
158
- }