@astrosheep/keiyaku 4.5.11 → 4.5.13

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 (272) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +135 -377
  2. package/build/integrations/pi/keiyaku.ts +11 -116
  3. package/build/src/akuma/akuma-errors.d.ts +1 -0
  4. package/build/src/akuma/akuma-errors.js +1 -0
  5. package/build/src/akuma/akuma-handle.d.ts +1 -0
  6. package/build/src/akuma/akuma-handle.js +6 -7
  7. package/build/src/akuma/akuma-product.d.ts +6 -8
  8. package/build/src/akuma/akuma-product.js +141 -57
  9. package/build/src/akuma/akuma.d.ts +5 -7
  10. package/build/src/akuma/akuma.js +1 -22
  11. package/build/src/akuma/archetype.d.ts +6 -5
  12. package/build/src/akuma/archetype.js +137 -38
  13. package/build/src/akuma/body.d.ts +5 -5
  14. package/build/src/akuma/body.js +223 -63
  15. package/build/src/akuma/call-input.d.ts +4 -0
  16. package/build/src/akuma/call-input.js +21 -0
  17. package/build/src/akuma/call-request.d.ts +5 -8
  18. package/build/src/akuma/call-request.js +28 -73
  19. package/build/src/akuma/fleet-execution.d.ts +26 -0
  20. package/build/src/akuma/fleet-execution.js +109 -0
  21. package/build/src/{library/fleet-result.d.ts → akuma/fleet-observation.d.ts} +13 -57
  22. package/build/src/{library/fleet-result.js → akuma/fleet-observation.js} +4 -25
  23. package/build/src/akuma/fleet-request.d.ts +122 -0
  24. package/build/src/akuma/fleet-request.js +168 -0
  25. package/build/src/akuma/heart/facts.d.ts +23 -0
  26. package/build/src/akuma/heart/facts.js +7 -0
  27. package/build/src/akuma/heart/index.d.ts +43 -4
  28. package/build/src/akuma/heart/index.js +107 -7
  29. package/build/src/akuma/heart/request-authority.d.ts +2 -0
  30. package/build/src/akuma/heart/request-authority.js +28 -3
  31. package/build/src/akuma/heart/request-rows.d.ts +2 -0
  32. package/build/src/akuma/heart/request-rows.js +24 -5
  33. package/build/src/akuma/heart/rows.d.ts +4 -1
  34. package/build/src/akuma/heart/rows.js +46 -19
  35. package/build/src/akuma/heart/schema.d.ts +1 -1
  36. package/build/src/akuma/heart/schema.js +28 -6
  37. package/build/src/akuma/heart/storage.d.ts +1 -1
  38. package/build/src/akuma/heart/tells.d.ts +29 -0
  39. package/build/src/akuma/heart/tells.js +136 -5
  40. package/build/src/akuma/heart/timeline.js +9 -3
  41. package/build/src/akuma/projection-read.js +36 -3
  42. package/build/src/akuma/projection.js +3 -4
  43. package/build/src/akuma/provider.d.ts +4 -0
  44. package/build/src/akuma/provider.js +56 -3
  45. package/build/src/akuma/providers/claude/index.js +3 -0
  46. package/build/src/akuma/providers/codex-app-server/index.js +14 -12
  47. package/build/src/akuma/providers/pi/index.js +7 -1
  48. package/build/src/akuma/publication.js +65 -49
  49. package/build/src/akuma/request-lifecycle.d.ts +5 -4
  50. package/build/src/akuma/request-lifecycle.js +29 -16
  51. package/build/src/akuma/request-rendezvous.d.ts +15 -12
  52. package/build/src/akuma/request-rendezvous.js +80 -51
  53. package/build/src/akuma/request-serve.d.ts +1 -2
  54. package/build/src/akuma/request-serve.js +94 -39
  55. package/build/src/akuma/request-wire.d.ts +57 -26
  56. package/build/src/akuma/request-wire.js +64 -25
  57. package/build/src/akuma/turn-drive.d.ts +5 -4
  58. package/build/src/akuma/turn-drive.js +27 -11
  59. package/build/src/akuma-body.d.ts +4 -6
  60. package/build/src/akuma-body.js +19 -17
  61. package/build/src/bounded-list.d.ts +8 -0
  62. package/build/src/bounded-list.js +14 -0
  63. package/build/src/cli/accepted.d.ts +1 -1
  64. package/build/src/cli/accepted.js +1 -0
  65. package/build/src/cli/commands/akuma-invoke.js +1 -25
  66. package/build/src/cli/commands/contract-help.d.ts +5 -2
  67. package/build/src/cli/commands/contract-help.js +62 -12
  68. package/build/src/cli/commands/contract-invoke.d.ts +5 -0
  69. package/build/src/cli/commands/contract-invoke.js +26 -1
  70. package/build/src/cli/commands/contract.js +50 -18
  71. package/build/src/cli/commands/task-invoke.js +10 -2
  72. package/build/src/cli/commands/task-query.js +3 -4
  73. package/build/src/cli/coordinates.d.ts +13 -0
  74. package/build/src/cli/coordinates.js +38 -24
  75. package/build/src/cli/draft.d.ts +1 -1
  76. package/build/src/cli/invoke.js +14 -1
  77. package/build/src/cli/render/akuma-activity.d.ts +0 -1
  78. package/build/src/cli/render/akuma-activity.js +5 -38
  79. package/build/src/cli/render/akuma.js +4 -1
  80. package/build/src/cli/render/audit.js +4 -1
  81. package/build/src/cli/render/catalog.js +13 -39
  82. package/build/src/cli/render/contract.js +4 -14
  83. package/build/src/cli/render/kanshi-akuma.js +3 -8
  84. package/build/src/cli/render/kanshi.js +8 -34
  85. package/build/src/cli/render/nuke.js +7 -3
  86. package/build/src/cli/render/receipt.d.ts +1 -0
  87. package/build/src/cli/render/receipt.js +8 -0
  88. package/build/src/cli/render/refusal.js +4 -3
  89. package/build/src/cli/render/task.js +4 -37
  90. package/build/src/cli/render/terminal.d.ts +2 -6
  91. package/build/src/cli/render/terminal.js +4 -9
  92. package/build/src/cli/result.d.ts +2 -1
  93. package/build/src/contract-guidance.js +13 -3
  94. package/build/src/contract-worktree.d.ts +1 -0
  95. package/build/src/contract-worktree.js +26 -2
  96. package/build/src/core/facts/codec.d.ts +2 -1
  97. package/build/src/core/facts/codec.js +3 -0
  98. package/build/src/core/facts/gate.d.ts +2 -1
  99. package/build/src/core/facts/gate.js +63 -0
  100. package/build/src/core/verbs/abandon.d.ts +2 -1
  101. package/build/src/core/verbs/abandon.js +16 -0
  102. package/build/src/core/verbs/amend.d.ts +2 -1
  103. package/build/src/core/verbs/amend.js +20 -0
  104. package/build/src/core/verbs/arc.d.ts +2 -1
  105. package/build/src/core/verbs/arc.js +16 -0
  106. package/build/src/core/verbs/attestation.d.ts +2 -1
  107. package/build/src/core/verbs/attestation.js +16 -0
  108. package/build/src/core/verbs/bind.d.ts +2 -1
  109. package/build/src/core/verbs/bind.js +16 -0
  110. package/build/src/core/verbs/deliver.d.ts +2 -1
  111. package/build/src/core/verbs/deliver.js +16 -0
  112. package/build/src/core/verbs/placement.d.ts +2 -1
  113. package/build/src/core/verbs/placement.js +58 -1
  114. package/build/src/dispatch/association.d.ts +13 -0
  115. package/build/src/dispatch/association.js +20 -0
  116. package/build/src/dispatch/index.d.ts +6 -0
  117. package/build/src/dispatch/index.js +27 -3
  118. package/build/src/git/hooks.d.ts +9 -1
  119. package/build/src/git/hooks.js +79 -1
  120. package/build/src/git/nuke.d.ts +2 -1
  121. package/build/src/git/nuke.js +6 -11
  122. package/build/src/git/private-state-seat.d.ts +26 -1
  123. package/build/src/git/private-state-seat.js +78 -13
  124. package/build/src/git/process.d.ts +2 -0
  125. package/build/src/git/reconcile.d.ts +1 -2
  126. package/build/src/git/reconcile.js +0 -6
  127. package/build/src/git/repository.d.ts +0 -2
  128. package/build/src/git/repository.js +27 -25
  129. package/build/src/git/result-codec.d.ts +29 -0
  130. package/build/src/git/result-codec.js +306 -0
  131. package/build/src/git/target-placement.js +2 -8
  132. package/build/src/git/workspace.d.ts +2 -0
  133. package/build/src/git/workspace.js +4 -0
  134. package/build/src/index.d.ts +1 -0
  135. package/build/src/kanshi/fleet.js +1 -1
  136. package/build/src/kanshi/read.js +55 -28
  137. package/build/src/kanshi/report.d.ts +4 -3
  138. package/build/src/kanshi/select.js +14 -1
  139. package/build/src/library/address.d.ts +1 -0
  140. package/build/src/library/address.js +4 -7
  141. package/build/src/library/akuma-creation.d.ts +5 -3
  142. package/build/src/library/akuma-creation.js +90 -33
  143. package/build/src/library/audit.js +2 -1
  144. package/build/src/library/catalog.d.ts +10 -2
  145. package/build/src/library/catalog.js +65 -25
  146. package/build/src/library/composition.d.ts +1 -0
  147. package/build/src/library/composition.js +1 -0
  148. package/build/src/library/configuration.d.ts +4 -21
  149. package/build/src/library/configuration.js +2 -158
  150. package/build/src/library/continuation.d.ts +20 -1
  151. package/build/src/library/continuation.js +36 -0
  152. package/build/src/library/contract-bind.d.ts +1 -0
  153. package/build/src/library/contract-bind.js +16 -5
  154. package/build/src/library/contract-forwarding.d.ts +2 -2
  155. package/build/src/library/contract-forwarding.js +18 -4
  156. package/build/src/library/contract-handle.js +4 -3
  157. package/build/src/library/contract-operations.d.ts +5 -9
  158. package/build/src/library/contract-operations.js +34 -47
  159. package/build/src/library/contract.d.ts +11 -2
  160. package/build/src/library/contract.js +21 -1
  161. package/build/src/library/delivery.d.ts +4 -1
  162. package/build/src/library/delivery.js +47 -0
  163. package/build/src/library/fleet.d.ts +4 -136
  164. package/build/src/library/fleet.js +31 -315
  165. package/build/src/library/keiyaku.d.ts +7 -3
  166. package/build/src/library/keiyaku.js +1 -0
  167. package/build/src/library/mutation.d.ts +431 -3
  168. package/build/src/library/mutation.js +192 -19
  169. package/build/src/library/nuke.d.ts +7 -1
  170. package/build/src/library/nuke.js +18 -4
  171. package/build/src/library/reconcile.d.ts +14 -0
  172. package/build/src/library/reconcile.js +22 -8
  173. package/build/src/library/refusal.d.ts +9 -1
  174. package/build/src/library/refusal.js +76 -0
  175. package/build/src/library/region.d.ts +0 -8
  176. package/build/src/library/region.js +1 -29
  177. package/build/src/library/result-codec.d.ts +2 -0
  178. package/build/src/library/result-codec.js +12 -0
  179. package/build/src/markdown/lex.js +9 -2
  180. package/build/src/markdown/types.d.ts +2 -1
  181. package/build/src/markdown/types.js +3 -1
  182. package/build/src/plugin/akuma-signals.d.ts +12 -0
  183. package/build/src/plugin/akuma-signals.js +14 -0
  184. package/build/src/plugin/public.d.ts +51 -0
  185. package/build/src/plugin/public.js +1 -0
  186. package/build/src/plugin/runtime.d.ts +14 -0
  187. package/build/src/plugin/runtime.js +357 -0
  188. package/build/src/protocol/amend.js +3 -3
  189. package/build/src/protocol/attempt.d.ts +2 -1
  190. package/build/src/protocol/attempt.js +1 -1
  191. package/build/src/protocol/audit.d.ts +1 -1
  192. package/build/src/protocol/audit.js +1 -1
  193. package/build/src/protocol/bind.d.ts +3 -1
  194. package/build/src/protocol/bind.js +26 -0
  195. package/build/src/protocol/completion.js +0 -1
  196. package/build/src/protocol/deliver.d.ts +1 -1
  197. package/build/src/protocol/deliver.js +136 -57
  198. package/build/src/protocol/intent.d.ts +0 -1
  199. package/build/src/protocol/intent.js +0 -1
  200. package/build/src/protocol/operations.d.ts +9 -2
  201. package/build/src/protocol/operations.js +16 -1
  202. package/build/src/protocol/outcome.d.ts +3 -0
  203. package/build/src/protocol/outcome.js +17 -1
  204. package/build/src/protocol/placement.js +10 -3
  205. package/build/src/protocol/read/status.d.ts +8 -0
  206. package/build/src/protocol/read/status.js +49 -0
  207. package/build/src/protocol/reintegrate.js +10 -3
  208. package/build/src/protocol/result-codec.d.ts +22 -0
  209. package/build/src/protocol/result-codec.js +442 -0
  210. package/build/src/protocol/review.d.ts +1 -1
  211. package/build/src/protocol/review.js +81 -46
  212. package/build/src/protocol/run.d.ts +22 -2
  213. package/build/src/protocol/run.js +119 -29
  214. package/build/src/runtime/proc/lifecycle.js +1 -1
  215. package/build/src/runtime/proc/line-rpc.d.ts +7 -1
  216. package/build/src/runtime/proc/line-rpc.js +49 -9
  217. package/build/src/runtime/proc/run.d.ts +0 -1
  218. package/build/src/runtime/proc/run.js +1 -11
  219. package/build/src/runtime/proc/termination.d.ts +1 -0
  220. package/build/src/runtime/proc/termination.js +63 -18
  221. package/build/src/runtime/proc/windows-launch.exe +0 -0
  222. package/build/src/settings.d.ts +10 -0
  223. package/build/src/settings.js +88 -2
  224. package/build/src/settlement/result-codec.d.ts +2 -0
  225. package/build/src/settlement/result-codec.js +56 -0
  226. package/build/src/settlement/settle.d.ts +5 -12
  227. package/build/src/settlement/settle.js +60 -55
  228. package/build/src/task/board.d.ts +3 -0
  229. package/build/src/task/board.js +22 -4
  230. package/build/src/task/catalog.d.ts +13 -2
  231. package/build/src/task/catalog.js +59 -5
  232. package/build/src/task/compose.d.ts +4 -2
  233. package/build/src/task/compose.js +56 -30
  234. package/build/src/task/created-observation.d.ts +39 -0
  235. package/build/src/task/created-observation.js +26 -0
  236. package/build/src/task/identity.d.ts +6 -0
  237. package/build/src/task/identity.js +48 -7
  238. package/build/src/task/index.d.ts +4 -3
  239. package/build/src/task/index.js +19 -16
  240. package/build/src/task/input.d.ts +3 -1
  241. package/build/src/task/input.js +7 -4
  242. package/build/src/task/lifecycle-operations.d.ts +6 -0
  243. package/build/src/task/lifecycle-operations.js +116 -0
  244. package/build/src/task/mutation-result.d.ts +762 -20
  245. package/build/src/task/mutation-result.js +34 -9
  246. package/build/src/task/mutation.d.ts +4 -9
  247. package/build/src/task/mutation.js +17 -52
  248. package/build/src/task/operation-types.d.ts +114 -0
  249. package/build/src/task/operation-types.js +1 -0
  250. package/build/src/task/operations.d.ts +6 -113
  251. package/build/src/task/operations.js +75 -117
  252. package/build/src/task/query.d.ts +8 -11
  253. package/build/src/task/query.js +7 -14
  254. package/build/src/task/store.d.ts +11 -1
  255. package/build/src/task/store.js +169 -55
  256. package/build/src/task/view.d.ts +4 -0
  257. package/build/src/task/view.js +7 -0
  258. package/build/src/verification/declaration.d.ts +1 -0
  259. package/build/src/verification/declaration.js +18 -1
  260. package/build/src/verification/execution.d.ts +0 -1
  261. package/build/src/verification/execution.js +5 -5
  262. package/build/src/world.d.ts +0 -2
  263. package/build/src/world.js +3 -7
  264. package/package.json +17 -5
  265. package/build/src/cli/square-edge.d.ts +0 -7
  266. package/build/src/cli/square-edge.js +0 -159
  267. package/build/src/git/ref-migration.d.ts +0 -22
  268. package/build/src/git/ref-migration.js +0 -55
  269. package/build/src/library/contract-forwarding-reconciliation-result.d.ts +0 -102
  270. package/build/src/library/contract-forwarding-reconciliation-result.js +0 -92
  271. package/build/src/library/contract-forwarding-result.d.ts +0 -4270
  272. package/build/src/library/contract-forwarding-result.js +0 -521
