@astrosheep/keiyaku 4.1.0 → 4.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
  5. package/build/src/akuma/akuma-errors.d.ts +6 -0
  6. package/build/src/akuma/akuma-errors.js +9 -0
  7. package/build/src/akuma/akuma-handle.d.ts +39 -0
  8. package/build/src/akuma/akuma-handle.js +263 -0
  9. package/build/src/akuma/akuma-observe.d.ts +19 -0
  10. package/build/src/akuma/akuma-observe.js +74 -0
  11. package/build/src/akuma/akuma-product-symbols.d.ts +1 -0
  12. package/build/src/akuma/akuma-product-symbols.js +1 -0
  13. package/build/src/akuma/akuma-product.d.ts +18 -0
  14. package/build/src/akuma/akuma-product.js +154 -0
  15. package/build/src/akuma/akuma.d.ts +37 -81
  16. package/build/src/akuma/akuma.js +39 -447
  17. package/build/src/akuma/allowed.d.ts +1 -0
  18. package/build/src/akuma/allowed.js +6 -0
  19. package/build/src/akuma/archetype.js +8 -5
  20. package/build/src/akuma/body-supervisor.d.ts +26 -0
  21. package/build/src/akuma/body-supervisor.js +89 -0
  22. package/build/src/akuma/body.d.ts +45 -4
  23. package/build/src/akuma/body.js +145 -35
  24. package/build/src/akuma/coordinate.js +17 -7
  25. package/build/src/akuma/heart/facts.js +1 -1
  26. package/build/src/akuma/heart/index.d.ts +1 -1
  27. package/build/src/akuma/heart/index.js +2 -4
  28. package/build/src/akuma/heart/request-authority.js +4 -4
  29. package/build/src/akuma/heart/request-rows.js +27 -16
  30. package/build/src/akuma/heart/rows.js +79 -41
  31. package/build/src/akuma/heart/soul.js +1 -1
  32. package/build/src/akuma/heart/storage.d.ts +1 -0
  33. package/build/src/akuma/heart/storage.js +76 -11
  34. package/build/src/akuma/heart/tells.js +35 -18
  35. package/build/src/akuma/heart/timeline.js +19 -11
  36. package/build/src/akuma/identity.d.ts +1 -0
  37. package/build/src/akuma/identity.js +1 -0
  38. package/build/src/akuma/index.d.ts +3 -3
  39. package/build/src/akuma/index.js +1 -1
  40. package/build/src/akuma/nuke.js +106 -14
  41. package/build/src/akuma/projection-read.d.ts +17 -0
  42. package/build/src/akuma/projection-read.js +135 -0
  43. package/build/src/akuma/projection.d.ts +1 -16
  44. package/build/src/akuma/projection.js +77 -154
  45. package/build/src/akuma/provider-recipe.js +11 -5
  46. package/build/src/akuma/provider.js +105 -62
  47. package/build/src/akuma/providers/acp/config.js +5 -6
  48. package/build/src/akuma/providers/acp/core.js +17 -10
  49. package/build/src/akuma/providers/acp/events.js +38 -29
  50. package/build/src/akuma/providers/acp/index.js +13 -9
  51. package/build/src/akuma/providers/claude/events.js +8 -12
  52. package/build/src/akuma/providers/claude/index.d.ts +1 -0
  53. package/build/src/akuma/providers/claude/index.js +55 -26
  54. package/build/src/akuma/providers/claude/input.js +6 -2
  55. package/build/src/akuma/providers/codex-app-server/events.js +61 -36
  56. package/build/src/akuma/providers/codex-app-server/index.js +25 -13
  57. package/build/src/akuma/providers/grok-build/index.js +22 -25
  58. package/build/src/akuma/providers/index.js +2 -18
  59. package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
  60. package/build/src/akuma/providers/opencode-sdk/index.js +26 -17
  61. package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
  62. package/build/src/akuma/providers/pi/events.js +26 -19
  63. package/build/src/akuma/providers/pi/index.js +58 -40
  64. package/build/src/akuma/publication.js +9 -9
  65. package/build/src/akuma/request-execution.d.ts +6 -0
  66. package/build/src/akuma/request-execution.js +86 -0
  67. package/build/src/akuma/request-serve.d.ts +12 -1
  68. package/build/src/akuma/request-serve.js +19 -122
  69. package/build/src/akuma/request-wire.d.ts +2 -2
  70. package/build/src/akuma/request-wire.js +75 -102
  71. package/build/src/akuma/requests.js +2 -2
  72. package/build/src/akuma/{body-turn.d.ts → turn-drive.d.ts} +2 -25
  73. package/build/src/akuma/{body-turn.js → turn-drive.js} +20 -103
  74. package/build/src/akuma-body.js +6 -5
  75. package/build/src/body/amend.d.ts +4 -1
  76. package/build/src/body/amend.js +14 -6
  77. package/build/src/body/decode.js +2 -4
  78. package/build/src/body/envelope.js +2 -4
  79. package/build/src/body/region.d.ts +1 -2
  80. package/build/src/body/region.js +2 -70
  81. package/build/src/body/render.js +17 -12
  82. package/build/src/body/shape.js +1 -7
  83. package/build/src/cli/accepted.d.ts +1 -1
  84. package/build/src/cli/accepted.js +8 -1
  85. package/build/src/cli/commands/akuma-invoke.js +18 -6
  86. package/build/src/cli/commands/akuma.d.ts +0 -6
  87. package/build/src/cli/commands/akuma.js +11 -24
  88. package/build/src/cli/commands/amend.d.ts +2 -2
  89. package/build/src/cli/commands/amend.js +2 -4
  90. package/build/src/cli/commands/bind.d.ts +4 -4
  91. package/build/src/cli/commands/bind.js +16 -6
  92. package/build/src/cli/commands/contract-invoke.d.ts +25 -0
  93. package/build/src/cli/commands/contract-invoke.js +193 -0
  94. package/build/src/cli/commands/contract.d.ts +109 -10
  95. package/build/src/cli/commands/contract.js +339 -16
  96. package/build/src/cli/commands/install.d.ts +1 -1
  97. package/build/src/cli/commands/install.js +23 -15
  98. package/build/src/cli/commands/task-invoke.js +187 -67
  99. package/build/src/cli/commands/task-query.js +48 -24
  100. package/build/src/cli/commands/task.js +150 -38
  101. package/build/src/cli/coordinates.js +2 -4
  102. package/build/src/cli/invoke.js +92 -208
  103. package/build/src/cli/main.js +4 -2
  104. package/build/src/cli/parse.d.ts +3 -90
  105. package/build/src/cli/parse.js +27 -233
  106. package/build/src/cli/render/akuma-activity.d.ts +38 -0
  107. package/build/src/cli/render/akuma-activity.js +362 -0
  108. package/build/src/cli/render/akuma-tool-command.js +6 -7
  109. package/build/src/cli/render/akuma-tool.js +10 -8
  110. package/build/src/cli/render/akuma.d.ts +1 -1
  111. package/build/src/cli/render/akuma.js +61 -353
  112. package/build/src/cli/render/audit.js +5 -15
  113. package/build/src/cli/render/board.d.ts +1 -0
  114. package/build/src/cli/render/board.js +17 -0
  115. package/build/src/cli/render/catalog.js +81 -8
  116. package/build/src/cli/render/contract-history.d.ts +2 -0
  117. package/build/src/cli/render/contract-history.js +83 -0
  118. package/build/src/cli/render/contract-observation.d.ts +10 -0
  119. package/build/src/cli/render/contract-observation.js +58 -0
  120. package/build/src/cli/render/contract.d.ts +1 -2
  121. package/build/src/cli/render/contract.js +41 -142
  122. package/build/src/cli/render/kanshi.js +239 -215
  123. package/build/src/cli/render/receipt.js +2 -9
  124. package/build/src/cli/render/refusal.js +10 -15
  125. package/build/src/cli/render/region.js +22 -6
  126. package/build/src/cli/render/settings.js +4 -4
  127. package/build/src/cli/render/task.js +34 -14
  128. package/build/src/cli/render/terminal.js +16 -5
  129. package/build/src/cli/result.d.ts +3 -3
  130. package/build/src/cli/runtime.d.ts +6 -1
  131. package/build/src/cli/runtime.js +84 -63
  132. package/build/src/cli/selectors.js +2 -4
  133. package/build/src/cli/usage.js +6 -5
  134. package/build/src/contract-worktree.d.ts +1 -23
  135. package/build/src/contract-worktree.js +79 -155
  136. package/build/src/coordination/durable-file.js +7 -3
  137. package/build/src/coordination/sqlite-transaction-lock.js +29 -12
  138. package/build/src/core/facts/codec.js +7 -3
  139. package/build/src/core/facts/types.d.ts +1 -1
  140. package/build/src/core/subject.js +16 -9
  141. package/build/src/core/verbs/abandon.d.ts +1 -1
  142. package/build/src/core/verbs/abandon.js +1 -1
  143. package/build/src/core/verbs/amend.d.ts +1 -1
  144. package/build/src/core/verbs/amend.js +7 -7
  145. package/build/src/core/verbs/attestation.js +4 -1
  146. package/build/src/core/verbs/bind.d.ts +1 -1
  147. package/build/src/core/verbs/bind.js +1 -1
  148. package/build/src/core/verbs/placement.d.ts +1 -1
  149. package/build/src/core/verbs/placement.js +10 -8
  150. package/build/src/dispatch/index.js +8 -6
  151. package/build/src/duration.js +5 -1
  152. package/build/src/git/admission.js +5 -3
  153. package/build/src/git/hooks.d.ts +8 -0
  154. package/build/src/git/hooks.js +63 -14
  155. package/build/src/git/identity.js +1 -4
  156. package/build/src/git/integration.d.ts +2 -3
  157. package/build/src/git/integration.js +32 -39
  158. package/build/src/git/nuke.d.ts +1 -1
  159. package/build/src/git/nuke.js +110 -57
  160. package/build/src/git/observe.d.ts +13 -1
  161. package/build/src/git/observe.js +51 -44
  162. package/build/src/git/process.js +4 -2
  163. package/build/src/git/read-observation.js +10 -8
  164. package/build/src/git/reconcile.d.ts +22 -2
  165. package/build/src/git/reconcile.js +38 -274
  166. package/build/src/git/repository.d.ts +2 -0
  167. package/build/src/git/repository.js +13 -22
  168. package/build/src/git/scratch.d.ts +8 -5
  169. package/build/src/git/scratch.js +29 -2
  170. package/build/src/git/target-placement.d.ts +9 -10
  171. package/build/src/git/target-placement.js +59 -62
  172. package/build/src/git/tender.js +13 -46
  173. package/build/src/git/terminal-reconcile.d.ts +21 -0
  174. package/build/src/git/terminal-reconcile.js +278 -0
  175. package/build/src/git/terminal-seal.js +15 -12
  176. package/build/src/git/tree.js +5 -2
  177. package/build/src/git/workspace.d.ts +24 -2
  178. package/build/src/git/workspace.js +120 -16
  179. package/build/src/identity/coordinates.js +3 -1
  180. package/build/src/identity/selector.js +6 -3
  181. package/build/src/kanshi/fleet.d.ts +6 -0
  182. package/build/src/kanshi/fleet.js +27 -0
  183. package/build/src/kanshi/index.d.ts +1 -1
  184. package/build/src/kanshi/read.js +60 -48
  185. package/build/src/kanshi/report.d.ts +11 -23
  186. package/build/src/kanshi/select.js +25 -24
  187. package/build/src/library/address.d.ts +2 -1
  188. package/build/src/library/address.js +7 -8
  189. package/build/src/library/akuma-creation.js +20 -12
  190. package/build/src/library/audit.d.ts +0 -1
  191. package/build/src/library/audit.js +1 -2
  192. package/build/src/library/bind.d.ts +53 -5
  193. package/build/src/library/bind.js +98 -22
  194. package/build/src/library/catalog.d.ts +1 -0
  195. package/build/src/library/catalog.js +6 -3
  196. package/build/src/library/configuration.js +3 -1
  197. package/build/src/library/continuation.d.ts +15 -4
  198. package/build/src/library/continuation.js +24 -16
  199. package/build/src/library/contract-bind.d.ts +26 -0
  200. package/build/src/library/contract-bind.js +106 -0
  201. package/build/src/library/contract-operations.d.ts +77 -0
  202. package/build/src/library/contract-operations.js +130 -0
  203. package/build/src/library/contract-types.d.ts +95 -0
  204. package/build/src/library/contract-types.js +1 -0
  205. package/build/src/library/contract.d.ts +19 -154
  206. package/build/src/library/contract.js +46 -261
  207. package/build/src/library/fleet.d.ts +1 -1
  208. package/build/src/library/fleet.js +19 -11
  209. package/build/src/library/input.d.ts +2 -0
  210. package/build/src/library/input.js +14 -0
  211. package/build/src/library/keiyaku.d.ts +8 -7
  212. package/build/src/library/keiyaku.js +3 -3
  213. package/build/src/library/nuke.js +14 -5
  214. package/build/src/library/reconcile.d.ts +9 -4
  215. package/build/src/library/reconcile.js +30 -24
  216. package/build/src/library/refusal.d.ts +13 -5
  217. package/build/src/library/refusal.js +7 -0
  218. package/build/src/library/region.d.ts +8 -7
  219. package/build/src/library/region.js +31 -11
  220. package/build/src/library/repo.js +2 -2
  221. package/build/src/markdown/lex.js +9 -2
  222. package/build/src/markdown/parse.js +11 -7
  223. package/build/src/markdown/query.js +4 -2
  224. package/build/src/protocol/amend.js +3 -1
  225. package/build/src/protocol/attempt.d.ts +7 -3
  226. package/build/src/protocol/attempt.js +9 -5
  227. package/build/src/protocol/audit.d.ts +1 -1
  228. package/build/src/protocol/audit.js +4 -14
  229. package/build/src/protocol/bind.d.ts +19 -6
  230. package/build/src/protocol/bind.js +28 -13
  231. package/build/src/protocol/completion.d.ts +0 -1
  232. package/build/src/protocol/completion.js +1 -3
  233. package/build/src/protocol/deliver.d.ts +1 -3
  234. package/build/src/protocol/deliver.js +15 -39
  235. package/build/src/protocol/intent.d.ts +1 -0
  236. package/build/src/protocol/intent.js +9 -7
  237. package/build/src/protocol/operations.d.ts +3 -7
  238. package/build/src/protocol/operations.js +5 -3
  239. package/build/src/protocol/placement.d.ts +0 -1
  240. package/build/src/protocol/placement.js +6 -6
  241. package/build/src/protocol/read/observation.d.ts +11 -0
  242. package/build/src/protocol/read/observation.js +37 -0
  243. package/build/src/protocol/read/status.d.ts +23 -12
  244. package/build/src/protocol/read/status.js +90 -72
  245. package/build/src/protocol/reconcile.d.ts +1 -0
  246. package/build/src/protocol/reconcile.js +2 -3
  247. package/build/src/protocol/reintegrate.js +1 -1
  248. package/build/src/protocol/review.d.ts +0 -1
  249. package/build/src/protocol/review.js +15 -22
  250. package/build/src/protocol/run.d.ts +1 -0
  251. package/build/src/protocol/run.js +4 -5
  252. package/build/src/runtime/proc/launch.d.ts +33 -0
  253. package/build/src/runtime/proc/launch.js +98 -0
  254. package/build/src/runtime/proc/line-rpc.js +9 -3
  255. package/build/src/runtime/proc/run.d.ts +12 -6
  256. package/build/src/runtime/proc/run.js +78 -21
  257. package/build/src/runtime/proc/stdio.js +7 -10
  258. package/build/src/settings.js +6 -2
  259. package/build/src/settlement/holder.js +13 -10
  260. package/build/src/settlement/settle.js +39 -6
  261. package/build/src/task/board.js +12 -6
  262. package/build/src/task/compose.js +85 -22
  263. package/build/src/task/context.js +21 -8
  264. package/build/src/task/document.js +46 -10
  265. package/build/src/task/identity.js +5 -2
  266. package/build/src/task/index.d.ts +0 -1
  267. package/build/src/task/index.js +119 -34
  268. package/build/src/task/input.js +29 -7
  269. package/build/src/task/mutation.js +61 -19
  270. package/build/src/task/operations.d.ts +6 -1
  271. package/build/src/task/operations.js +83 -29
  272. package/build/src/task/query.js +55 -26
  273. package/build/src/task/store.d.ts +3 -1
  274. package/build/src/task/store.js +81 -17
  275. package/build/src/verification/execution.js +14 -11
  276. package/build/src/workspace-place.js +19 -7
  277. package/build/src/world.js +16 -6
  278. package/package.json +8 -3
