@astrosheep/keiyaku 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/README.md +133 -8
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +13 -5
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -32
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +134 -0
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +262 -46
  12. package/build/src/akuma/abort.d.ts +2 -0
  13. package/build/src/akuma/abort.js +50 -0
  14. package/build/src/akuma/akuma.d.ts +50 -33
  15. package/build/src/akuma/akuma.js +175 -127
  16. package/build/src/akuma/archetype.d.ts +14 -5
  17. package/build/src/akuma/archetype.js +85 -39
  18. package/build/src/akuma/body.d.ts +3 -5
  19. package/build/src/akuma/body.js +490 -183
  20. package/build/src/akuma/coordinate.d.ts +9 -0
  21. package/build/src/akuma/coordinate.js +22 -0
  22. package/build/src/akuma/heart/facts.d.ts +88 -45
  23. package/build/src/akuma/heart/facts.js +19 -8
  24. package/build/src/akuma/heart/index.d.ts +64 -55
  25. package/build/src/akuma/heart/index.js +172 -252
  26. package/build/src/akuma/heart/rows.d.ts +38 -83
  27. package/build/src/akuma/heart/rows.js +117 -155
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +61 -22
  30. package/build/src/akuma/heart/soul.d.ts +8 -0
  31. package/build/src/akuma/heart/soul.js +136 -0
  32. package/build/src/akuma/heart/storage.d.ts +47 -0
  33. package/build/src/akuma/heart/storage.js +224 -0
  34. package/build/src/akuma/heart/tells.d.ts +12 -0
  35. package/build/src/akuma/heart/tells.js +79 -0
  36. package/build/src/akuma/heart/timeline.d.ts +15 -0
  37. package/build/src/akuma/heart/timeline.js +86 -0
  38. package/build/src/akuma/identity.d.ts +2 -2
  39. package/build/src/akuma/identity.js +9 -9
  40. package/build/src/akuma/index.d.ts +10 -3
  41. package/build/src/akuma/index.js +7 -1
  42. package/build/src/akuma/projection.d.ts +176 -0
  43. package/build/src/akuma/projection.js +256 -0
  44. package/build/src/akuma/provider-recipe.d.ts +24 -0
  45. package/build/src/akuma/provider-recipe.js +100 -0
  46. package/build/src/akuma/provider.d.ts +67 -13
  47. package/build/src/akuma/provider.js +172 -105
  48. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  49. package/build/src/akuma/providers/acp/core.js +159 -0
  50. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  51. package/build/src/akuma/providers/acp/events.js +73 -0
  52. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  53. package/build/src/akuma/providers/acp/index.js +94 -0
  54. package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
  55. package/build/src/akuma/providers/claude/events.js +238 -0
  56. package/build/src/akuma/providers/claude/index.d.ts +47 -0
  57. package/build/src/akuma/providers/claude/index.js +279 -0
  58. package/build/src/akuma/providers/claude/input.d.ts +13 -0
  59. package/build/src/akuma/providers/claude/input.js +109 -0
  60. package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
  61. package/build/src/akuma/providers/codex-app-server/events.js +15 -12
  62. package/build/src/akuma/providers/codex-app-server/index.d.ts +15 -13
  63. package/build/src/akuma/providers/codex-app-server/index.js +77 -33
  64. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  65. package/build/src/akuma/providers/grok-build/index.js +70 -0
  66. package/build/src/akuma/providers/index.d.ts +5 -3
  67. package/build/src/akuma/providers/index.js +35 -56
  68. package/build/src/akuma/providers/opencode-sdk/events.d.ts +54 -0
  69. package/build/src/akuma/providers/opencode-sdk/events.js +235 -0
  70. package/build/src/akuma/providers/opencode-sdk/index.d.ts +33 -0
  71. package/build/src/akuma/providers/opencode-sdk/index.js +308 -0
  72. package/build/src/akuma/providers/opencode-sdk/session.d.ts +26 -0
  73. package/build/src/akuma/providers/opencode-sdk/session.js +63 -0
  74. package/build/src/akuma/providers/pi/events.d.ts +33 -0
  75. package/build/src/akuma/providers/pi/events.js +166 -0
  76. package/build/src/akuma/providers/pi/index.d.ts +11 -0
  77. package/build/src/akuma/providers/pi/index.js +191 -0
  78. package/build/src/akuma/publication.d.ts +3 -3
  79. package/build/src/akuma/publication.js +28 -40
  80. package/build/src/akuma/requests.d.ts +9 -6
  81. package/build/src/akuma/requests.js +95 -65
  82. package/build/src/alias/index.d.ts +4 -3
  83. package/build/src/alias/index.js +12 -13
  84. package/build/src/body/decode.js +7 -1
  85. package/build/src/body/region.d.ts +2 -0
  86. package/build/src/body/region.js +77 -7
  87. package/build/src/body/render.js +2 -1
  88. package/build/src/body/shape.js +7 -1
  89. package/build/src/body/verification.js +19 -4
  90. package/build/src/cli/accepted.d.ts +18 -12
  91. package/build/src/cli/accepted.js +73 -34
  92. package/build/src/cli/actor.js +3 -3
  93. package/build/src/cli/commands/akuma-invoke.d.ts +44 -19
  94. package/build/src/cli/commands/akuma-invoke.js +101 -52
  95. package/build/src/cli/commands/akuma.d.ts +27 -9
  96. package/build/src/cli/commands/akuma.js +151 -80
  97. package/build/src/cli/commands/contract.d.ts +155 -0
  98. package/build/src/cli/commands/contract.js +20 -0
  99. package/build/src/cli/commands/install.js +2 -0
  100. package/build/src/cli/commands/task-invoke.d.ts +19 -4
  101. package/build/src/cli/commands/task-invoke.js +65 -17
  102. package/build/src/cli/commands/task-query.d.ts +5 -0
  103. package/build/src/cli/commands/task-query.js +247 -0
  104. package/build/src/cli/commands/task.d.ts +3 -1
  105. package/build/src/cli/commands/task.js +52 -14
  106. package/build/src/cli/coordinates.d.ts +18 -0
  107. package/build/src/cli/coordinates.js +120 -0
  108. package/build/src/cli/draft.d.ts +8 -0
  109. package/build/src/cli/draft.js +96 -0
  110. package/build/src/cli/invoke.d.ts +9 -3
  111. package/build/src/cli/invoke.js +287 -108
  112. package/build/src/cli/main.js +54 -7
  113. package/build/src/cli/parse.d.ts +21 -117
  114. package/build/src/cli/parse.js +79 -84
  115. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  116. package/build/src/cli/render/akuma-tool-command.js +144 -0
  117. package/build/src/cli/render/akuma-tool.d.ts +4 -2
  118. package/build/src/cli/render/akuma-tool.js +35 -5
  119. package/build/src/cli/render/akuma.d.ts +3 -1
  120. package/build/src/cli/render/akuma.js +247 -212
  121. package/build/src/cli/render/audit.d.ts +3 -0
  122. package/build/src/cli/render/audit.js +104 -0
  123. package/build/src/cli/render/catalog.d.ts +2 -0
  124. package/build/src/cli/render/catalog.js +16 -0
  125. package/build/src/cli/render/contract.d.ts +3 -3
  126. package/build/src/cli/render/contract.js +200 -54
  127. package/build/src/cli/render/kanshi.js +272 -129
  128. package/build/src/cli/render/receipt.d.ts +19 -0
  129. package/build/src/cli/render/receipt.js +106 -0
  130. package/build/src/cli/render/refusal.d.ts +16 -2
  131. package/build/src/cli/render/refusal.js +88 -3
  132. package/build/src/cli/render/region.d.ts +2 -0
  133. package/build/src/cli/render/region.js +17 -0
  134. package/build/src/cli/render/task.d.ts +2 -1
  135. package/build/src/cli/render/task.js +223 -60
  136. package/build/src/cli/render/terminal.d.ts +20 -0
  137. package/build/src/cli/render/terminal.js +121 -0
  138. package/build/src/cli/render/text.js +11 -3
  139. package/build/src/cli/result.d.ts +126 -19
  140. package/build/src/cli/usage.d.ts +1 -0
  141. package/build/src/cli/usage.js +3 -0
  142. package/build/src/contract-worktree.d.ts +44 -0
  143. package/build/src/contract-worktree.js +251 -0
  144. package/build/src/coordination/durable-file.d.ts +5 -1
  145. package/build/src/coordination/durable-file.js +57 -10
  146. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  147. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  148. package/build/src/core/facts/codec.js +23 -4
  149. package/build/src/core/facts/eligibility.d.ts +1 -10
  150. package/build/src/core/facts/eligibility.js +0 -49
  151. package/build/src/core/facts/fold.js +1 -6
  152. package/build/src/core/facts/gate.d.ts +1 -0
  153. package/build/src/core/facts/gate.js +1 -0
  154. package/build/src/core/facts/observation.d.ts +3 -0
  155. package/build/src/core/facts/observation.js +12 -0
  156. package/build/src/core/facts/types.d.ts +10 -3
  157. package/build/src/core/subject.js +2 -2
  158. package/build/src/core/verbs/amend.d.ts +1 -1
  159. package/build/src/core/verbs/amend.js +3 -18
  160. package/build/src/core/verbs/bind.js +2 -16
  161. package/build/src/core/verbs/deliver.d.ts +1 -1
  162. package/build/src/core/verbs/deliver.js +14 -4
  163. package/build/src/core/verbs/placement.d.ts +1 -1
  164. package/build/src/core/verbs/placement.js +7 -9
  165. package/build/src/dispatch/index.d.ts +5 -3
  166. package/build/src/dispatch/index.js +30 -21
  167. package/build/src/duration.d.ts +10 -0
  168. package/build/src/duration.js +22 -0
  169. package/build/src/git/admission.d.ts +2 -2
  170. package/build/src/git/admission.js +33 -23
  171. package/build/src/git/hooks.d.ts +15 -0
  172. package/build/src/git/hooks.js +70 -18
  173. package/build/src/git/identity.d.ts +5 -1
  174. package/build/src/git/identity.js +23 -4
  175. package/build/src/git/integration.d.ts +48 -0
  176. package/build/src/git/integration.js +250 -0
  177. package/build/src/git/observe.d.ts +29 -15
  178. package/build/src/git/observe.js +185 -76
  179. package/build/src/git/read-observation.d.ts +41 -0
  180. package/build/src/git/read-observation.js +361 -0
  181. package/build/src/git/reconcile.d.ts +17 -5
  182. package/build/src/git/reconcile.js +305 -109
  183. package/build/src/git/repository.d.ts +41 -18
  184. package/build/src/git/repository.js +220 -114
  185. package/build/src/git/scratch.d.ts +17 -0
  186. package/build/src/git/scratch.js +73 -0
  187. package/build/src/git/target-placement.d.ts +92 -0
  188. package/build/src/git/target-placement.js +375 -0
  189. package/build/src/git/tender.d.ts +49 -0
  190. package/build/src/git/tender.js +63 -0
  191. package/build/src/git/terminal-seal.d.ts +24 -0
  192. package/build/src/git/terminal-seal.js +89 -0
  193. package/build/src/git/tree.d.ts +2 -2
  194. package/build/src/git/tree.js +4 -0
  195. package/build/src/git/workspace.d.ts +53 -0
  196. package/build/src/git/workspace.js +139 -0
  197. package/build/src/identity/selector.d.ts +6 -0
  198. package/build/src/identity/selector.js +19 -0
  199. package/build/src/index.d.ts +4 -2
  200. package/build/src/index.js +2 -1
  201. package/build/src/kanshi/index.d.ts +2 -2
  202. package/build/src/kanshi/index.js +1 -1
  203. package/build/src/kanshi/read.d.ts +7 -3
  204. package/build/src/kanshi/read.js +245 -45
  205. package/build/src/kanshi/report.d.ts +81 -6
  206. package/build/src/kanshi/select.d.ts +5 -0
  207. package/build/src/kanshi/select.js +33 -1
  208. package/build/src/library/address.d.ts +57 -0
  209. package/build/src/library/address.js +165 -0
  210. package/build/src/library/akuma-creation.d.ts +16 -7
  211. package/build/src/library/akuma-creation.js +96 -22
  212. package/build/src/library/audit.d.ts +18 -0
  213. package/build/src/library/audit.js +44 -0
  214. package/build/src/library/bind.d.ts +21 -0
  215. package/build/src/library/bind.js +56 -0
  216. package/build/src/library/catalog.d.ts +58 -0
  217. package/build/src/library/catalog.js +69 -0
  218. package/build/src/library/configuration.d.ts +6 -15
  219. package/build/src/library/configuration.js +14 -17
  220. package/build/src/library/contract.d.ts +23 -49
  221. package/build/src/library/contract.js +171 -185
  222. package/build/src/library/delivery.d.ts +24 -0
  223. package/build/src/library/delivery.js +21 -0
  224. package/build/src/library/fleet.d.ts +65 -0
  225. package/build/src/library/fleet.js +153 -0
  226. package/build/src/library/input.d.ts +3 -0
  227. package/build/src/library/input.js +19 -0
  228. package/build/src/library/keiyaku.d.ts +18 -3
  229. package/build/src/library/keiyaku.js +12 -1
  230. package/build/src/library/mutation.d.ts +39 -0
  231. package/build/src/library/mutation.js +37 -0
  232. package/build/src/library/reconcile.d.ts +29 -0
  233. package/build/src/library/reconcile.js +179 -0
  234. package/build/src/library/refusal.d.ts +21 -0
  235. package/build/src/library/refusal.js +29 -0
  236. package/build/src/library/region.d.ts +14 -1
  237. package/build/src/library/region.js +18 -4
  238. package/build/src/library/repo.d.ts +4 -13
  239. package/build/src/library/repo.js +14 -24
  240. package/build/src/protocol/attempt.d.ts +16 -3
  241. package/build/src/protocol/attempt.js +41 -10
  242. package/build/src/protocol/bind.d.ts +9 -2
  243. package/build/src/protocol/bind.js +48 -40
  244. package/build/src/protocol/intent.d.ts +57 -20
  245. package/build/src/protocol/intent.js +55 -79
  246. package/build/src/protocol/operations.d.ts +152 -43
  247. package/build/src/protocol/operations.js +482 -166
  248. package/build/src/protocol/outcome.d.ts +14 -3
  249. package/build/src/protocol/outcome.js +11 -3
  250. package/build/src/protocol/placement.d.ts +41 -0
  251. package/build/src/protocol/placement.js +147 -0
  252. package/build/src/protocol/read/documents.d.ts +2 -2
  253. package/build/src/protocol/read/documents.js +4 -4
  254. package/build/src/protocol/read/status.d.ts +18 -5
  255. package/build/src/protocol/read/status.js +73 -13
  256. package/build/src/protocol/run.d.ts +49 -7
  257. package/build/src/protocol/run.js +53 -25
  258. package/build/src/runtime/proc/line-rpc.d.ts +4 -8
  259. package/build/src/runtime/proc/line-rpc.js +22 -28
  260. package/build/src/runtime/proc/run.d.ts +23 -21
  261. package/build/src/runtime/proc/run.js +123 -89
  262. package/build/src/runtime/proc/stdio.d.ts +18 -0
  263. package/build/src/runtime/proc/stdio.js +58 -0
  264. package/build/src/settings.d.ts +7 -1
  265. package/build/src/settings.js +32 -17
  266. package/build/src/settlement/fence.d.ts +5 -0
  267. package/build/src/settlement/fence.js +14 -0
  268. package/build/src/settlement/holder.d.ts +35 -4
  269. package/build/src/settlement/holder.js +127 -28
  270. package/build/src/settlement/settle.d.ts +9 -1
  271. package/build/src/settlement/settle.js +74 -37
  272. package/build/src/task/board.d.ts +23 -5
  273. package/build/src/task/board.js +17 -10
  274. package/build/src/task/compose.d.ts +2 -2
  275. package/build/src/task/compose.js +18 -10
  276. package/build/src/task/context.d.ts +3 -3
  277. package/build/src/task/context.js +15 -20
  278. package/build/src/task/document.d.ts +2 -1
  279. package/build/src/task/document.js +15 -5
  280. package/build/src/task/index.d.ts +27 -15
  281. package/build/src/task/index.js +57 -35
  282. package/build/src/task/operations.d.ts +38 -13
  283. package/build/src/task/operations.js +80 -46
  284. package/build/src/task/query.d.ts +67 -0
  285. package/build/src/task/query.js +279 -0
  286. package/build/src/task/store.d.ts +5 -7
  287. package/build/src/task/store.js +43 -28
  288. package/build/src/verification/declaration.d.ts +1 -0
  289. package/build/src/verification/execution.d.ts +51 -0
  290. package/build/src/verification/execution.js +108 -0
  291. package/build/src/workspace-place.d.ts +41 -0
  292. package/build/src/workspace-place.js +386 -0
  293. package/build/src/world.d.ts +24 -0
  294. package/build/src/world.js +136 -0
  295. package/package.json +8 -4
  296. package/build/src/akuma/activity.d.ts +0 -66
  297. package/build/src/akuma/activity.js +0 -139
  298. package/build/src/akuma/providers/claude.js +0 -305
  299. package/build/src/context-root.d.ts +0 -4
  300. package/build/src/context-root.js +0 -15
  301. package/build/src/git/delivery.d.ts +0 -20
  302. package/build/src/git/delivery.js +0 -109
  303. package/build/src/git/verification.d.ts +0 -14
  304. package/build/src/git/verification.js +0 -56
  305. package/build/src/protocol/read/audit.d.ts +0 -25
  306. package/build/src/protocol/read/audit.js +0 -39
  307. package/build/src/verification/producer.d.ts +0 -23
  308. package/build/src/verification/producer.js +0 -54
