@astrosheep/keiyaku 4.0.1 → 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 (245) hide show
  1. package/README.md +137 -5
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
  9. package/build/src/akuma/abort.d.ts +2 -0
  10. package/build/src/akuma/abort.js +50 -0
  11. package/build/src/akuma/akuma.d.ts +23 -14
  12. package/build/src/akuma/akuma.js +120 -104
  13. package/build/src/akuma/archetype.d.ts +7 -6
  14. package/build/src/akuma/archetype.js +68 -41
  15. package/build/src/akuma/body.d.ts +3 -5
  16. package/build/src/akuma/body.js +408 -213
  17. package/build/src/akuma/heart/facts.d.ts +25 -34
  18. package/build/src/akuma/heart/facts.js +18 -7
  19. package/build/src/akuma/heart/index.d.ts +39 -42
  20. package/build/src/akuma/heart/index.js +134 -93
  21. package/build/src/akuma/heart/rows.d.ts +9 -31
  22. package/build/src/akuma/heart/rows.js +26 -44
  23. package/build/src/akuma/heart/schema.d.ts +1 -1
  24. package/build/src/akuma/heart/schema.js +7 -15
  25. package/build/src/akuma/heart/soul.d.ts +8 -0
  26. package/build/src/akuma/heart/soul.js +136 -0
  27. package/build/src/akuma/heart/storage.d.ts +28 -14
  28. package/build/src/akuma/heart/storage.js +86 -26
  29. package/build/src/akuma/identity.d.ts +2 -2
  30. package/build/src/akuma/identity.js +9 -9
  31. package/build/src/akuma/index.d.ts +6 -1
  32. package/build/src/akuma/index.js +6 -0
  33. package/build/src/akuma/projection.d.ts +117 -38
  34. package/build/src/akuma/projection.js +208 -97
  35. package/build/src/akuma/provider-recipe.d.ts +24 -0
  36. package/build/src/akuma/provider-recipe.js +100 -0
  37. package/build/src/akuma/provider.d.ts +12 -4
  38. package/build/src/akuma/provider.js +117 -70
  39. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  40. package/build/src/akuma/providers/acp/core.js +159 -0
  41. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  42. package/build/src/akuma/providers/acp/events.js +73 -0
  43. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  44. package/build/src/akuma/providers/acp/index.js +94 -0
  45. package/build/src/akuma/providers/claude/events.js +66 -13
  46. package/build/src/akuma/providers/claude/index.d.ts +2 -1
  47. package/build/src/akuma/providers/claude/index.js +35 -21
  48. package/build/src/akuma/providers/codex-app-server/events.js +4 -1
  49. package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
  50. package/build/src/akuma/providers/codex-app-server/index.js +24 -31
  51. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  52. package/build/src/akuma/providers/grok-build/index.js +70 -0
  53. package/build/src/akuma/providers/index.d.ts +5 -3
  54. package/build/src/akuma/providers/index.js +24 -59
  55. package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
  56. package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
  57. package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
  58. package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
  59. package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
  60. package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
  61. package/build/src/akuma/providers/pi/events.js +49 -11
  62. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  63. package/build/src/akuma/providers/pi/index.js +50 -21
  64. package/build/src/akuma/publication.d.ts +3 -3
  65. package/build/src/akuma/publication.js +28 -40
  66. package/build/src/akuma/requests.d.ts +9 -7
  67. package/build/src/akuma/requests.js +92 -65
  68. package/build/src/alias/index.d.ts +2 -2
  69. package/build/src/alias/index.js +10 -10
  70. package/build/src/body/decode.js +7 -1
  71. package/build/src/body/region.d.ts +2 -0
  72. package/build/src/body/region.js +77 -7
  73. package/build/src/cli/accepted.d.ts +17 -13
  74. package/build/src/cli/accepted.js +72 -34
  75. package/build/src/cli/actor.js +3 -3
  76. package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
  77. package/build/src/cli/commands/akuma-invoke.js +14 -9
  78. package/build/src/cli/commands/akuma.d.ts +13 -3
  79. package/build/src/cli/commands/akuma.js +67 -34
  80. package/build/src/cli/commands/contract.d.ts +18 -5
  81. package/build/src/cli/commands/contract.js +9 -3
  82. package/build/src/cli/commands/task-invoke.d.ts +17 -4
  83. package/build/src/cli/commands/task-invoke.js +43 -20
  84. package/build/src/cli/commands/task-query.d.ts +5 -0
  85. package/build/src/cli/commands/task-query.js +247 -0
  86. package/build/src/cli/commands/task.d.ts +3 -1
  87. package/build/src/cli/commands/task.js +51 -13
  88. package/build/src/cli/coordinates.d.ts +18 -0
  89. package/build/src/cli/coordinates.js +120 -0
  90. package/build/src/cli/draft.d.ts +8 -0
  91. package/build/src/cli/draft.js +96 -0
  92. package/build/src/cli/invoke.d.ts +4 -3
  93. package/build/src/cli/invoke.js +160 -179
  94. package/build/src/cli/main.js +34 -6
  95. package/build/src/cli/parse.d.ts +9 -2
  96. package/build/src/cli/parse.js +29 -7
  97. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  98. package/build/src/cli/render/akuma-tool-command.js +144 -0
  99. package/build/src/cli/render/akuma-tool.d.ts +2 -2
  100. package/build/src/cli/render/akuma-tool.js +30 -4
  101. package/build/src/cli/render/akuma.d.ts +1 -0
  102. package/build/src/cli/render/akuma.js +211 -116
  103. package/build/src/cli/render/audit.d.ts +3 -0
  104. package/build/src/cli/render/audit.js +104 -0
  105. package/build/src/cli/render/contract.d.ts +3 -3
  106. package/build/src/cli/render/contract.js +192 -79
  107. package/build/src/cli/render/kanshi.js +263 -168
  108. package/build/src/cli/render/receipt.d.ts +19 -0
  109. package/build/src/cli/render/receipt.js +106 -0
  110. package/build/src/cli/render/refusal.d.ts +16 -2
  111. package/build/src/cli/render/refusal.js +88 -20
  112. package/build/src/cli/render/region.d.ts +2 -0
  113. package/build/src/cli/render/region.js +17 -0
  114. package/build/src/cli/render/task.d.ts +2 -1
  115. package/build/src/cli/render/task.js +223 -60
  116. package/build/src/cli/render/terminal.d.ts +7 -0
  117. package/build/src/cli/render/terminal.js +46 -0
  118. package/build/src/cli/render/text.js +6 -3
  119. package/build/src/cli/result.d.ts +115 -20
  120. package/build/src/cli/usage.d.ts +1 -0
  121. package/build/src/cli/usage.js +3 -0
  122. package/build/src/contract-worktree.d.ts +6 -5
  123. package/build/src/contract-worktree.js +95 -57
  124. package/build/src/coordination/durable-file.d.ts +4 -3
  125. package/build/src/coordination/durable-file.js +29 -25
  126. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  127. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  128. package/build/src/core/facts/fold.js +1 -6
  129. package/build/src/core/facts/gate.d.ts +1 -0
  130. package/build/src/core/facts/gate.js +1 -0
  131. package/build/src/core/verbs/amend.d.ts +1 -1
  132. package/build/src/core/verbs/amend.js +0 -11
  133. package/build/src/core/verbs/deliver.d.ts +1 -1
  134. package/build/src/core/verbs/deliver.js +1 -7
  135. package/build/src/core/verbs/placement.d.ts +1 -1
  136. package/build/src/core/verbs/placement.js +4 -1
  137. package/build/src/dispatch/index.d.ts +2 -2
  138. package/build/src/dispatch/index.js +17 -17
  139. package/build/src/git/admission.d.ts +1 -1
  140. package/build/src/git/admission.js +11 -11
  141. package/build/src/git/hooks.js +13 -13
  142. package/build/src/git/integration.d.ts +14 -15
  143. package/build/src/git/integration.js +80 -44
  144. package/build/src/git/observe.d.ts +5 -3
  145. package/build/src/git/observe.js +18 -12
  146. package/build/src/git/read-observation.js +9 -9
  147. package/build/src/git/reconcile.d.ts +2 -0
  148. package/build/src/git/reconcile.js +138 -95
  149. package/build/src/git/repository.d.ts +27 -19
  150. package/build/src/git/repository.js +155 -83
  151. package/build/src/git/scratch.d.ts +7 -3
  152. package/build/src/git/scratch.js +44 -37
  153. package/build/src/git/target-placement.d.ts +40 -4
  154. package/build/src/git/target-placement.js +221 -101
  155. package/build/src/git/tender.d.ts +6 -5
  156. package/build/src/git/tender.js +24 -43
  157. package/build/src/git/terminal-seal.d.ts +1 -1
  158. package/build/src/git/terminal-seal.js +7 -5
  159. package/build/src/git/workspace.d.ts +36 -4
  160. package/build/src/git/workspace.js +53 -18
  161. package/build/src/identity/selector.js +1 -1
  162. package/build/src/index.d.ts +3 -3
  163. package/build/src/index.js +1 -1
  164. package/build/src/kanshi/index.d.ts +2 -2
  165. package/build/src/kanshi/index.js +1 -1
  166. package/build/src/kanshi/read.d.ts +2 -1
  167. package/build/src/kanshi/read.js +118 -27
  168. package/build/src/kanshi/report.d.ts +50 -0
  169. package/build/src/kanshi/select.d.ts +5 -0
  170. package/build/src/kanshi/select.js +32 -0
  171. package/build/src/library/address.d.ts +12 -3
  172. package/build/src/library/address.js +77 -46
  173. package/build/src/library/akuma-creation.d.ts +6 -1
  174. package/build/src/library/akuma-creation.js +86 -13
  175. package/build/src/library/audit.d.ts +18 -0
  176. package/build/src/library/audit.js +44 -0
  177. package/build/src/library/bind.js +4 -4
  178. package/build/src/library/catalog.d.ts +1 -1
  179. package/build/src/library/catalog.js +5 -8
  180. package/build/src/library/contract.d.ts +5 -6
  181. package/build/src/library/contract.js +11 -35
  182. package/build/src/library/delivery.d.ts +2 -1
  183. package/build/src/library/fleet.d.ts +2 -2
  184. package/build/src/library/fleet.js +35 -71
  185. package/build/src/library/keiyaku.d.ts +3 -2
  186. package/build/src/library/keiyaku.js +1 -0
  187. package/build/src/library/mutation.d.ts +7 -6
  188. package/build/src/library/mutation.js +23 -25
  189. package/build/src/library/reconcile.d.ts +29 -0
  190. package/build/src/library/reconcile.js +179 -0
  191. package/build/src/library/region.d.ts +12 -0
  192. package/build/src/library/region.js +15 -1
  193. package/build/src/library/repo.d.ts +4 -16
  194. package/build/src/library/repo.js +13 -38
  195. package/build/src/protocol/attempt.js +6 -6
  196. package/build/src/protocol/bind.js +4 -4
  197. package/build/src/protocol/intent.d.ts +15 -2
  198. package/build/src/protocol/intent.js +21 -6
  199. package/build/src/protocol/operations.d.ts +73 -22
  200. package/build/src/protocol/operations.js +292 -88
  201. package/build/src/protocol/outcome.d.ts +9 -3
  202. package/build/src/protocol/outcome.js +3 -1
  203. package/build/src/protocol/placement.d.ts +15 -4
  204. package/build/src/protocol/placement.js +58 -25
  205. package/build/src/protocol/read/status.d.ts +8 -1
  206. package/build/src/protocol/read/status.js +61 -14
  207. package/build/src/runtime/proc/line-rpc.d.ts +3 -8
  208. package/build/src/runtime/proc/line-rpc.js +16 -43
  209. package/build/src/runtime/proc/run.d.ts +15 -29
  210. package/build/src/runtime/proc/run.js +113 -105
  211. package/build/src/runtime/proc/stdio.d.ts +18 -0
  212. package/build/src/runtime/proc/stdio.js +58 -0
  213. package/build/src/settings.d.ts +2 -2
  214. package/build/src/settings.js +8 -8
  215. package/build/src/settlement/fence.d.ts +0 -4
  216. package/build/src/settlement/fence.js +0 -9
  217. package/build/src/settlement/holder.d.ts +11 -1
  218. package/build/src/settlement/holder.js +25 -0
  219. package/build/src/settlement/settle.d.ts +1 -1
  220. package/build/src/settlement/settle.js +52 -89
  221. package/build/src/task/board.d.ts +3 -3
  222. package/build/src/task/board.js +6 -9
  223. package/build/src/task/compose.d.ts +1 -1
  224. package/build/src/task/compose.js +18 -10
  225. package/build/src/task/context.d.ts +3 -3
  226. package/build/src/task/context.js +14 -14
  227. package/build/src/task/document.d.ts +2 -1
  228. package/build/src/task/document.js +15 -5
  229. package/build/src/task/index.d.ts +19 -7
  230. package/build/src/task/index.js +42 -23
  231. package/build/src/task/operations.d.ts +15 -9
  232. package/build/src/task/operations.js +78 -48
  233. package/build/src/task/query.d.ts +67 -0
  234. package/build/src/task/query.js +279 -0
  235. package/build/src/task/store.d.ts +2 -2
  236. package/build/src/task/store.js +40 -25
  237. package/build/src/verification/execution.d.ts +4 -2
  238. package/build/src/verification/execution.js +9 -5
  239. package/build/src/workspace-place.d.ts +41 -0
  240. package/build/src/workspace-place.js +386 -0
  241. package/build/src/world.d.ts +13 -2
  242. package/build/src/world.js +81 -48
  243. package/package.json +3 -2
  244. package/build/src/protocol/read/audit.d.ts +0 -31
  245. package/build/src/protocol/read/audit.js +0 -55