@@ -1,18 +1,19 @@
1
1
  import { Repo } from "../library/repo.js";
2
2
  import { scopeForRepo } from "../library/repo.js";
3
- import { resolveHereContractWorkspace } from "../contract-worktree.js";
4
3
  import { observeTaskBoard } from "../task/operations.js";
5
4
  import { contractNamespace } from "../settlement/settle.js";
6
5
  import { Akuma } from "../akuma/index.js";
7
6
  import { readAliases } from "../alias/index.js";
8
7
  import { readDispatchesAt } from "../dispatch/index.js";
9
8
  import { readTaskHolderProjectionAt } from "../settlement/holder.js";
9
+ import { observeCurrentPhysicalIssue } from "../protocol/read/observation.js";
10
10
  import { readContractBoard } from "../protocol/read/status.js";
11
11
  import { withGitDecodeChannel, withGitReadObservation } from "../git/read-observation.js";
12
12
  import { readDocuments } from "../protocol/read/documents.js";
13
- import { readRegionDeclarations, validateRegionPath } from "../library/region.js";
13
+ import { readRegionDeclarations, validateRegionPatterns } from "../library/region.js";
14
14
  import { contractId } from "../core/facts/types.js";
15
15
  import { selectKanshi, selectRegion } from "./select.js";