@@ -1,8 +1,16 @@
1
- import { resolve } from "node:path";
2
- import { listKeiyaku, taskHoldersForRepo } from "../library/contract.js";
3
- import { NoGitWorldError, Repo } from "../library/repo.js";
4
- import { Tasks } from "../task/index.js";
1
+ import { Repo } from "../library/repo.js";
2
+ import { scopeForRepo } from "../library/repo.js";
3
+ import { observeTaskStatusRows } from "../task/operations.js";
5
4
  import { Akuma } from "../akuma/index.js";
5
+ import { readAliases } from "../alias/index.js";
6
+ import { readDispatchesAt } from "../dispatch/index.js";
7
+ import { readTaskHolderProjectionAt } from "../settlement/holder.js";
8
+ import { readContractBoard } from "../protocol/read/status.js";
9
+ import { withGitDecodeChannel, withGitReadObservation } from "../git/read-observation.js";
10
+ import { readDocuments } from "../protocol/read/documents.js";
11
+ import { readRegionDeclarations, validateRegionPath } from "../library/region.js";
12
+ import { contractId } from "../core/facts/types.js";
13
+ import { selectRegion } from "./select.js";
6
14
  function diagnostic(error) {
7
15
  let source;
8
16
  if (error instanceof Error)
@@ -20,81 +28,273 @@ function diagnostic(error) {
20
28
  const line = source.replaceAll(/\s+/gu, " ").trim();
21
29
  return line.length <= 240 ? line : `${line.slice(0, 239)}…`;
22
30
  }
31
+ function record(value, label) {
32
+ if (typeof value !== "object" || value === null || Array.isArray(value))
33
+ throw new TypeError(`kanshi ${label} must be an object`);
34
+ return value;
35
+ }
36
+ function exactKeys(value, allowed, label) {
37
+ for (const key of Object.keys(value))
38
+ if (!allowed.includes(key))
39
+ throw new TypeError(`kanshi ${label} has unknown field: ${key}`);
40
+ }
41
+ function regionSelection(value) {
42
+ const selection = record(value, "region selection");
43
+ if (typeof selection.kind !== "string")
44
+ throw new TypeError("kanshi region selection kind must be a string");
45
+ if (selection.kind === "declarations") {
46
+ exactKeys(selection, ["kind"], "region selection");
47
+ return { kind: "declarations" };
48
+ }
49
+ if (selection.kind === "contract") {
50
+ exactKeys(selection, ["kind", "contract"], "region selection");
51
+ if (typeof selection.contract !== "string")
52
+ throw new TypeError("kanshi region contract must be a ContractId");
53
+ try {
54
+ return { kind: "contract", contract: contractId(selection.contract) };
55
+ }
56
+ catch {
57
+ throw new TypeError("kanshi region contract must be a canonical ContractId");
58
+ }
59
+ }
60
+ if (selection.kind === "overlap") {
61
+ exactKeys(selection, ["kind", "contract"], "region selection");
62
+ if (selection.contract === undefined)
63
+ return { kind: "overlap" };
64
+ if (typeof selection.contract !== "string")
65
+ throw new TypeError("kanshi region contract must be a ContractId");
66
+ try {
67
+ return { kind: "overlap", contract: contractId(selection.contract) };
68
+ }
69
+ catch {
70
+ throw new TypeError("kanshi region contract must be a canonical ContractId");
71
+ }
72
+ }
73
+ if (selection.kind === "path") {
74
+ exactKeys(selection, ["kind", "path"], "region selection");
75
+ try {
76
+ validateRegionPath(selection.path);
77
+ }
78
+ catch (error) {
79
+ throw new TypeError(error instanceof Error ? error.message : String(error));
80
+ }
81
+ return { kind: "path", path: selection.path };
82
+ }
83
+ throw new TypeError(`kanshi region selection kind is invalid: ${selection.kind}`);
84
+ }
23
85
  function coordinate(input) {
24
- if (input === undefined)
25
- return process.cwd();
26
86
  if (typeof input !== "object" || input === null || Array.isArray(input))
27
87
  throw new TypeError("kanshi input must be an object");
28
88
  for (const key of Object.keys(input))
29
- if (key !== "path")
89
+ if (key !== "world" && key !== "repo" && key !== "region")
30
90
  throw new TypeError(`kanshi input has unknown field: ${key}`);
31
- if (input.path === undefined)
32
- return process.cwd();
33
- if (typeof input.path !== "string" || input.path.trim().length === 0)
34
- throw new TypeError("kanshi path must be a nonblank string");
35
- return input.path;
91
+ if (input.world !== null && (typeof input.world !== "string" || input.world.trim().length === 0)) {
92
+ throw new TypeError("kanshi world must be a WorldRoot or null");
93
+ }
94
+ if (input.repo !== undefined && !(input.repo instanceof Repo))
95
+ throw new TypeError("kanshi repo must be a Repo");
96
+ return input.region === undefined ? input : { ...input, region: regionSelection(input.region) };
36
97
  }
37
- async function readContracts(path) {
98
+ async function readRegion(observation, selection) {
38
99
  try {
39
- const repo = Repo.at({ path });
40
- try {
41
- return { repo, section: { kind: "present", value: await listKeiyaku({ repo }) } };
42
- }
43
- catch (error) {
44
- return { repo, section: { kind: "failed", failure: { message: diagnostic(error) } } };
45
- }
100
+ const declarations = [...readRegionDeclarations(await readDocuments(observation))].sort((left, right) => left.contract.localeCompare(right.contract));
101
+ return { kind: "present", value: selectRegion({ declarations, selection }) };
46
102
  }
47
103
  catch (error) {
48
- return { section: error instanceof NoGitWorldError
49
- ? { kind: "absent" }
50
- : { kind: "failed", failure: { message: diagnostic(error) } } };
104
+ return { kind: "failed", failure: { message: diagnostic(error) } };
105
+ }
106
+ }
107
+ async function readBranch(repo) {
108
+ if (repo === undefined)
109
+ return null;
110
+ try {
111
+ return await repo.currentBranch();
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ }
117
+ async function readContracts(observation) {
118
+ try {
119
+ return { kind: "present", value: await readContractBoard(observation) };
120
+ }
121
+ catch (error) {
122
+ return { kind: "failed", failure: { message: diagnostic(error) } };
123
+ }
124
+ }
125
+ async function readHolders(observation) {
126
+ try {
127
+ return { kind: "present", value: await readTaskHolderProjectionAt(observation) };
128
+ }
129
+ catch (error) {
130
+ return { kind: "failed", failure: { message: diagnostic(error) } };
131
+ }
132
+ }
133
+ function attachFleet(contracts, akuma) {
134
+ if (contracts.kind !== "present")
135
+ return contracts;
136
+ const attachments = new Map();
137
+ if (akuma.kind === "present") {
138
+ for (const row of akuma.value.rows) {
139
+ if (row.contract === undefined)
140
+ continue;
141
+ const current = attachments.get(row.contract.id) ?? [];
142
+ current.push({ id: row.id, aliases: row.aliases });
143
+ attachments.set(row.contract.id, current);
144
+ }
51
145
  }
146
+ return {
147
+ kind: "present",
148
+ value: {
149
+ ...contracts.value,
150
+ rows: contracts.value.rows.map((row) => ({ ...row, fleet: attachments.get(row.id) ?? [] })),
151
+ },
152
+ };
153
+ }
154
+ function decorateContracts(contracts, holders) {
155
+ if (contracts.kind !== "present")
156
+ return contracts;
157
+ return {
158
+ kind: "present",
159
+ value: {
160
+ ...contracts.value,
161
+ rows: contracts.value.rows.map((row) => {
162
+ if (holders.kind === "failed")
163
+ return { ...row, holder: { kind: "unavailable" }, fleet: [] };
164
+ const holder = holders.kind === "present" ? holders.value.get(row.id) : undefined;
165
+ return {
166
+ ...row,
167
+ fleet: [],
168
+ holder: holder?.disposition === "held"
169
+ ? { kind: "held", taskId: holder.taskId }
170
+ : { kind: "none" },
171
+ };
172
+ }),
173
+ },
174
+ };
52
175
  }
53
- function joinTasks(rows, holders, contracts) {
176
+ function contractEndpointObserver(contracts) {
54
177
  const dispositions = contracts.kind === "present"
55
178
  ? new Map(contracts.value.rows.map((row) => [row.id, row.disposition]))
56
179
  : null;
57
- const associations = new Map(holders
58
- .filter((holder) => holder.disposition === "held")
59
- .map((holder) => [holder.taskId, holder.contractId]));
180
+ return (id) => dispositions === null ? "unavailable" : dispositions.get(id) ?? "missing";
181
+ }
182
+ function joinTasks(rows, holders, observeContract) {
183
+ const associations = new Map(holders.kind === "present"
184
+ ? [...holders.value.values()]
185
+ .filter((holder) => holder.disposition === "held")
186
+ .map((holder) => [holder.taskId, holder.contractId])
187
+ : []);
60
188
  return rows.map((row) => {
61
189
  const contractId = associations.get(row.id);
62
190
  if (contractId === undefined)
63
191
  return row;
64
- const observed = contracts.kind !== "present"
65
- ? "unavailable"
66
- : dispositions?.get(contractId) ?? "missing";
67
- return { ...row, contract: { id: contractId, observed } };
192
+ return { ...row, contract: { id: contractId, observed: observeContract(contractId) } };
68
193
  });
69
194
  }
70
- async function readTasks(path, contracts, repo) {
195
+ async function readTasks(path, holders, observeContract) {
196
+ if (holders.kind === "failed")
197
+ return { kind: "failed", failure: holders.failure };
198
+ try {
199
+ return {
200
+ kind: "present",
201
+ value: { root: path, rows: joinTasks(await observeTaskStatusRows(path), holders, observeContract) },
202
+ };
203
+ }
204
+ catch (error) {
205
+ return { kind: "failed", failure: { message: diagnostic(error) } };
206
+ }
207
+ }
208
+ async function joinAkuma(path, observeContract, dispatches) {
71
209
  try {
72
- const tasks = Tasks.at({ path });
73
- const result = await tasks.list({ selection: "all", scope: "world" });
74
- if (result.kind !== "accepted")
75
- return { kind: "failed", failure: { message: diagnostic(result) } };
210
+ const source = await Akuma.of(path).list();
211
+ const aliases = await readAliases(path);
212
+ const aliasById = new Map();
213
+ for (const binding of aliases)
214
+ aliasById.set(binding.akuId, [...(aliasById.get(binding.akuId) ?? []), binding]);
215
+ const dispatchById = new Map(dispatches.map((dispatch) => [dispatch.akuId, dispatch]));
76
216
  return {
77
217
  kind: "present",
78
- value: { root: tasks.root, rows: joinTasks(result.value, repo === undefined ? [] : taskHoldersForRepo(repo), contracts) },
218
+ value: {
219
+ ...source,
220
+ rows: source.rows.map((row) => {
221
+ const dispatch = dispatchById.get(row.id);
222
+ return {
223
+ ...row,
224
+ aliases: (aliasById.get(row.id) ?? []).map((binding) => binding.alias),
225
+ ...(dispatch === undefined ? {} : {
226
+ contract: {
227
+ id: dispatch.contractId,
228
+ observed: observeContract(dispatch.contractId),
229
+ },
230
+ }),
231
+ };
232
+ }),
233
+ },
79
234
  };
80
235
  }
81
236
  catch (error) {
82
237
  return { kind: "failed", failure: { message: diagnostic(error) } };
83
238
  }
84
239
  }
85
- function readAkuma(path) {
240
+ async function readDispatches(observation) {
86
241
  try {
87
- const source = Akuma.at({ path }).list();
88
- return { kind: "present", value: source };
242
+ return { kind: "present", value: await readDispatchesAt(observation) };
89
243
  }
90
244
  catch (error) {
91
245
  return { kind: "failed", failure: { message: diagnostic(error) } };
92
246
  }
93
247
  }
94
248
  export async function kanshi(input) {
95
- const path = resolve(coordinate(input));
96
- const contractRead = await readContracts(path);
97
- const contracts = contractRead.section;
98
- const tasks = await readTasks(path, contracts, contractRead.repo);
99
- return { root: path, contracts, tasks, akuma: readAkuma(path) };
249
+ const observedAt = new Date().toISOString();
250
+ const { world, repo } = coordinate(input);
251
+ const branch = await readBranch(repo);
252
+ if (repo === undefined) {
253
+ const contracts = { kind: "absent" };
254
+ const holders = { kind: "absent" };
255
+ const observeContract = contractEndpointObserver(contracts);
256
+ const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
257
+ const akuma = world === null ? { kind: "absent" } : await joinAkuma(world, observeContract, []);
258
+ return { root: world, observedAt, branch, contracts, tasks, akuma, ...(input.region === undefined ? {} : { region: { kind: "absent" } }) };
259
+ }
260
+ try {
261
+ const repository = scopeForRepo(repo);
262
+ return await withGitDecodeChannel(repository, (channel) => withGitReadObservation(repository, channel, async (observation) => {
263
+ const [contractSection, holders, dispatches, region] = await Promise.all([
264
+ readContracts(observation),
265
+ readHolders(observation),
266
+ readDispatches(observation),
267
+ input.region === undefined ? Promise.resolve(undefined) : readRegion(observation, input.region),
268
+ ]);
269
+ const contracts = decorateContracts(contractSection, holders);
270
+ const observeContract = contractEndpointObserver(contracts);
271
+ const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
272
+ const akuma = world === null
273
+ ? { kind: "absent" }
274
+ : dispatches.kind === "failed"
275
+ ? dispatches
276
+ : await joinAkuma(world, observeContract, dispatches.value);
277
+ return {
278
+ root: world,
279
+ observedAt,
280
+ branch,
281
+ contracts: attachFleet(contracts, akuma),
282
+ tasks,
283
+ akuma,
284
+ ...(region === undefined ? {} : { region }),
285
+ };
286
+ }));
287
+ }
288
+ catch (error) {
289
+ const failure = { kind: "failed", failure: { message: diagnostic(error) } };
290
+ return {
291
+ root: world,
292
+ observedAt,
293
+ branch,
294
+ contracts: failure,
295
+ tasks: world === null ? { kind: "absent" } : failure,
296
+ akuma: world === null ? { kind: "absent" } : failure,
297
+ ...(input.region === undefined ? {} : { region: failure }),
298
+ };
299
+ }
100
300
  }
@@ -1,6 +1,9 @@
1
- import type { ContractBoard, ContractDisposition } from "../index.js";
2
- import type { TaskRow } from "../task/index.js";
1
+ import type { ContractBoard, ContractDisposition } from "../library/contract.js";
2
+ import type { TaskId, TaskRef, TaskRow } from "../task/index.js";
3
3
  import type { AkumaList, AkumaListRow, UnbornAkumaListRow } from "../akuma/index.js";
4
+ import type { AkumaAlias } from "../identity/selector.js";
5
+ import type { WorldRoot } from "../world.js";
6
+ import type { ContractId } from "../library/contract.js";
4
7
  export type Section<Value> = Readonly<{
5
8
  kind: "present";
6
9
  value: Value;
@@ -13,23 +16,95 @@ export type Section<Value> = Readonly<{
13
16
  }>;
14
17
  }>;
15
18
  export type ContractEndpointObservation = ContractDisposition | "missing" | "unavailable";
19
+ export type ContractHolderObservation = Readonly<{
20
+ kind: "held";
21
+ taskId: TaskId;
22
+ }> | Readonly<{
23
+ kind: "none";
24
+ }> | Readonly<{
25
+ kind: "unavailable";
26
+ }>;
27
+ export type ContractFleetAttachment = Readonly<{
28
+ id: string;
29
+ aliases: readonly AkumaAlias[];
30
+ }>;
31
+ export type ContractKanshiRow = ContractBoard["rows"][number] & Readonly<{
32
+ holder: ContractHolderObservation;
33
+ fleet: readonly ContractFleetAttachment[];
34
+ }>;
35
+ export type ContractKanshiBoard = Omit<ContractBoard, "rows"> & Readonly<{
36
+ rows: readonly ContractKanshiRow[];
37
+ }>;
16
38
  export type TaskKanshiRow = TaskRow & Readonly<{
17
39
  contract?: Readonly<{
18
40
  id: string;
19
41
  observed: ContractEndpointObservation;
20
42
  }>;
43
+ blockers?: readonly TaskRef[];
21
44
  }>;
22
45
  export type TaskKanshiWorld = Readonly<{
23
- root: string;
46
+ root: WorldRoot;
24
47
  rows: readonly TaskKanshiRow[];
25
48
  }>;
26
- export type AkumaKanshiRow = AkumaListRow | UnbornAkumaListRow;
49
+ export type AkumaKanshiRow = (AkumaListRow | UnbornAkumaListRow) & Readonly<{
50
+ aliases: readonly AkumaAlias[];
51
+ contract?: Readonly<{
52
+ id: string;
53
+ observed: ContractEndpointObservation;
54
+ }>;
55
+ }>;
27
56
  export type AkumaKanshiWorld = Omit<AkumaList, "rows"> & Readonly<{
28
57
  rows: readonly AkumaKanshiRow[];
29
58
  }>;
59
+ export type KanshiRegionSelection = Readonly<{
60
+ kind: "declarations";
61
+ }> | Readonly<{
62
+ kind: "contract";
63
+ contract: ContractId;
64
+ }> | Readonly<{
65
+ kind: "overlap";
66
+ contract?: ContractId;
67
+ }> | Readonly<{
68
+ kind: "path";
69
+ path: string;
70
+ }>;
71
+ export type RegionDeclaration = Readonly<{
72
+ contract: ContractId;
73
+ patterns: readonly string[];
74
+ }>;
75
+ export type RegionIntersection = Readonly<{
76
+ left: ContractId;
77
+ right: ContractId;
78
+ patterns: readonly Readonly<{
79
+ left: string;
80
+ right: string;
81
+ }>[];
82
+ }>;
83
+ export type RegionPathMatch = Readonly<{
84
+ contract: ContractId;
85
+ pattern: string;
86
+ }>;
87
+ export type RegionRead = Readonly<{
88
+ kind: "declarations";
89
+ declarations: readonly RegionDeclaration[];
90
+ }> | Readonly<{
91
+ kind: "contract";
92
+ declaration: RegionDeclaration;
93
+ }> | Readonly<{
94
+ kind: "overlap";
95
+ subject?: ContractId;
96
+ intersections: readonly RegionIntersection[];
97
+ }> | Readonly<{
98
+ kind: "path";
99
+ path: string;
100
+ matches: readonly RegionPathMatch[];
101
+ }>;
30
102
  export type KanshiReport = Readonly<{
31
- root: string;
32
- contracts: Section<ContractBoard>;
103
+ root: WorldRoot | null;
104
+ observedAt: string;
105
+ branch: string | null;
106
+ contracts: Section<ContractKanshiBoard>;
33
107
  tasks: Section<TaskKanshiWorld>;
34
108
  akuma: Section<AkumaKanshiWorld>;
109
+ region?: Section<RegionRead>;
35
110
  }>;
@@ -1,4 +1,5 @@
1
1
  import type { KanshiReport } from "./report.js";
2
+ import type { KanshiRegionSelection, RegionDeclaration, RegionRead } from "./report.js";
2
3
  export type KanshiSelection = Readonly<{
3
4
  contract: string;
4
5
  }>;
@@ -6,3 +7,7 @@ export declare function selectKanshi(input: Readonly<{
6
7
  report: KanshiReport;
7
8
  contract: string;
8
9
  }>): KanshiReport;
10
+ export declare function selectRegion(input: Readonly<{
11
+ declarations: readonly RegionDeclaration[];
12
+ selection: KanshiRegionSelection;
13
+ }>): RegionRead;
@@ -1,3 +1,4 @@
1
+ import { regionIntersections, regionPathMatches } from "../library/region.js";
1
2
  export function selectKanshi(input) {
2
3
  const { report, contract } = input;
3
4
  return {
@@ -13,9 +14,40 @@ export function selectKanshi(input) {
13
14
  kind: "present",
14
15
  value: {
15
16
  ...report.akuma.value,
16
- rows: [],
17
+ rows: report.akuma.value.rows.filter((row) => row.contract?.id === contract),
17
18
  },
18
19
  }
19
20
  : report.akuma,
20
21
  };
21
22
  }
23
+ export function selectRegion(input) {
24
+ const { declarations, selection } = input;
25
+ if (selection.kind === "declarations")
26
+ return { kind: "declarations", declarations };
27
+ if (selection.kind === "contract") {
28
+ const declaration = declarations.find((value) => value.contract === selection.contract);
29
+ if (declaration === undefined)
30
+ 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
+ }
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 };
53
+ }
@@ -0,0 +1,57 @@
1
+ import { type AkuId } from "../akuma/identity.js";
2
+ import { type AkumaAlias, type AkumaGlob } from "../identity/selector.js";
3
+ import type { Settings } from "../settings.js";
4
+ import type { WorldRoot } from "../world.js";
5
+ import { type Repo } from "./repo.js";
6
+ export type DirectAkumaSelector = AkuId | AkumaAlias;
7
+ export type SetAkumaSelector = DirectAkumaSelector | AkumaGlob | `kei/${string}`;
8
+ export type AkumaAddressInput = Readonly<{
9
+ path: WorldRoot;
10
+ akuma: string;
11
+ settings?: Settings;
12
+ repo?: Repo;
13
+ }>;
14
+ export type AkumaSetAddressInput = Readonly<{
15
+ path: WorldRoot;
16
+ akuma: readonly string[];
17
+ settings?: Settings;
18
+ repo?: Repo;
19
+ }>;
20
+ export type AkumaWorldScopeRefusal = Readonly<{
21
+ kind: "akuma-not-in-world";
22
+ ids: readonly AkuId[];
23
+ world: WorldRoot;
24
+ }>;
25
+ export declare class AkumaWorldScopeError extends TypeError {
26
+ readonly refusal: AkumaWorldScopeRefusal;
27
+ constructor(refusal: AkumaWorldScopeRefusal);
28
+ }
29
+ export type NamedAddressContract = Readonly<{
30
+ id: string;
31
+ disposition: "active" | "terminal";
32
+ workspace: "worktree" | "here";
33
+ worktreePath: string | null;
34
+ }>;
35
+ export type NamedAddress = Readonly<{
36
+ kind: "contract";
37
+ id: string;
38
+ }> | Readonly<{
39
+ kind: "akuma";
40
+ id: AkuId;
41
+ }>;
42
+ export type NamedAddressInput = Readonly<{
43
+ path: WorldRoot | null;
44
+ selector: string;
45
+ contracts: readonly NamedAddressContract[];
46
+ }>;
47
+ export declare function resolveNamedAddress(input: NamedAddressInput): Promise<NamedAddress>;
48
+ export declare function addressAkuma(input: AkumaAddressInput): Promise<Readonly<{
49
+ path: WorldRoot;
50
+ id: AkuId;
51
+ settings?: Settings;
52
+ }>>;
53
+ export declare function addressAkumaSet(input: AkumaSetAddressInput): Promise<Readonly<{
54
+ path: WorldRoot;
55
+ ids: readonly AkuId[];
56
+ settings?: Settings;
57
+ }>>;