@@ -1,10 +1,10 @@
1
1
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
2
2
  import { gitObjectId, gitObjectIdForSnapshot, mintChangeId, mintSnapshotId } from "./identity.js";
3
- import { GitPlumbingError, readRef, runGit, runGitWithEnvironment, } from "./repository.js";
3
+ import { decodeGitNameOnly, decodeGitNumstat, GitPlumbingError, readRef, runGit, runGitWithEnvironment, } from "./repository.js";
4
4
  const REQUIRED_GIT = "2.38";
5
- function runAllowingNonzero(repository, args, input) {
5
+ async function runAllowingNonzero(repository, args, input) {
6
6
  try {
7
- return { stdout: runGit(repository, args, input), stderr: Buffer.alloc(0), status: 0 };
7
+ return { stdout: await runGit(repository, args, input), stderr: Buffer.alloc(0), status: 0 };
8
8
  }
9
9
  catch (error) {
10
10
  if (!(error instanceof GitPlumbingError))
@@ -12,29 +12,51 @@ function runAllowingNonzero(repository, args, input) {
12
12
  return { stdout: error.stdout, stderr: error.stderr, status: error.status };
13
13
  }
14
14
  }
15
- function stablePatchId(repository, predecessor, tree) {
16
- const diff = runGit(repository, ["diff", "--binary", gitObjectIdForSnapshot(predecessor), tree]);
17
- const output = runGit(repository, ["patch-id", "--stable"], diff).toString("utf8").trim();
18
- const separator = output.indexOf(" ");
19
- const identity = output.length === 0
20
- ? runGit(repository, ["hash-object", "-t", "blob", "--stdin"], diff).toString("utf8").trim()
21
- : separator < 0 ? output : output.slice(0, separator);
22
- return mintChangeId(identity);
15
+ /** Mint the one worktree-content identity shared by review and delivery. */
16
+ export async function worktreeChangeId(repository, input, tender) {
17
+ const patch = await runGit(repository, [
18
+ "-c", "core.quotePath=false",
19
+ "-c", "core.abbrev=40",
20
+ "-c", "diff.algorithm=myers",
21
+ "-c", "diff.renames=false",
22
+ "-c", "diff.indentHeuristic=false",
23
+ "-c", "diff.suppressBlankEmpty=false",
24
+ "diff",
25
+ "--no-ext-diff",
26
+ "--no-textconv",
27
+ "--no-indent-heuristic",
28
+ "--no-renames",
29
+ "--full-index",
30
+ "--binary",
31
+ "--no-color",
32
+ "--diff-algorithm=myers",
33
+ "--unified=3",
34
+ "--src-prefix=a/",
35
+ "--dst-prefix=b/",
36
+ "--inter-hunk-context=0",
37
+ "--no-relative",
38
+ "--ignore-submodules=none",
39
+ "--submodule=short",
40
+ gitObjectIdForSnapshot(input.coordinates.start),
41
+ tender.tree,
42
+ ]);
43
+ const id = (await runGit(repository, ["patch-id", "--verbatim"], patch)).toString("utf8").trim().split(/\s/, 1)[0] ?? "";
44
+ return mintChangeId(id === "" ? "0000000000000000000000000000000000000000" : id);
23
45
  }
24
46
  /** Materialize the exact integration tree against its observed predecessor. */
25
- export function materializeIntegrationSnapshot(repository, tree, parent, input) {
26
- const commit = runGitWithEnvironment(repository, ["commit-tree", tree, "-p", gitObjectIdForSnapshot(parent)], `${input.message ?? `${input.contractId}: ${input.title}`}\n\nKeiyaku-Contract: ${input.contractId}\n`, {
47
+ export async function materializeIntegrationSnapshot(repository, tree, parent, input) {
48
+ const commit = (await runGitWithEnvironment(repository, ["commit-tree", tree, "-p", gitObjectIdForSnapshot(parent)], `${input.message ?? `${input.contractId}: ${input.title}`}\n\nKeiyaku-Contract: ${input.contractId}\n`, {
27
49
  GIT_AUTHOR_NAME: "Keiyaku",
28
50
  GIT_AUTHOR_EMAIL: "keiyaku@localhost",
29
51
  GIT_COMMITTER_NAME: "Keiyaku",
30
52
  GIT_COMMITTER_EMAIL: "keiyaku@localhost",
31
53
  GIT_AUTHOR_DATE: "Thu, 01 Jan 1970 00:00:00 +0000",
32
54
  GIT_COMMITTER_DATE: "Thu, 01 Jan 1970 00:00:00 +0000",
33
- }).toString("utf8").trim();
55
+ })).toString("utf8").trim();
34
56
  return mintSnapshotId(commit);
35
57
  }
36
- function isAncestor(repository, ancestor, descendant) {
37
- const result = runAllowingNonzero(repository, [
58
+ async function isAncestor(repository, ancestor, descendant) {
59
+ const result = await runAllowingNonzero(repository, [
38
60
  "merge-base",
39
61
  "--is-ancestor",
40
62
  gitObjectIdForSnapshot(ancestor),
@@ -50,8 +72,8 @@ function isAncestor(repository, ancestor, descendant) {
50
72
  message: "git merge-base --is-ancestor failed",
51
73
  });
52
74
  }
53
- function commonAncestor(repository, left, right) {
54
- const result = runAllowingNonzero(repository, [
75
+ async function commonAncestor(repository, left, right) {
76
+ const result = await runAllowingNonzero(repository, [
55
77
  "merge-base",
56
78
  gitObjectIdForSnapshot(left),
57
79
  gitObjectIdForSnapshot(right),
@@ -67,8 +89,8 @@ function commonAncestor(repository, left, right) {
67
89
  }
68
90
  return mintSnapshotId(result.stdout.toString("utf8").trim());
69
91
  }
70
- function supportsMergeTree(repository) {
71
- return runAllowingNonzero(repository, ["merge-tree", "--write-tree", "--stdin"], "").status === 0;
92
+ async function supportsMergeTree(repository) {
93
+ return (await runAllowingNonzero(repository, ["merge-tree", "--write-tree", "--stdin"], "")).status === 0;
72
94
  }
73
95
  function nulFields(output) {
74
96
  const fields = output.toString("utf8").split("\0");
@@ -76,11 +98,11 @@ function nulFields(output) {
76
98
  throw new Error("Git merge-tree output is not NUL terminated");
77
99
  return fields.slice(0, -1);
78
100
  }
79
- function mergedTree(repository, contractId, base, targetHead, tenderTree) {
80
- if (!supportsMergeTree(repository)) {
101
+ async function mergedTree(repository, contractId, base, targetHead, tenderTree) {
102
+ if (!(await supportsMergeTree(repository))) {
81
103
  return { kind: "refused", refusal: { kind: "integration-unsupported", contractId, requiredGit: REQUIRED_GIT } };
82
104
  }
83
- const result = runAllowingNonzero(repository, [
105
+ const result = await runAllowingNonzero(repository, [
84
106
  "merge-tree",
85
107
  "--write-tree",
86
108
  "--no-messages",
@@ -117,7 +139,7 @@ function mergedTree(repository, contractId, base, targetHead, tenderTree) {
117
139
  message: "git merge-tree --write-tree failed",
118
140
  });
119
141
  }
120
- export function planIntegration(repository, input, tender, requireBranchesToBeUpToDate) {
142
+ export async function planIntegration(repository, input, tender, requireBranchesToBeUpToDate) {
121
143
  const target = input.coordinates.target;
122
144
  if (target === undefined) {
123
145
  return {
@@ -125,18 +147,17 @@ export function planIntegration(repository, input, tender, requireBranchesToBeUp
125
147
  data: {
126
148
  predecessor: input.coordinates.start,
127
149
  tree: tender.tree,
128
- changeId: stablePatchId(repository, input.coordinates.start, tender.tree),
129
150
  },
130
151
  };
131
152
  }
132
- const observed = readRef(repository, target);
153
+ const observed = await readRef(repository, target);
133
154
  if (observed === null) {
134
155
  return { kind: "refused", refusal: { kind: "target-missing", contractId: input.contractId } };
135
156
  }
136
157
  const targetHead = mintSnapshotId(observed);
137
158
  let tree;
138
159
  if (requireBranchesToBeUpToDate) {
139
- if (!isAncestor(repository, targetHead, tender.head)) {
160
+ if (!(await isAncestor(repository, targetHead, tender.head))) {
140
161
  return {
141
162
  kind: "refused",
142
163
  refusal: {
@@ -150,7 +171,7 @@ export function planIntegration(repository, input, tender, requireBranchesToBeUp
150
171
  tree = tender.tree;
151
172
  }
152
173
  else {
153
- const base = commonAncestor(repository, tender.head, targetHead);
174
+ const base = await commonAncestor(repository, tender.head, targetHead);
154
175
  if (base === null) {
155
176
  return {
156
177
  kind: "refused",
@@ -162,7 +183,7 @@ export function planIntegration(repository, input, tender, requireBranchesToBeUp
162
183
  },
163
184
  };
164
185
  }
165
- const merged = mergedTree(repository, input.contractId, base, targetHead, tender.tree);
186
+ const merged = await mergedTree(repository, input.contractId, base, targetHead, tender.tree);
166
187
  if (merged.kind === "refused")
167
188
  return merged;
168
189
  tree = merged.data;
@@ -172,20 +193,12 @@ export function planIntegration(repository, input, tender, requireBranchesToBeUp
172
193
  data: {
173
194
  predecessor: targetHead,
174
195
  tree,
175
- changeId: stablePatchId(repository, targetHead, tree),
176
196
  },
177
197
  };
178
198
  }
179
- /** Prepare the integration-derived review subject from one captured tender. */
180
- export function prepareReviewIntegration(repository, input, tender, workspace) {
181
- const integration = planIntegration(repository, input, tender, false);
182
- return integration.kind === "refused"
183
- ? integration
184
- : { kind: "prepared", data: { changeId: integration.data.changeId, ...(workspace === undefined ? {} : { workspace }) } };
185
- }
186
- function deliverySnapshotAvailability(repository, predecessor, candidate) {
199
+ async function deliverySnapshotAvailability(repository, predecessor, candidate) {
187
200
  const objects = [gitObjectIdForSnapshot(predecessor), gitObjectIdForSnapshot(candidate)];
188
- const types = runGit(repository, ["cat-file", "--batch-check=%(objectname) %(objecttype)"], `${objects.join("\n")}\n`).toString("ascii").trimEnd().split("\n").map((record) => record.split(" ")[1]);
201
+ const types = (await runGit(repository, ["cat-file", "--batch-check=%(objectname) %(objecttype)"], `${objects.join("\n")}\n`)).toString("ascii").trimEnd().split("\n").map((record) => record.split(" ")[1]);
189
202
  if (types.includes("missing"))
190
203
  return "unavailable";
191
204
  if (types.some((type) => type !== "commit")) {
@@ -193,21 +206,44 @@ function deliverySnapshotAvailability(repository, predecessor, candidate) {
193
206
  }
194
207
  return "available";
195
208
  }
209
+ /** Compute predecessor-to-candidate scope from the exact integration trees. */
210
+ export async function readDeliveryScope(repository, predecessor, candidate, includePaths) {
211
+ const scope = decodeGitNumstat(await runGit(repository, [
212
+ "diff",
213
+ "--numstat",
214
+ "-z",
215
+ gitObjectIdForSnapshot(predecessor),
216
+ gitObjectIdForSnapshot(candidate),
217
+ ]));
218
+ if (!includePaths)
219
+ return scope;
220
+ return {
221
+ ...scope,
222
+ paths: decodeGitNameOnly(await runGit(repository, [
223
+ "diff",
224
+ "--name-only",
225
+ "--no-renames",
226
+ "-z",
227
+ gitObjectIdForSnapshot(predecessor),
228
+ gitObjectIdForSnapshot(candidate),
229
+ ])),
230
+ };
231
+ }
196
232
  /** Read a recorded integration pair's patch, or null when Git no longer has it. */
197
- export function readDeliveryDiff(repository, predecessor, candidate) {
198
- if (deliverySnapshotAvailability(repository, predecessor, candidate) === "unavailable")
233
+ export async function readDeliveryDiff(repository, predecessor, candidate) {
234
+ if (await deliverySnapshotAvailability(repository, predecessor, candidate) === "unavailable")
199
235
  return null;
200
236
  try {
201
- return runGit(repository, [
237
+ return (await runGit(repository, [
202
238
  "diff",
203
239
  "--no-ext-diff",
204
240
  "--no-color",
205
241
  gitObjectIdForSnapshot(predecessor),
206
242
  gitObjectIdForSnapshot(candidate),
207
- ]).toString("utf8");
243
+ ])).toString("utf8");
208
244
  }
209
245
  catch (error) {
210
- if (deliverySnapshotAvailability(repository, predecessor, candidate) === "unavailable")
246
+ if (await deliverySnapshotAvailability(repository, predecessor, candidate) === "unavailable")
211
247
  return null;
212
248
  throw error;
213
249
  }
@@ -33,14 +33,16 @@ export type BindCoordinatesObservation = Readonly<{
33
33
  target?: string;
34
34
  branch: string | null;
35
35
  }>;
36
- export declare function normalizeTargetBranch(repository: GitRepository, input: string): string | null;
36
+ export declare function normalizeTargetBranch(repository: GitRepository, input: string): Promise<string | null>;
37
37
  /** Read one worktree's attached branch, or null for detached HEAD. */
38
- export declare function currentBranch(repository: GitRepository, path?: string): string | null;
38
+ export declare function currentBranch(repository: GitRepository, path?: string): Promise<string | null>;
39
39
  /** Observe bind's tender start and optional reward target without creating persistent state. */
40
- export declare function observeBindCoordinates(repository: GitRepository, requestedTarget?: string): BindCoordinatesObservation | null;
40
+ export declare function observeBindCoordinates(repository: GitRepository, requestedTarget?: string): Promise<BindCoordinatesObservation | null>;
41
41
  export declare function observeActiveContractWorld(observation: GitReadObservation): Promise<ActiveContractWorldObservation>;
42
42
  export declare function observeContractWorld(observation: GitReadObservation, requested?: readonly ContractId[]): Promise<ContractWorldObservation>;
43
43
  export declare function observeContractsForAdmissionAt(repository: GitRepository, channel: GitDecodeChannel, ids: readonly ContractId[], selection?: GitTreeSelection): Promise<GitDecisionObservation>;
44
+ /** Observe selected Contract journals and their current direct prerequisites in one Git epoch. */
45
+ export declare function observeGitForAdmissionAt(repository: GitRepository, channel: GitDecodeChannel, ids: readonly ContractId[], selection?: GitTreeSelection): Promise<GitDecisionObservation>;
44
46
  export declare function withContractReadObservationAt<Value>(repository: GitRepository, channel: GitDecodeChannel, id: ContractId, consume: (observation: GitReadObservation) => Value | PromiseLike<Value>): Promise<Value>;
45
47
  /** Observe targeted Contract journals within an already frozen Git epoch. */
46
48
  export declare function observeContractsForAdmissionInObservationAt(observation: GitReadObservation, ids: readonly ContractId[]): Promise<GitDecisionObservation>;
@@ -19,7 +19,7 @@ export async function observeDeliveryTargetAt(observation, state) {
19
19
  return { head, drift: head !== expected };
20
20
  }
21
21
  const TARGET_COORDINATES_FORMAT = "%(refname)%00%(objectname)%00";
22
- export function normalizeTargetBranch(repository, input) {
22
+ export async function normalizeTargetBranch(repository, input) {
23
23
  if (input.includes("\0"))
24
24
  return null;
25
25
  const prefix = "refs/heads/";
@@ -30,7 +30,7 @@ export function normalizeTargetBranch(repository, input) {
30
30
  if (branch.length === 0 || branch.startsWith("-") || isKeiyakuOwnedRef(target))
31
31
  return null;
32
32
  try {
33
- const checked = runGit(repository, ["check-ref-format", "--branch", branch]).toString("utf8").trim();
33
+ const checked = (await runGit(repository, ["check-ref-format", "--branch", branch])).toString("utf8").trim();
34
34
  return checked === branch ? target : null;
35
35
  }
36
36
  catch (error) {
@@ -40,14 +40,14 @@ export function normalizeTargetBranch(repository, input) {
40
40
  }
41
41
  }
42
42
  /** Read one worktree's attached branch, or null for detached HEAD. */
43
- export function currentBranch(repository, path) {
43
+ export async function currentBranch(repository, path) {
44
44
  try {
45
- const ref = runGit(repository, [
45
+ const ref = (await runGit(repository, [
46
46
  ...(path === undefined ? [] : ["-C", path]),
47
47
  "symbolic-ref",
48
48
  "--quiet",
49
49
  "HEAD",
50
- ]).toString("utf8").trim();
50
+ ])).toString("utf8").trim();
51
51
  return ref.startsWith("refs/heads/") ? ref : null;
52
52
  }
53
53
  catch (error) {
@@ -66,12 +66,12 @@ function structuredFields(output, fieldCount) {
66
66
  return fields.slice(0, -1);
67
67
  }
68
68
  /** Observe bind's tender start and optional reward target without creating persistent state. */
69
- export function observeBindCoordinates(repository, requestedTarget) {
69
+ export async function observeBindCoordinates(repository, requestedTarget) {
70
70
  if (requestedTarget === undefined) {
71
71
  try {
72
72
  return {
73
- start: mintSnapshotId(runGit(repository, ["rev-parse", "--verify", "HEAD"]).toString("utf8").trim()),
74
- branch: currentBranch(repository),
73
+ start: mintSnapshotId((await runGit(repository, ["rev-parse", "--verify", "HEAD"])).toString("utf8").trim()),
74
+ branch: await currentBranch(repository),
75
75
  };
76
76
  }
77
77
  catch {
@@ -81,7 +81,7 @@ export function observeBindCoordinates(repository, requestedTarget) {
81
81
  if (isKeiyakuOwnedRef(requestedTarget)) {
82
82
  throw new Error(`bind target names a Keiyaku-owned ref: ${requestedTarget}`);
83
83
  }
84
- const output = runGit(repository, [
84
+ const output = await runGit(repository, [
85
85
  "for-each-ref",
86
86
  `--format=${TARGET_COORDINATES_FORMAT}`,
87
87
  "--",
@@ -93,7 +93,7 @@ export function observeBindCoordinates(repository, requestedTarget) {
93
93
  if (target !== requestedTarget || start === undefined)
94
94
  malformedBindCoordinatesOutput();
95
95
  try {
96
- return { target, start: mintSnapshotId(start), branch: currentBranch(repository) };
96
+ return { target, start: mintSnapshotId(start), branch: await currentBranch(repository) };
97
97
  }
98
98
  catch {
99
99
  malformedBindCoordinatesOutput();
@@ -218,7 +218,7 @@ export async function observeContractWorld(observation, requested = []) {
218
218
  };
219
219
  }
220
220
  async function observeTargetedContractsAt(observation, ids) {
221
- return observeTargetedContractsFromSnapshotAt(observation.snapshot, observation.readBlobs, ids);
221
+ return await observeTargetedContractsFromSnapshotAt(observation.snapshot, observation.readBlobs, ids);
222
222
  }
223
223
  async function observeTargetedContractsFromSnapshotAt(snapshot, readBlobsAt, ids) {
224
224
  const paths = ids.flatMap(contractJournalPaths);
@@ -243,7 +243,13 @@ export async function observeContractsForAdmissionAt(repository, channel, ids, s
243
243
  return withGitTargetedReadObservation(repository, channel, {
244
244
  paths: [...ids.flatMap(contractJournalPaths), ...(selection.paths ?? [])],
245
245
  ...(selection.subtrees === undefined ? {} : { subtrees: selection.subtrees }),
246
- }, (observation) => observeContractsForAdmissionInObservationAt(observation, ids));
246
+ }, async (observation) => await observeContractsForAdmissionInObservationAt(observation, ids));
247
+ }
248
+ /** Observe selected Contract journals and their current direct prerequisites in one Git epoch. */
249
+ export async function observeGitForAdmissionAt(repository, channel, ids, selection = {}) {
250
+ const observation = await observeContractsForAdmissionAt(repository, channel, ids, selection);
251
+ const prerequisites = [...new Set(ids.flatMap((id) => observation.decision.get(id)?.terms.after ?? []))];
252
+ return await extendContractsForAdmissionAt(channel, observation, prerequisites);
247
253
  }
248
254
  export function withContractReadObservationAt(repository, channel, id, consume) {
249
255
  return withGitTargetedReadObservation(repository, channel, {
@@ -100,7 +100,7 @@ function batchObjectReader(repository) {
100
100
  const cached = cache.get(oid);
101
101
  if (cached !== undefined)
102
102
  return cached;
103
- const requested = tail.then(() => read(oid));
103
+ const requested = tail.then(async () => await read(oid));
104
104
  tail = requested.then(() => undefined, () => undefined);
105
105
  cache.set(oid, requested);
106
106
  return requested;
@@ -280,7 +280,7 @@ export async function withGitDecodeChannel(repository, consume) {
280
280
  return result;
281
281
  }
282
282
  async function observeEpoch(repository, channel, selection, consume) {
283
- const commit = readRef(repository, GIT_REF);
283
+ const commit = await readRef(repository, GIT_REF);
284
284
  let active = true;
285
285
  const refs = new Map();
286
286
  const assertActive = () => {
@@ -291,10 +291,10 @@ async function observeEpoch(repository, channel, selection, consume) {
291
291
  assertActive();
292
292
  let resolved = refs.get(ref);
293
293
  if (resolved === undefined) {
294
- resolved = Promise.resolve().then(() => readRef(repository, ref));
294
+ resolved = readRef(repository, ref);
295
295
  refs.set(ref, resolved);
296
296
  }
297
- return resolved;
297
+ return await resolved;
298
298
  };
299
299
  const readBlobResults = async (oids) => {
300
300
  assertActive();
@@ -326,7 +326,7 @@ async function observeEpoch(repository, channel, selection, consume) {
326
326
  const commitObject = (await channel.readObjects([commit])).get(commit);
327
327
  if (commitObject === undefined)
328
328
  throw new Error(`missing state commit result: ${commit}`);
329
- const tree = commitTree(commitObject, commit);
329
+ const tree = await commitTree(commitObject, commit);
330
330
  const observed = selection === null
331
331
  ? await completeTree(channel, tree)
332
332
  : await readGitTreeSelection(channel, tree, selection);
@@ -353,9 +353,9 @@ async function observeEpoch(repository, channel, selection, consume) {
353
353
  throw failure;
354
354
  return result;
355
355
  }
356
- export function withGitReadObservation(repository, channel, consume) {
357
- return observeEpoch(repository, channel, null, consume);
356
+ export async function withGitReadObservation(repository, channel, consume) {
357
+ return await observeEpoch(repository, channel, null, consume);
358
358
  }
359
- export function withGitTargetedReadObservation(repository, channel, selection, consume) {
360
- return observeEpoch(repository, channel, selection, consume);
359
+ export async function withGitTargetedReadObservation(repository, channel, selection, consume) {
360
+ return await observeEpoch(repository, channel, selection, consume);
361
361
  }
@@ -22,6 +22,7 @@ type ReconcileInput = Readonly<{
22
22
  hooks: WorktreeHooks;
23
23
  retryHooks: boolean;
24
24
  retainTerminalWorktree?: boolean;
25
+ place?: string;
25
26
  }>;
26
27
  type WorktreeRetained = Readonly<{
27
28
  kind: "worktree-retained";
@@ -53,6 +54,7 @@ type ReconcileBatchOptions = Readonly<{
53
54
  hooks: WorktreeHooks;
54
55
  retryHooks: boolean;
55
56
  retainTerminalWorktree: boolean;
57
+ places?: ReadonlyMap<ContractId, string>;
56
58
  }>;
57
59
  /** Reconcile each discovered Contract through its own serialized, fresh observation. */
58
60
  export declare function reconcileBatch(repository: GitRepository, channel: GitDecodeChannel, contracts: Iterable<ContractId>, options: ReconcileBatchOptions): Promise<readonly ReconcileBatchItem[]>;