16
+ import { FLEET_SNAPSHOT_ROWS, visibleFleetRows } from "./fleet.js";
16
17
  function diagnostic(error) {
17
18
  let source;
18
19
  if (error instanceof Error)
@@ -59,28 +60,14 @@ function regionSelection(value) {
59
60
  throw new TypeError("kanshi region contract must be a canonical ContractId");
60
61
  }
61
62
  }
62
- if (selection.kind === "overlap") {
63
- exactKeys(selection, ["kind", "contract"], "region selection");
64
- if (selection.contract === undefined)
65
- return { kind: "overlap" };
66
- if (typeof selection.contract !== "string")
67
- throw new TypeError("kanshi region contract must be a ContractId");
68
- try {
69
- return { kind: "overlap", contract: contractId(selection.contract) };
70
- }
71
- catch {
72
- throw new TypeError("kanshi region contract must be a canonical ContractId");
73
- }
74
- }
75
63
  if (selection.kind === "path") {
76
- exactKeys(selection, ["kind", "path"], "region selection");
64
+ exactKeys(selection, ["kind", "patterns"], "region selection");
77
65
  try {
78
- validateRegionPath(selection.path);
66
+ return { kind: "path", patterns: validateRegionPatterns(selection.patterns) };
79
67
  }
80
68
  catch (error) {
81
69
  throw new TypeError(error instanceof Error ? error.message : String(error));
82
70
  }
83
- return { kind: "path", path: selection.path };
84
71
  }