@@ -2,4 +2,5 @@ export * from "./library/keiyaku.js";
2
2
  export { settings } from "./settings.js";
3
3
  export { World, WorldError } from "./world.js";
4
4
  export type { WorldResolution, WorldResolutionInput, WorldRoot } from "./world.js";
5
+ export type { KeiyakuPlugin, PluginContext, PluginHooks, PluginInstance, PluginManifest, PluginOutcome, PluginSignal, PluginSignalMap, } from "./plugin/public.js";
5
6
  export type { Settings, SettingsEntry, SettingsInput, SettingsNamespaceFailure, SettingsNamespaceView, SettingsScope, SettingsScopeState, } from "./settings.js";
@@ -16,7 +16,7 @@ export function visibleFleetRows(rows) {
16
16
  const leftAt = fleetUpdatedAt(left);
17
17
  const rightAt = fleetUpdatedAt(right);
18
18
  if (leftAt === rightAt)
19
- return 0;
19
+ return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
20
20
  if (leftAt === null)
21
21
  return 1;
22
22
  if (rightAt === null)
@@ -1,19 +1,21 @@
1
1
  import { Repo } from "../library/repo.js";
2
2
  import { scopeForRepo } from "../library/repo.js";
3
3
  import { observeTaskBoard } from "../task/operations.js";
4
- import { contractNamespace } from "../settlement/settle.js";
4
+ import { contractNamespace } from "../task/identity.js";
5
5
  import { Akuma } from "../akuma/index.js";
6
6
  import { readAliases } from "../alias/index.js";
7
7
  import { readDispatchesAt } from "../dispatch/index.js";
8
8
  import { readTaskHolderProjectionAt } from "../settlement/holder.js";
9
9
  import { observeCurrentPhysicalIssue } from "../protocol/read/observation.js";
10
- import { readContractBoard } from "../protocol/read/status.js";
10
+ import { readContractBoard, readContractCatalogue } from "../protocol/read/status.js";
11
11
  import { withGitDecodeChannel, withGitReadObservation } from "../git/read-observation.js";
12
+ import { decodeContractDocument } from "../body/decode.js";
13
+ import { assertRegionPattern } from "../body/region.js";
12
14
  import { readDocuments } from "../protocol/read/documents.js";
13
- import { readRegionDeclarations, validateRegionPatterns } from "../library/region.js";
14
15
  import { contractId } from "../core/facts/types.js";
15
16
  import { selectKanshi, selectRegion } from "./select.js";
16
- import { FLEET_SNAPSHOT_ROWS, visibleFleetRows } from "./fleet.js";
17
+ import { FLEET_SNAPSHOT_ROWS, FLEET_VISIBLE_ROWS } from "./fleet.js";
18
+ import { observeRecentTaskStatus } from "../task/index.js";
17
19
  function diagnostic(error) {
18
20
  let source;
19
21
  if (error instanceof Error)
@@ -41,6 +43,21 @@ function exactKeys(value, allowed, label) {
41
43
  if (!allowed.includes(key))
42
44
  throw new TypeError(`kanshi ${label} has unknown field: ${key}`);
43
45
  }
46
+ function validateRegionPatterns(patterns) {
47
+ if (!Array.isArray(patterns) || patterns.length === 0)
48
+ throw new Error("Region query requires one or more path patterns");
49
+ return patterns.map((pattern) => {
50
+ if (typeof pattern !== "string")
51
+ throw new Error("Region path patterns must be strings");
52
+ return assertRegionPattern(pattern);
53
+ });
54
+ }
55
+ function readRegionDeclarations(documents) {
56
+ return documents.map((document) => ({
57
+ contract: document.contract,
58
+ patterns: decodeContractDocument(document.documentBytes).region,
59
+ }));
60
+ }
44
61
  function regionSelection(value) {
45
62
  const selection = record(value, "region selection");
46
63
  if (typeof selection.kind !== "string")
@@ -115,7 +132,9 @@ async function readContracts(observation, include) {
115
132
  try {
116
133
  return {
117
134
  kind: "present",
118
- value: await readContractBoard(observation, include),
135
+ value: include === undefined
136
+ ? await readContractCatalogue(observation, 10)
137
+ : await readContractBoard(observation, include),
119
138
  };
120
139
  }
121
140
  catch (error) {
@@ -159,15 +178,20 @@ function decorateContracts(contracts, holders, namespaceTasks) {
159
178
  value: {
160
179
  ...contracts.value,
161
180
  rows: contracts.value.rows.map((row) => {
162
- const selected = namespaceTasks(row.id);
181
+ const selected = namespaceTasks?.(row.id);
163
182
  if (holders.kind === "failed") {
164
- return { ...row, holder: { kind: "unavailable" }, fleet: [], namespaceTasks: selected };
183
+ return {
184
+ ...row,
185
+ holder: { kind: "unavailable" },
186
+ fleet: [],
187
+ ...(selected === undefined ? {} : { namespaceTasks: selected }),
188
+ };
165
189
  }
166
190
  const holder = holders.kind === "present" ? holders.value.get(row.id) : undefined;
167
191
  return {
168
192
  ...row,
169
193
  fleet: [],
170
- namespaceTasks: selected,
194
+ ...(selected === undefined ? {} : { namespaceTasks: selected }),
171
195
  holder: holder?.disposition === "held"
172
196
  ? { kind: "held", taskId: holder.taskId }
173
197
  : { kind: "none" },
@@ -177,10 +201,15 @@ function decorateContracts(contracts, holders, namespaceTasks) {
177
201
  };
178
202
  }
179
203
  function contractEndpointObserver(contracts) {
180
- const dispositions = contracts.kind === "present"
181
- ? new Map(contracts.value.rows.map((row) => [row.id, row.disposition]))
182
- : null;
183
- return (id) => (dispositions === null ? "unavailable" : (dispositions.get(id) ?? "missing"));
204
+ if (contracts.kind !== "present")
205
+ return () => "unavailable";
206
+ const dispositions = new Map(contracts.value.rows.map((row) => [row.id, row.disposition]));
207
+ return (id) => {
208
+ const disposition = dispositions.get(id);
209
+ if (disposition !== undefined)
210
+ return disposition;
211
+ return "hasMore" in contracts.value ? "unavailable" : "missing";
212
+ };
184
213
  }
185
214
  function joinTasks(rows, holders, observeContract) {
186
215
  const associations = new Map(holders.kind === "present"
@@ -212,23 +241,19 @@ function namespaceTaskSection(board, id) {
212
241
  return { kind: "failed", failure: board.failure };
213
242
  return { kind: "present", value: board.observation.selectNamespace(contractNamespace(id)) };
214
243
  }
215
- function readTasks(path, board, holders, observeContract) {
244
+ async function readTasks(path, holders, observeContract) {
216
245
  if (holders.kind === "failed")
217
246
  return { kind: "failed", failure: holders.failure };
218
- if (board.kind === "failed")
219
- return { kind: "failed", failure: board.failure };
220
- if (board.kind === "absent")
221
- return { kind: "absent" };
222
- return {
247
+ return observeRecentTaskStatus(path, { limit: 10 }).then((recent) => ({
223
248
  kind: "present",
224
- value: { root: path, rows: joinTasks(board.observation.statusRows, holders, observeContract) },
225
- };
249
+ value: { root: path, hasMore: recent.hasMore, rows: joinTasks(recent.rows, holders, observeContract) },
250
+ }), (error) => ({ kind: "failed", failure: { message: diagnostic(error) } }));
226
251
  }
227
252
  async function joinAkuma(path, observeContract, dispatches, aliases) {
228
253
  if (aliases.kind !== "present")
229
254
  return aliases;
230
255
  try {
231
- const source = await Akuma.of(path).list();
256
+ const source = await Akuma.of(path).list({ limit: FLEET_VISIBLE_ROWS });
232
257
  const aliasById = new Map();
233
258
  for (const binding of aliases.value)
234
259
  aliasById.set(binding.akuId, [...(aliasById.get(binding.akuId) ?? []), binding]);
@@ -248,7 +273,7 @@ async function joinAkuma(path, observeContract, dispatches, aliases) {
248
273
  }),
249
274
  };
250
275
  });
251
- const snapshotRows = visibleFleetRows(rows).slice(0, FLEET_SNAPSHOT_ROWS);
276
+ const snapshotRows = rows.slice(0, FLEET_SNAPSHOT_ROWS);
252
277
  const snapshots = new Map(await Promise.all(snapshotRows.map(async (row) => {
253
278
  try {
254
279
  return [row.id, (await Akuma.of(path).of({ id: row.id }).status()).timeline];
@@ -292,8 +317,7 @@ async function observeWithoutRepo(world, region, observedAt, branch) {
292
317
  const contracts = { kind: "absent" };
293
318
  const holders = { kind: "absent" };
294
319
  const observeContract = contractEndpointObserver(contracts);
295
- const board = await readTaskWorld(world);
296
- const tasks = world === null ? { kind: "absent" } : readTasks(world, board, holders, observeContract);
320
+ const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
297
321
  const aliases = world === null ? { kind: "absent" } : await readAliasBindings(world);
298
322
  const akuma = world === null ? { kind: "absent" } : await joinAkuma(world, observeContract, [], aliases);
299
323
  return {
@@ -313,17 +337,20 @@ async function observeRepo(input) {
313
337
  const { world, repo, region, contract, observedAt, branch } = input;
314
338
  try {
315
339
  return await withGitDecodeChannel(repo, (channel) => withGitReadObservation(repo, channel, async (observation) => {
316
- const [contractSection, holders, dispatches, regionSection, board] = await Promise.all([
340
+ const [contractSection, holders, dispatches, regionSection] = await Promise.all([
317
341
  readContracts(observation, contract),
318
342
  readHolders(observation),
319
343
  readDispatches(observation),
320
344
  region === undefined ? Promise.resolve(undefined) : readRegion(observation, region),
321
- readTaskWorld(world),
322
345
  ]);
323
- const contracts = decorateContracts(contractSection, holders, (id) => namespaceTaskSection(board, id));
346
+ const selectedContract = contract !== undefined &&
347
+ contractSection.kind === "present" &&
348
+ contractSection.value.rows.some((row) => row.id === contract);
349
+ const board = selectedContract ? await readTaskWorld(world) : undefined;
350
+ const contracts = decorateContracts(contractSection, holders, selectedContract ? (id) => (id === contract ? namespaceTaskSection(board, id) : undefined) : undefined);
324
351
  const observeContract = contractEndpointObserver(contracts);
325
352
  const aliases = world === null ? { kind: "absent" } : await readAliasBindings(world);
326
- const tasks = world === null ? { kind: "absent" } : readTasks(world, board, holders, observeContract);
353
+ const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
327
354
  const akuma = world === null
328
355
  ? { kind: "absent" }
329
356
  : dispatches.kind === "failed"
@@ -6,6 +6,7 @@ import type { WorldRoot } from "../world.js";
6
6
  import type { ContractId } from "../library/contract.js";
7
7
  import type { RegionOverlap } from "../library/region.js";
8
8
  import type { CurrentPhysicalIssue } from "../protocol/read/observation.js";
9
+ import type { BoundedList } from "../bounded-list.js";
9
10
  export type { RegionOverlap };
10
11
  export type Section<Value> = Readonly<{
11
12
  kind: "present";
@@ -35,11 +36,12 @@ export type ContractKanshiRow = ContractBoard["rows"][number] & Readonly<{
35
36
  phase: ContractPhase;
36
37
  holder: ContractHolderObservation;
37
38
  fleet: readonly ContractFleetAttachment[];
38
- namespaceTasks: Section<readonly TaskRow[]>;
39
+ namespaceTasks?: Section<readonly TaskRow[]>;
39
40
  issue?: CurrentPhysicalIssue;
40
41
  }>;
41
42
  export type ContractKanshiBoard = Omit<ContractBoard, "rows"> & Readonly<{
42
43
  rows: readonly ContractKanshiRow[];
44
+ hasMore?: boolean;
43
45
  }>;
44
46
  export type TaskKanshiRow = TaskRow & Readonly<{
45
47
  contract?: Readonly<{
@@ -48,9 +50,8 @@ export type TaskKanshiRow = TaskRow & Readonly<{
48
50
  }>;
49
51
  blockers?: readonly TaskRef[];
50
52
  }>;
51
- export type TaskKanshiWorld = Readonly<{
53
+ export type TaskKanshiWorld = BoundedList<TaskKanshiRow> & Readonly<{
52
54
  root: WorldRoot;
53
- rows: readonly TaskKanshiRow[];
54
55
  }>;
55
56
  export type AkumaKanshiRow = (AkumaListRow | UnbornAkumaListRow) & Readonly<{
56
57
  aliases: readonly AkumaAlias[];
@@ -1,4 +1,17 @@
1
- import { regionOverlaps } from "../library/region.js";
1
+ import { regionsOverlap } from "../body/region.js";
2
+ function regionOverlaps(mine, declarations) {
3
+ const overlaps = [];
4
+ for (const declaration of declarations) {
5
+ const pairs = regionsOverlap(mine, declaration.patterns);
6
+ if (pairs.length === 0)
7
+ continue;
8
+ overlaps.push({
9
+ contract: declaration.contract,
10
+ patterns: pairs.map(([minePattern, theirsPattern]) => ({ mine: minePattern, theirs: theirsPattern })),
11
+ });
12
+ }
13
+ return overlaps;
14
+ }
2
15
  export function selectKanshi(input) {
3
16
  const { report, contract } = input;
4
17
  return {
@@ -1,3 +1,4 @@
1
+ /** @architectureCompositionRoot */
1
2
  import { type AliasBinding } from "../alias/index.js";
2
3
  import { type AkuId } from "../akuma/identity.js";
3
4
  import { contractId } from "../core/facts/types.js";
@@ -1,3 +1,4 @@
1
+ /** @architectureCompositionRoot */
1
2
  import { readAliases } from "../alias/index.js";
2
3
  import { Akuma } from "../akuma/akuma.js";
3
4
  import { probeBornAkuma } from "../akuma/index.js";
@@ -21,9 +22,6 @@ function nonblank(value, label) {
21
22
  throw new TypeError(`${label} must be a nonblank string`);
22
23
  return value;
23
24
  }
24
- function world(path) {
25
- return Akuma.of(path);
26
- }
27
25
  async function directId(path, selector) {
28
26
  if (selector.startsWith("@")) {
29
27
  const alias = parseAkumaAlias(selector);
@@ -76,9 +74,6 @@ export async function addressAkuma(input) {
76
74
  const path = await World.prove(nonblank(values.path, "path"));
77
75
  return { path, id: await directId(path, nonblank(values.akuma, "akuma")) };
78
76
  }
79
- function idsFromFleet(fleet) {
80
- return fleet.rows.map((row) => row.id);
81
- }
82
77
  function parseSetSelector(raw) {
83
78
  const selector = nonblank(raw, "akuma selector");
84
79
  if (selector.startsWith("kei/"))
@@ -149,7 +144,9 @@ export async function addressAkumaSet(input) {
149
144
  if (hasSelectorKind(selectors, "contract") && values.repo === undefined) {
150
145
  throw new TypeError("Contract Akuma selector requires repo");
151
146
  }
152
- const fleetIds = hasSelectorKind(selectors, "glob") ? idsFromFleet(await world(path).list()) : [];
147
+ const fleetIds = hasSelectorKind(selectors, "glob")
148
+ ? (await Akuma.of(path).listComplete()).rows.map((row) => row.id)
149
+ : [];
153
150
  const aliases = hasSelectorKind(selectors, "alias")
154
151
  ? new Map((await readAliases(path)).map((binding) => [binding.alias, binding.akuId]))
155
152
  : new Map();
@@ -1,8 +1,9 @@
1
1
  import { type AliasBinding } from "../alias/index.js";
2
2
  import { type AkumaStatus, type ForkReceipt, type ReadonlyRestraint } from "../akuma/akuma.js";
3
- import { type AkumaBornCall } from "../akuma/akuma-product.js";
4
- import type { AkuId } from "../akuma/identity.js";
3
+ import type { AkumaBornCall } from "../akuma/akuma-product.js";
4
+ import { type AkuId } from "../akuma/identity.js";
5
5
  import { type Dispatch, type DispatchFailure } from "../dispatch/index.js";
6
+ import type { PrivateStateSeatCloseLag } from "../git/private-state-seat.js";
6
7
  import { type AkumaAlias } from "../identity/selector.js";
7
8
  import type { Settings } from "../settings.js";
8
9
  import { type WorldRoot } from "../world.js";
@@ -20,6 +21,7 @@ export type DispatchStage = Readonly<{
20
21
  }> | Readonly<{
21
22
  kind: "dispatched";
22
23
  dispatch: Dispatch;
24
+ seatClose?: readonly PrivateStateSeatCloseLag[];
23
25
  }> | Readonly<{
24
26
  kind: "failed";
25
27
  failure: DispatchFailure | IntegrationFailure;
@@ -100,6 +102,6 @@ export type ForkResult = Readonly<{
100
102
  parent: AkuId;
101
103
  }>);
102
104
  export declare function beginCall(input: CallInput, context: ExecutionContext): Promise<BornCall>;
103
- export declare function finishCall(born: BornCall, participantName?: string): Promise<CallResult>;
105
+ export declare function finishCall(born: BornCall): Promise<CallResult>;
104
106
  export declare function callKeiyaku(input: CallInput, execution?: ExecutionContext): Promise<CallResult>;
105
107
  export declare function forkKeiyaku(input: ForkInput): Promise<ForkResult>;
@@ -1,13 +1,17 @@
1
- import { realpath, stat } from "node:fs/promises";
1
+ /** @architectureCompositionRoot */
2
+ import { appendFile } from "node:fs/promises";
2
3
  import { moveAlias } from "../alias/index.js";
3
4
  import { Akuma } from "../akuma/akuma.js";
4
- import { beginAkumaCall, finishAkumaCall } from "../akuma/akuma-product.js";
5
+ import { pathsForAkuId } from "../akuma/identity.js";
6
+ import { readSoul } from "../akuma/heart/index.js";
5
7
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
6
8
  import { publishDispatch, readDispatch } from "../dispatch/index.js";
7
9
  import { parseAkumaAlias } from "../identity/selector.js";
10
+ import { emitCalledPluginSignal } from "../plugin/akuma-signals.js";
8
11
  import { readManagedWorktreeAppointment } from "../workspace-place.js";
9
12
  import { World } from "../world.js";
10
13
  import { localExecutionContext } from "../akuma/requests.js";
14
+ import { callReadonly, canonicalBirthCwd } from "../akuma/call-input.js";
11
15
  import { requireInput } from "./input.js";
12
16
  import { addressAkuma } from "./address.js";
13
17
  import { KeiyakuRefused } from "./contract.js";
@@ -66,11 +70,6 @@ function callMode(value) {
66
70
  return "detach";
67
71
  throw new TypeError("mode must be wait or detach");
68
72
  }
69
- function callReadonly(value) {
70
- if (value === undefined || value === true)
71
- return value;
72
- throw new TypeError("readonly must be true");
73
- }
74
73
  function callTimeout(value, mode) {
75
74
  if (mode === "detach" && value !== undefined) {
76
75
  throw new TypeError("timeoutMs is not valid in detach mode");
@@ -82,6 +81,14 @@ function callTimeout(value, mode) {
82
81
  }
83
82
  return value;
84
83
  }
84
+ function callSeat(contract) {
85
+ if (contract === undefined)
86
+ return undefined;
87
+ const seat = seatForKeiyaku(contract);
88
+ if (seat === null)
89
+ throw new TypeError("contract must be a Keiyaku");
90
+ return seat;
91
+ }
85
92
  async function observeCall(handle, mode, timeoutMs) {
86
93
  if (mode === "detach") {
87
94
  return { kind: "detached" };
@@ -93,11 +100,72 @@ async function observeCall(handle, mode, timeoutMs) {
93
100
  return { kind: "failed", failure: integrationFailure(error) };
94
101
  }
95
102
  }
103
+ async function callerAkuId(path, born) {
104
+ if (born.kind !== "requested")
105
+ return undefined;
106
+ const soul = await readSoul(pathsForAkuId(path, born.id));
107
+ return soul?.origin.kind === "request" ? soul.origin.parent : undefined;
108
+ }
109
+ function pluginDiagnostic(error) {
110
+ const message = error instanceof Error ? error.message : String(error);
111
+ return message.length <= 500 ? message : `${message.slice(0, 500)}...`;
112
+ }
113
+ async function recordPluginDiagnostic(paths, error) {
114
+ try {
115
+ await appendFile(paths.log, `plugin call admission failed: ${pluginDiagnostic(error)}\n`);
116
+ }
117
+ catch {
118
+ // Plugin diagnostic loss must not change an already admitted call.
119
+ }
120
+ }
121
+ async function emitCalledSignal(input) {
122
+ try {
123
+ const callerAkumaId = await callerAkuId(input.path, input.born);
124
+ const paths = input.born.kind === "requested" ? pathsForAkuId(input.path, input.akumaId) : input.born.allocated.paths;
125
+ const reportDiagnostic = (message) => {
126
+ void recordPluginDiagnostic(paths, message);
127
+ };
128
+ try {
129
+ await emitCalledPluginSignal({
130
+ world: input.path,
131
+ ...(input.settings === undefined ? {} : { settings: input.settings }),
132
+ reportDiagnostic,
133
+ akumaId: input.akumaId,
134
+ ...(callerAkumaId === undefined ? {} : { callerAkumaId }),
135
+ ...(input.contractId === undefined ? {} : { contractId: input.contractId }),
136
+ });
137
+ }
138
+ catch (error) {
139
+ await recordPluginDiagnostic(paths, error);
140
+ }
141
+ }
142
+ catch {
143
+ // Plugin delivery must not change an already admitted call.
144
+ }
145
+ }
146
+ async function admitCall(input) {
147
+ const born = await input.world.beginCall(input.call, input.context);
148
+ const akuma = born.kind === "requested" ? born.id : born.allocated.id;
149
+ void emitCalledSignal({
150
+ path: input.path,
151
+ ...(input.settings === undefined ? {} : { settings: input.settings }),
152
+ born,
153
+ akumaId: akuma,
154
+ ...(input.contractId === undefined ? {} : { contractId: input.contractId }),
155
+ });
156
+ return { born, akuma };
157
+ }
96
158
  async function dispatchStage(input) {
97
159
  try {
98
160
  const published = await publishDispatch(input);
99
161
  return published.kind === "dispatched"
100
- ? { kind: "dispatched", dispatch: published.dispatch }
162
+ ? {
163
+ kind: "dispatched",
164
+ dispatch: published.dispatch,
165
+ ...(published.seatClose === undefined || published.seatClose.length === 0
166
+ ? {}
167
+ : { seatClose: published.seatClose }),
168
+ }
101
169
  : { kind: "failed", failure: published.failure };
102
170
  }
103
171
  catch (error) {
@@ -115,19 +183,6 @@ async function forkDispatchStage(input) {
115
183
  return { kind: "failed", failure: integrationFailure(error) };
116
184
  }
117
185
  }
118
- async function canonicalizeExistingDirectory(path, diagnostic) {
119
- try {
120
- const real = await realpath(path);
121
- if (!(await stat(real)).isDirectory())
122
- throw new Error(diagnostic);
123
- return real;
124
- }
125
- catch (error) {
126
- if (error instanceof Error && error.message === diagnostic)
127
- throw error;
128
- throw new Error(diagnostic);
129
- }
130
- }
131
186
  function unavailableWorkspace(contractId, detail) {
132
187
  return new Error(`Contract workspace is unavailable: ${contractId} ${detail}`);
133
188
  }
@@ -149,7 +204,7 @@ async function currentManagedContract(contract, contractId) {
149
204
  async function resolveCallExecution(input) {
150
205
  if (input.cwd !== undefined) {
151
206
  return {
152
- cwd: await canonicalizeExistingDirectory(input.cwd, `cwd is not an existing directory: ${input.cwd}`),
207
+ cwd: await canonicalBirthCwd(input.cwd),
153
208
  source: "input",
154
209
  };
155
210
  }
@@ -166,7 +221,7 @@ async function resolveCallExecution(input) {
166
221
  throw new Error(`${appointment.diagnostic}; use reconcile`);
167
222
  }
168
223
  return {
169
- cwd: await canonicalizeExistingDirectory(appointment.path, `Contract workspace is unavailable: ${appointment.path}`),
224
+ cwd: await canonicalBirthCwd(appointment.path, `Contract workspace is unavailable: ${appointment.path}`),
170
225
  source: "contract-worktree",
171
226
  };
172
227
  }
@@ -191,17 +246,14 @@ export async function beginCall(input, context) {
191
246
  const path = await World.prove(nonblank(values.path, "path"));
192
247
  const archetype = nonblank(values.archetype, "archetype");
193
248
  const body = text(values.body, "body");
194
- const readonlyRequested = callReadonly(values.readonly);
249
+ const readonlyRequested = callReadonly(values.readonly, "readonly must be true").readonly;
195
250
  const cwd = values.cwd === undefined ? undefined : nonblank(values.cwd, "cwd");
196
251
  const mode = callMode(values.mode);
197
252
  const timeoutMs = callTimeout(values.timeoutMs, mode);
198
253
  const home = homeOption(values.home);
199
254
  const settings = settingsOption(values.settings);
200
255
  const alias = values.alias === undefined ? undefined : parseAkumaAlias(nonblank(values.alias, "alias"));
201
- const selectedSeat = values.contract === undefined ? undefined : seatForKeiyaku(values.contract);
202
- if (values.contract !== undefined && selectedSeat === null)
203
- throw new TypeError("contract must be a Keiyaku");
204
- const seat = selectedSeat ?? undefined;
256
+ const seat = callSeat(values.contract);
205
257
  const execution = await resolveCallExecution({
206
258
  path,
207
259
  ...(cwd === undefined ? {} : { cwd }),
@@ -215,8 +267,14 @@ export async function beginCall(input, context) {
215
267
  ...(values.allowed === undefined ? {} : { allowed: values.allowed }),
216
268
  ...(execution === undefined ? {} : { cwd: execution.cwd }),
217
269
  };
218
- const born = await beginAkumaCall(world, call, execution === undefined ? {} : { cwdCanonical: true });
219
- const akuma = born.kind === "requested" ? born.id : born.allocated.id;
270
+ const { born, akuma } = await admitCall({
271
+ path,
272
+ world,
273
+ call: call,
274
+ context: execution === undefined ? {} : { cwdCanonical: true },
275
+ ...(settings === undefined ? {} : { settings }),
276
+ ...(seat === undefined ? {} : { contractId: seat.id }),
277
+ });
220
278
  const completedExecution = execution ?? born.execution;
221
279
  const dispatch = seat === undefined
222
280
  ? { kind: "none" }
@@ -245,11 +303,10 @@ export async function beginCall(input, context) {
245
303
  alias: aliasStage,
246
304
  };
247
305
  }
248
- export async function finishCall(born, participantName) {
306
+ export async function finishCall(born) {
249
307
  const world = akumaWorld(born.path);
250
308
  const contractId = born.dispatch.kind === "dispatched" ? born.dispatch.dispatch.contractId : undefined;
251
- const handle = await finishAkumaCall(world, born.born, {
252
- ...(participantName === undefined ? {} : { participantName }),
309
+ const handle = await world.finishCall(born.born, {
253
310
  ...(contractId === undefined ? {} : { contractId }),
254
311
  });
255
312
  const readonly = (await handle.status()).readonly;
@@ -4,7 +4,7 @@ import { auditOperation } from "../protocol/audit.js";
4
4
  import { withScopeAbortSignal } from "../protocol/operations.js";
5
5
  import { worktreeHooksOption } from "./configuration.js";
6
6
  import { documentDerivation } from "./input.js";
7
- import { completeMutation } from "./mutation.js";
7
+ import { auditPending, completeMutation } from "./mutation.js";
8
8
  import { requireAccepted } from "./refusal.js";
9
9
  /** Normalize public audit input and project the protocol audit operation. */
10
10
  export async function auditContract(input) {
@@ -28,6 +28,7 @@ export async function auditContract(input) {
28
28
  contractId: input.contractId,
29
29
  accepted,
30
30
  value: (report) => report,
31
+ valuePending: auditPending,
31
32
  hooks: composition?.hooks ?? worktreeHooksOption(undefined),
32
33
  });
33
34
  });
@@ -1,19 +1,23 @@
1
+ /** @architectureCompositionRoot */
1
2
  import { type AkumaList } from "../akuma/akuma.js";
2
3
  import { type ArchetypeCatalogRow } from "../akuma/archetype.js";
3
4
  import type { TaskRow } from "../task/index.js";
4
- import { type ContractBoard } from "./contract.js";
5
+ import { type ContractCatalogue } from "./contract.js";
5
6
  import { Repo } from "./repo.js";
6
7
  import { type WorldRoot } from "../world.js";
7
8
  export type CatalogQuery = Readonly<{
8
9
  kind: "tasks";
9
10
  namespace?: readonly string[];
11
+ limit?: number;
10
12
  }> | Readonly<{
11
13
  kind: "contracts";
14
+ limit?: number;
12
15
  }> | Readonly<{
13
16
  kind: "archetypes";
14
17
  }> | Readonly<{
15
18
  kind: "akuma";
16
19
  archetype?: string;
20
+ limit?: number;
17
21
  }>;
18
22
  export type CatalogInput = Readonly<{
19
23
  query: Extract<CatalogQuery, {
@@ -29,6 +33,7 @@ export type CatalogInput = Readonly<{
29
33
  query: Extract<CatalogQuery, {
30
34
  kind: "archetypes";
31
35
  }>;
36
+ path?: WorldRoot;
32
37
  home?: string;
33
38
  }> | Readonly<{
34
39
  query: Extract<CatalogQuery, {
@@ -40,12 +45,14 @@ export type Catalog = Readonly<{
40
45
  kind: "tasks";
41
46
  root: WorldRoot;
42
47
  rows: readonly TaskRow[];
48
+ hasMore: boolean;
43
49
  }> | Readonly<{
44
50
  kind: "contracts";
45
51
  root: string;
46
52
  state: string | null;
47
53
  observedAt: string;
48
- rows: ContractBoard["rows"];
54
+ rows: ContractCatalogue["rows"];
55
+ hasMore: boolean;
49
56
  }> | Readonly<{
50
57
  kind: "archetypes";
51
58
  rows: readonly ArchetypeCatalogRow[];
@@ -56,5 +63,6 @@ export type Catalog = Readonly<{
56
63
  observedAt: string;
57
64
  rows: AkumaList["rows"];
58
65
  searched: readonly string[];
66
+ hasMore: boolean;
59
67
  }>;
60
68
  export declare function listCatalog(input: CatalogInput): Promise<Catalog>;