85
72
  throw new TypeError(`kanshi region selection kind is invalid: ${selection.kind}`);
86
73
  }
@@ -105,7 +92,9 @@ function coordinate(input) {
105
92
  }
106
93
  async function readRegion(observation, selection) {
107
94
  try {
108
- const declarations = [...readRegionDeclarations(await readDocuments(observation))].sort((left, right) => left.contract.localeCompare(right.contract));
95
+ const declarations = [
96
+ ...readRegionDeclarations(await readDocuments(observation)),
97
+ ].sort((left, right) => left.contract.localeCompare(right.contract));
109
98
  return { kind: "present", value: selectRegion({ declarations, selection }) };
110
99
  }
111
100
  catch (error) {
@@ -122,17 +111,33 @@ async function readBranch(repo) {
122
111
  return null;
123
112
  }
124
113
  }
125
- async function readContracts(observation, selected) {
114
+ async function readContracts(observation, include) {
126
115
  try {
127
116
  return {
128
117
  kind: "present",
129
- value: await readContractBoard(observation, selected, async (id) => await resolveHereContractWorkspace(observation.repository, id)),
118
+ value: await readContractBoard(observation, include),
130
119
  };
131
120
  }
132
121
  catch (error) {
133
122
  return { kind: "failed", failure: { message: diagnostic(error) } };
134
123
  }
135
124
  }
125
+ async function attachSelectedIssue(observation, contracts, selected) {
126
+ if (contracts.kind !== "present")
127
+ return contracts;
128
+ try {
129
+ const rows = await Promise.all(contracts.value.rows.map(async (row) => {
130
+ if (row.id !== selected)
131
+ return row;
132
+ const issue = await observeCurrentPhysicalIssue(observation.repository, row);
133
+ return issue === undefined ? row : { ...row, issue };
134
+ }));
135
+ return { kind: "present", value: { ...contracts.value, rows } };
136
+ }
137
+ catch (error) {
138
+ return { kind: "failed", failure: { message: diagnostic(error) } };
139
+ }
140
+ }
136
141
  async function readHolders(observation) {
137
142
  try {
138
143
  return { kind: "present", value: await readTaskHolderProjectionAt(observation) };
@@ -191,7 +196,7 @@ function contractEndpointObserver(contracts) {
191
196
  const dispositions = contracts.kind === "present"
192
197
  ? new Map(contracts.value.rows.map((row) => [row.id, row.disposition]))
193
198
  : null;
194
- return (id) => dispositions === null ? "unavailable" : dispositions.get(id) ?? "missing";
199
+ return (id) => (dispositions === null ? "unavailable" : (dispositions.get(id) ?? "missing"));
195
200
  }
196
201
  function joinTasks(rows, holders, observeContract) {
197
202
  const associations = new Map(holders.kind === "present"
@@ -249,23 +254,18 @@ async function joinAkuma(path, observeContract, dispatches, aliases) {
249
254
  return {
250
255
  ...row,
251
256
  aliases: (aliasById.get(row.id) ?? []).map((binding) => binding.alias),
252
- ...(dispatch === undefined ? {} : {
253
- contract: {
254
- id: dispatch.contractId,
255
- observed: observeContract(dispatch.contractId),
256
- },
257
- }),
257
+ ...(dispatch === undefined
258
+ ? {}
259
+ : {
260
+ contract: {
261
+ id: dispatch.contractId,
262
+ observed: observeContract(dispatch.contractId),
263
+ },
264
+ }),
258
265
  };
259
266
  });
260
- const running = rows
261
- .filter((row) => row.life === "running")
262
- .sort((left, right) => {
263
- const l = "lastActivityAt" in left && left.lastActivityAt !== null ? Date.parse(left.lastActivityAt) : -Infinity;
264
- const r = "lastActivityAt" in right && right.lastActivityAt !== null ? Date.parse(right.lastActivityAt) : -Infinity;
265
- return r - l;
266
- })
267
- .slice(0, 3);
268
- const snapshots = new Map(await Promise.all(running.map(async (row) => {
267
+ const snapshotRows = visibleFleetRows(rows).slice(0, FLEET_SNAPSHOT_ROWS);
268
+ const snapshots = new Map(await Promise.all(snapshotRows.map(async (row) => {
269
269
  try {
270
270
  return [row.id, (await Akuma.of(path).of({ id: row.id }).status()).timeline];
271
271
  }
@@ -306,7 +306,7 @@ async function readDispatches(observation) {
306
306
  }
307
307
  export async function observeKanshi(input) {
308
308
  const observedAt = new Date().toISOString();
309
- const { world, repo } = coordinate(input);
309
+ const { world, repo, region, contract } = coordinate(input);
310
310
  const branch = await readBranch(repo);
311
311
  if (repo === undefined) {
312
312
  const contracts = { kind: "absent" };
@@ -317,18 +317,26 @@ export async function observeKanshi(input) {
317
317
  const aliases = world === null ? { kind: "absent" } : await readAliasBindings(world);
318
318
  const akuma = world === null ? { kind: "absent" } : await joinAkuma(world, observeContract, [], aliases);
319
319
  return {
320
- report: { root: world, observedAt, branch, contracts, tasks, akuma, ...(input.region === undefined ? {} : { region: { kind: "absent" } }) },
320
+ report: {
321
+ root: world,
322
+ observedAt,
323
+ branch,
324
+ contracts,
325
+ tasks,
326
+ akuma,
327
+ ...(region === undefined ? {} : { region: { kind: "absent" } }),
328
+ },
321
329
  aliases,
322
330
  };
323
331
  }
324
332
  try {
325
333
  const repository = scopeForRepo(repo);
326
334
  return await withGitDecodeChannel(repository, (channel) => withGitReadObservation(repository, channel, async (observation) => {
327
- const [contractSection, holders, dispatches, region, board] = await Promise.all([
328
- readContracts(observation, input.contract),
335
+ const [contractSection, holders, dispatches, regionSection, board] = await Promise.all([
336
+ readContracts(observation, contract),
329
337
  readHolders(observation),
330
338
  readDispatches(observation),
331
- input.region === undefined ? Promise.resolve(undefined) : readRegion(observation, input.region),
339
+ region === undefined ? Promise.resolve(undefined) : readRegion(observation, region),
332
340
  readTaskWorld(world),
333
341
  ]);
334
342
  const contracts = decorateContracts(contractSection, holders, (id) => namespaceTaskSection(board, id));
@@ -340,19 +348,23 @@ export async function observeKanshi(input) {
340
348
  : dispatches.kind === "failed"
341
349
  ? dispatches
342
350
  : await joinAkuma(world, observeContract, dispatches.value, aliases);
343
- const report = {
351
+ const assembled = {
344
352
  root: world,
345
353
  observedAt,
346
354
  branch,
347
355
  contracts: attachFleet(contracts, akuma),
348
356
  tasks,
349
357
  akuma,
350
- ...(region === undefined ? {} : { region }),
358
+ ...(regionSection === undefined ? {} : { region: regionSection }),
351
359
  };
360
+ if (contract === undefined)
361
+ return { report: assembled, aliases };
362
+ const selected = selectKanshi({ report: assembled, contract });
352
363
  return {
353
- report: input.contract === undefined
354
- ? report
355
- : selectKanshi({ report, contract: input.contract }),
364
+ report: {
365
+ ...selected,
366
+ contracts: await attachSelectedIssue(observation, selected.contracts, contract),
367
+ },
356
368
  aliases,
357
369
  };
358
370
  }));
@@ -367,7 +379,7 @@ export async function observeKanshi(input) {
367
379
  contracts: failure,
368
380
  tasks: world === null ? { kind: "absent" } : failure,
369
381
  akuma: world === null ? { kind: "absent" } : failure,
370
- ...(input.region === undefined ? {} : { region: failure }),
382
+ ...(region === undefined ? {} : { region: failure }),
371
383
  },
372
384
  aliases: world === null ? { kind: "absent" } : failure,
373
385
  };
@@ -1,9 +1,12 @@
1
- import type { ContractBoard, ContractDisposition } from "../library/contract.js";
1
+ import type { ContractBoard, ContractDisposition, ContractPhase } from "../library/contract.js";
2
+ import type { CurrentPhysicalIssue } from "../protocol/read/observation.js";
2
3
  import type { TaskId, TaskRef, TaskRow } from "../task/index.js";
3
4
  import type { AkumaList, AkumaListRow, UnbornAkumaListRow, ActivitySnapshot } from "../akuma/index.js";
4
5
  import type { AkumaAlias } from "../identity/selector.js";
5
6
  import type { WorldRoot } from "../world.js";
6
7
  import type { ContractId } from "../library/contract.js";
8
+ import type { RegionOverlap } from "../library/region.js";
9
+ export type { RegionOverlap };
7
10
  export type Section<Value> = Readonly<{
8
11
  kind: "present";
9
12
  value: Value;
@@ -28,10 +31,13 @@ export type ContractFleetAttachment = Readonly<{
28
31
  id: string;
29
32
  aliases: readonly AkumaAlias[];
30
33
  }>;
34
+ export type { CurrentPhysicalIssue };
31
35
  export type ContractKanshiRow = ContractBoard["rows"][number] & Readonly<{
36
+ phase: ContractPhase;
32
37
  holder: ContractHolderObservation;
33
38
  fleet: readonly ContractFleetAttachment[];
34
39
  namespaceTasks: Section<readonly TaskRow[]>;
40
+ issue?: CurrentPhysicalIssue;
35
41
  }>;
36
42
  export type ContractKanshiBoard = Omit<ContractBoard, "rows"> & Readonly<{
37
43
  rows: readonly ContractKanshiRow[];
@@ -63,43 +69,25 @@ export type KanshiRegionSelection = Readonly<{
63
69
  }> | Readonly<{
64
70
  kind: "contract";
65
71
  contract: ContractId;
66
- }> | Readonly<{
67
- kind: "overlap";
68
- contract?: ContractId;
69
72
  }> | Readonly<{
70
73
  kind: "path";
71
- path: string;
74
+ patterns: readonly [string, ...string[]];
72
75
  }>;
73
76
  export type RegionDeclaration = Readonly<{
74
77
  contract: ContractId;
75
78
  patterns: readonly string[];
76
79
  }>;
77
- export type RegionIntersection = Readonly<{
78
- left: ContractId;
79
- right: ContractId;
80
- patterns: readonly Readonly<{
81
- left: string;
82
- right: string;
83
- }>[];
84
- }>;
85
- export type RegionPathMatch = Readonly<{
86
- contract: ContractId;
87
- pattern: string;
88
- }>;
89
80
  export type RegionRead = Readonly<{
90
81
  kind: "declarations";
91
82
  declarations: readonly RegionDeclaration[];
92
83
  }> | Readonly<{
93
84
  kind: "contract";
94
85
  declaration: RegionDeclaration;
95
- }> | Readonly<{
96
- kind: "overlap";
97
- subject?: ContractId;
98
- intersections: readonly RegionIntersection[];
86
+ overlaps: readonly RegionOverlap[];
99
87
  }> | Readonly<{
100
88
  kind: "path";
101
- path: string;
102
- matches: readonly RegionPathMatch[];
89
+ patterns: readonly string[];
90
+ overlaps: readonly RegionOverlap[];
103
91
  }>;
104
92
  export type KanshiReport = Readonly<{
105
93
  root: WorldRoot | null;
@@ -1,13 +1,25 @@
1
- import { regionIntersections, regionPathMatches } from "../library/region.js";
1
+ import { regionOverlaps } from "../library/region.js";
2
2
  export function selectKanshi(input) {
3
3
  const { report, contract } = input;
4
4
  return {
5
5
  ...report,
6
6
  contracts: report.contracts.kind === "present"
7
- ? { kind: "present", value: { ...report.contracts.value, rows: report.contracts.value.rows.filter((row) => row.id === contract) } }
7
+ ? {
8
+ kind: "present",
9
+ value: {
10
+ ...report.contracts.value,
11
+ rows: report.contracts.value.rows.filter((row) => row.id === contract),
12
+ },
13
+ }
8
14
  : report.contracts,
9
15
  tasks: report.tasks.kind === "present"
10
- ? { kind: "present", value: { ...report.tasks.value, rows: report.tasks.value.rows.filter((row) => row.contract?.id === contract) } }
16
+ ? {
17
+ kind: "present",
18
+ value: {
19
+ ...report.tasks.value,
20
+ rows: report.tasks.value.rows.filter((row) => row.contract?.id === contract),
21
+ },
22
+ }
11
23
  : report.tasks,
12
24
  akuma: report.akuma.kind === "present"
13
25
  ? {
@@ -28,26 +40,15 @@ export function selectRegion(input) {
28
40
  const declaration = declarations.find((value) => value.contract === selection.contract);
29
41
  if (declaration === undefined)
30
42
  throw new Error(`active contract not found: ${selection.contract}`);
31
- return { kind: "contract", declaration };
32
- }
33
- if (selection.kind === "path") {
34
- const matches = declarations.flatMap((declaration) => regionPathMatches(declaration.patterns, selection.path).map((pattern) => ({ contract: declaration.contract, pattern })));
35
- return { kind: "path", path: selection.path, matches };
36
- }
37
- const intersections = [];
38
- for (let leftIndex = 0; leftIndex < declarations.length; leftIndex += 1) {
39
- for (let rightIndex = leftIndex + 1; rightIndex < declarations.length; rightIndex += 1) {
40
- const left = declarations[leftIndex];
41
- const right = declarations[rightIndex];
42
- if (selection.contract !== undefined && left.contract !== selection.contract && right.contract !== selection.contract)
43
- continue;
44
- const patterns = regionIntersections(left.patterns, right.patterns);
45
- if (patterns.length > 0)
46
- intersections.push({ left: left.contract, right: right.contract, patterns });
47
- }
43
+ return {
44
+ kind: "contract",
45
+ declaration,
46
+ overlaps: regionOverlaps(declaration.patterns, declarations.filter((value) => value.contract !== selection.contract)),
47
+ };
48
48
  }
49
- if (selection.contract !== undefined && !declarations.some((value) => value.contract === selection.contract)) {
50
- throw new Error(`active contract not found: ${selection.contract}`);
51
- }
52
- return { kind: "overlap", ...(selection.contract === undefined ? {} : { subject: selection.contract }), intersections };
49
+ return {
50
+ kind: "path",
51
+ patterns: selection.patterns,
52
+ overlaps: regionOverlaps(selection.patterns, declarations),
53
+ };
53
54
  }
@@ -1,5 +1,6 @@
1
1
  import { type AliasBinding } from "../alias/index.js";
2
2
  import { type AkuId } from "../akuma/identity.js";
3
+ import { contractId } from "../core/facts/types.js";
3
4
  import { type AkumaAlias, type AkumaGlob } from "../identity/selector.js";
4
5
  import type { WorldRoot } from "../world.js";
5
6
  import type { KanshiReport, Section } from "../kanshi/index.js";
@@ -27,7 +28,7 @@ export declare class AkumaWorldScopeError extends TypeError {
27
28
  }
28
29
  export type NamedAddress = Readonly<{
29
30
  kind: "contract";
30
- id: string;
31
+ id: ReturnType<typeof contractId>;
31
32
  }> | Readonly<{
32
33
  kind: "akuma";
33
34
  id: AkuId;
@@ -46,11 +46,12 @@ export function resolveNamedAddress(input) {
46
46
  if (input.aliases.kind === "failed") {
47
47
  throw new TypeError("cannot resolve a named selector while Alias authority is failed");
48
48
  }
49
- const contractMatches = (input.report.contracts.kind === "present" ? input.report.contracts.value.rows : []).filter((row) => row.disposition === "active"
50
- && row.workspace === "worktree" && row.worktreePath !== null
51
- && `@${row.id.slice("kei/".length)}` === alias);
49
+ const contractMatches = (input.report.contracts.kind === "present" ? input.report.contracts.value.rows : []).filter((row) => row.disposition === "active" &&
50
+ row.workspace === "worktree" &&
51
+ row.worktreePath !== null &&
52
+ `@${row.id.slice("kei/".length)}` === alias);
52
53
  const aliasId = input.aliases.kind === "present"
53
- ? input.aliases.value.find((binding) => binding.alias === alias)?.akuId ?? null
54
+ ? (input.aliases.value.find((binding) => binding.alias === alias)?.akuId ?? null)
54
55
  : null;
55
56
  if (contractMatches.length > 0 && aliasId !== null)
56
57
  throw new TypeError(`ambiguous selector matches Contract and Akuma: ${selector}`);
@@ -127,7 +128,7 @@ async function contractMemberInWorld(path, id) {
127
128
  async function refuseForeignContractMembers(path, ids, contractMembers) {
128
129
  const foreign = [];
129
130
  for (const id of ids) {
130
- if (contractMembers.has(id) && !await contractMemberInWorld(path, id))
131
+ if (contractMembers.has(id) && !(await contractMemberInWorld(path, id)))
131
132
  foreign.push(id);
132
133
  }
133
134
  if (foreign.length > 0)
@@ -147,9 +148,7 @@ export async function addressAkumaSet(input) {
147
148
  if (hasSelectorKind(selectors, "contract") && values.repo === undefined) {
148
149
  throw new TypeError("Contract Akuma selector requires repo");
149
150
  }
150
- const fleetIds = hasSelectorKind(selectors, "glob")
151
- ? idsFromFleet(await world(path).list())
152
- : [];
151
+ const fleetIds = hasSelectorKind(selectors, "glob") ? idsFromFleet(await world(path).list()) : [];
153
152
  const aliases = hasSelectorKind(selectors, "alias")
154
153
  ? new Map((await readAliases(path)).map((binding) => [binding.alias, binding.akuId]))
155
154
  : new Map();
@@ -2,7 +2,7 @@ import { realpath, stat } from "node:fs/promises";
2
2
  import { moveAlias } from "../alias/index.js";
3
3
  import { Akuma, akumaCallExecution, callAkumaWithContext, } from "../akuma/akuma.js";
4
4
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
5
- import { publishDispatch, readDispatch, } from "../dispatch/index.js";
5
+ import { publishDispatch, readDispatch } from "../dispatch/index.js";
6
6
  import { parseAkumaAlias } from "../identity/selector.js";
7
7
  import { readManagedWorktreeAppointment } from "../workspace-place.js";
8
8
  import { requireInput } from "./input.js";
@@ -23,7 +23,9 @@ function text(value, label) {
23
23
  function settingsOption(value) {
24
24
  if (value === undefined)
25
25
  return undefined;
26
- if (typeof value !== "object" || value === null || typeof value.namespace !== "function") {
26
+ if (typeof value !== "object" ||
27
+ value === null ||
28
+ typeof value.namespace !== "function") {
27
29
  throw new TypeError("settings must be a Settings");
28
30
  }
29
31
  return value;
@@ -136,9 +138,6 @@ async function currentManagedContract(contract, contractId) {
136
138
  }
137
139
  if (state.terminal !== null)
138
140
  throw new KeiyakuRefused({ kind: "terminal", contractId: state.id });
139
- if (state.coordinates.workspace !== "worktree") {
140
- throw unavailableWorkspace(state.id, "is here");
141
- }
142
141
  return state;
143
142
  }
144
143
  async function resolveCallExecution(input) {
@@ -167,7 +166,20 @@ async function resolveCallExecution(input) {
167
166
  }
168
167
  export async function callKeiyaku(input) {
169
168
  const values = requireInput(input, "Keiyaku.call input");
170
- onlyKeys(values, ["path", "archetype", "body", "cwd", "readonly", "mode", "timeoutMs", "home", "settings", "contract", "alias", "allowed"], "Keiyaku.call input");
169
+ onlyKeys(values, [
170
+ "path",
171
+ "archetype",
172
+ "body",
173
+ "cwd",
174
+ "readonly",
175
+ "mode",
176
+ "timeoutMs",
177
+ "home",
178
+ "settings",
179
+ "contract",
180
+ "alias",
181
+ "allowed",
182
+ ], "Keiyaku.call input");
171
183
  const path = nonblank(values.path, "path");
172
184
  const archetype = nonblank(values.archetype, "archetype");
173
185
  const body = text(values.body, "body");
@@ -177,9 +189,7 @@ export async function callKeiyaku(input) {
177
189
  const timeoutMs = callTimeout(values.timeoutMs, mode);
178
190
  const home = homeOption(values.home);
179
191
  const settings = settingsOption(values.settings);
180
- const alias = values.alias === undefined
181
- ? undefined
182
- : parseAkumaAlias(nonblank(values.alias, "alias"));
192
+ const alias = values.alias === undefined ? undefined : parseAkumaAlias(nonblank(values.alias, "alias"));
183
193
  const seat = values.contract === undefined ? undefined : seatForKeiyaku(values.contract);
184
194
  const execution = await resolveCallExecution({
185
195
  path,
@@ -194,9 +204,7 @@ export async function callKeiyaku(input) {
194
204
  ...(values.allowed === undefined ? {} : { allowed: values.allowed }),
195
205
  ...(execution === undefined ? {} : { cwd: execution.cwd }),
196
206
  };
197
- const handle = execution === undefined
198
- ? await world.call(call)
199
- : await callAkumaWithContext(world, call, { cwdCanonical: true });
207
+ const handle = execution === undefined ? await world.call(call) : await callAkumaWithContext(world, call, { cwdCanonical: true });
200
208
  const completedExecution = execution ?? akumaCallExecution(handle);
201
209
  if (completedExecution === undefined)
202
210
  throw new Error("Akuma call is missing its birth execution");
@@ -16,5 +16,4 @@ export declare function auditContract(input: Readonly<{
16
16
  scope: RepositoryScope;
17
17
  contractId: ContractId;
18
18
  input?: AuditInput;
19
- resolveHereWorkspace?: (contractId: ContractId) => Promise<string | undefined>;
20
19
  }>): Promise<MutationResult<AuditReport>>;
@@ -2,7 +2,7 @@ import { decodeContractDocument } from "../body/decode.js";
2
2
  import { withGitDecodeChannel } from "../git/read-observation.js";
3
3
  import { auditOperation } from "../protocol/audit.js";
4
4
  import { worktreeHooksOption } from "./configuration.js";
5
- import { actorOption, documentDerivation, optionalBoolean, optionalSignal, requireInput, } from "./input.js";
5
+ import { actorOption, documentDerivation, optionalBoolean, optionalSignal, requireInput } from "./input.js";
6
6
  import { completeMutation } from "./mutation.js";
7
7
  import { requireAccepted } from "./refusal.js";
8
8
  function normalizeAuditInput(input) {
@@ -31,7 +31,6 @@ export async function auditContract(input) {
31
31
  requireBranchesToBeUpToDate: normalized.requireBranchesToBeUpToDate,
32
32
  ...(normalized.signal === undefined ? {} : { signal: normalized.signal }),
33
33
  ...(normalized.actor === undefined ? {} : { actor: normalized.actor }),
34
- ...(input.resolveHereWorkspace === undefined ? {} : { resolveHereWorkspace: input.resolveHereWorkspace }),
35
34
  }));
36
35
  return completeMutation({
37
36
  scope: input.scope,
@@ -1,22 +1,70 @@
1
+ import { decodeContractDocument } from "../body/decode.js";
1
2
  import { type ActorId, type ContractId } from "../core/facts/types.js";
2
3
  import type { GitDecodeChannel } from "../git/read-observation.js";
3
- import { bindOperation } from "../protocol/bind.js";
4
- import type { IntentOutcome, RepositoryScope } from "../protocol/operations.js";
4
+ import { bindOperation, type BindTargetSelection } from "../protocol/bind.js";
5
+ import { type IntentOutcome, type RepositoryScope } from "../protocol/operations.js";
5
6
  import type { TaskId } from "../task/identity.js";
6
7
  import type { VerificationDeclarationPreparation } from "../verification/declaration.js";
7
- import type { KeiyakuRefusal } from "./refusal.js";
8
+ import { type KeiyakuRefusal } from "./refusal.js";
8
9
  type BindAttemptInput = Readonly<{
9
10
  scope: RepositoryScope;
10
11
  channel: GitDecodeChannel;
11
12
  title: string;
12
13
  terms: Parameters<typeof bindOperation>[0]["terms"];
13
14
  verification: VerificationDeclarationPreparation;
14
- workspace: "worktree" | "here";
15
- target?: string;
15
+ workspace: "worktree";
16
+ targetSelection?: BindTargetSelection;
17
+ coordinates?: Readonly<{
18
+ start: import("../core/facts/types.js").SnapshotId;
19
+ }>;
20
+ source?: Parameters<typeof bindOperation>[0]["source"];
16
21
  task?: TaskId;
17
22
  actor?: ActorId;
18
23
  }>;
19
24
  export declare function admitBindWithAppointment(input: BindAttemptInput): Promise<IntentOutcome<Readonly<{
20
25
  contractId: ContractId;
21
26
  }>, KeiyakuRefusal>>;
27
+ export declare function admitForkBindWithAppointment(input: Readonly<{
28
+ scope: RepositoryScope;
29
+ channel: GitDecodeChannel;
30
+ sourceId: ContractId;
31
+ target?: string;
32
+ actor?: ActorId;
33
+ }>): Promise<{
34
+ admission: IntentOutcome<Readonly<{
35
+ contractId: ContractId;
36
+ }>, KeiyakuRefusal>;
37
+ document: import("../body/types.js").DecodedContractDocument;
38
+ }>;
39
+ export declare function admitMarkdownBind(input: Readonly<{
40
+ scope: RepositoryScope;
41
+ channel: GitDecodeChannel;
42
+ title: string;
43
+ terms: Parameters<typeof bindOperation>[0]["terms"];
44
+ verification: VerificationDeclarationPreparation;
45
+ workspace: "worktree";
46
+ targetSelection?: BindTargetSelection;
47
+ task?: TaskId;
48
+ actor?: ActorId;
49
+ }>): Promise<IntentOutcome<Readonly<{
50
+ contractId: ContractId;
51
+ }>, KeiyakuRefusal>>;
52
+ export declare function prepareMarkdownBind(input: Readonly<{
53
+ scope: RepositoryScope;
54
+ channel: GitDecodeChannel;
55
+ document: ReturnType<typeof decodeContractDocument>;
56
+ gates: readonly import("../core/facts/types.js").Gate[];
57
+ after: readonly ContractId[];
58
+ workspace: "worktree";
59
+ targetSelection?: BindTargetSelection;
60
+ task?: TaskId;
61
+ actor?: ActorId;
62
+ }>): Promise<{
63
+ admission: import("../settlement/holder.js").TaskHolderAdmission<IntentOutcome<Readonly<{
64
+ contractId: ContractId;
65
+ }>, KeiyakuRefusal>> | null;
66
+ result: IntentOutcome<Readonly<{
67
+ contractId: ContractId;
68
+ }>, KeiyakuRefusal>;
69
+ }>;
22
70
  export {};