@astrosheep/keiyaku 4.0.3 → 4.0.5
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.
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +15 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +34 -13
- package/build/src/akuma/akuma.d.ts +34 -12
- package/build/src/akuma/akuma.js +118 -63
- package/build/src/akuma/allowed.d.ts +7 -0
- package/build/src/akuma/allowed.js +33 -0
- package/build/src/akuma/archetype.d.ts +7 -4
- package/build/src/akuma/archetype.js +15 -16
- package/build/src/akuma/body.d.ts +6 -1
- package/build/src/akuma/body.js +36 -27
- package/build/src/akuma/heart/facts.d.ts +82 -14
- package/build/src/akuma/heart/index.d.ts +5 -18
- package/build/src/akuma/heart/index.js +14 -84
- package/build/src/akuma/heart/request-authority.d.ts +12 -0
- package/build/src/akuma/heart/request-authority.js +119 -0
- package/build/src/akuma/heart/request-rows.d.ts +16 -0
- package/build/src/akuma/heart/request-rows.js +88 -0
- package/build/src/akuma/heart/rows.d.ts +1 -26
- package/build/src/akuma/heart/rows.js +0 -50
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +22 -10
- package/build/src/akuma/heart/soul.js +2 -36
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +15 -0
- package/build/src/akuma/heart/timeline.d.ts +1 -5
- package/build/src/akuma/heart/timeline.js +8 -17
- package/build/src/akuma/index.d.ts +5 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/projection.d.ts +17 -3
- package/build/src/akuma/projection.js +40 -3
- package/build/src/akuma/provider-recipe.js +1 -11
- package/build/src/akuma/provider.d.ts +2 -7
- package/build/src/akuma/provider.js +2 -1
- package/build/src/akuma/providers/acp/core.d.ts +3 -1
- package/build/src/akuma/providers/acp/core.js +10 -6
- package/build/src/akuma/providers/acp/events.d.ts +11 -3
- package/build/src/akuma/providers/acp/events.js +78 -4
- package/build/src/akuma/providers/acp/index.js +0 -1
- package/build/src/akuma/providers/claude/events.js +62 -3
- package/build/src/akuma/providers/claude/index.d.ts +0 -4
- package/build/src/akuma/providers/claude/index.js +7 -3
- package/build/src/akuma/providers/codex-app-server/events.js +1 -13
- package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
- package/build/src/akuma/providers/codex-app-server/index.js +0 -2
- package/build/src/akuma/providers/grok-build/index.d.ts +2 -1
- package/build/src/akuma/providers/grok-build/index.js +72 -3
- package/build/src/akuma/providers/opencode-sdk/events.js +71 -6
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
- package/build/src/akuma/providers/opencode-sdk/index.js +8 -4
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
- package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
- package/build/src/akuma/providers/pi/events.js +17 -3
- package/build/src/akuma/providers/pi/index.js +11 -4
- package/build/src/akuma/providers/unified-patch.d.ts +4 -0
- package/build/src/akuma/providers/unified-patch.js +14 -0
- package/build/src/akuma/publication.d.ts +1 -1
- package/build/src/akuma/publication.js +1 -1
- package/build/src/akuma/request-serve.d.ts +87 -0
- package/build/src/akuma/request-serve.js +484 -0
- package/build/src/akuma/request-wire.d.ts +124 -0
- package/build/src/akuma/request-wire.js +380 -0
- package/build/src/akuma/requests.d.ts +41 -41
- package/build/src/akuma/requests.js +75 -374
- package/build/src/akuma-body.d.ts +8 -0
- package/build/src/akuma-body.js +84 -0
- package/build/src/body/arc.js +4 -29
- package/build/src/body/decode.js +5 -39
- package/build/src/body/envelope.d.ts +7 -0
- package/build/src/body/envelope.js +37 -0
- package/build/src/cli/accepted.d.ts +4 -1
- package/build/src/cli/accepted.js +39 -9
- package/build/src/cli/commands/akuma-invoke.d.ts +8 -7
- package/build/src/cli/commands/akuma-invoke.js +18 -10
- package/build/src/cli/commands/akuma.d.ts +11 -2
- package/build/src/cli/commands/akuma.js +67 -28
- package/build/src/cli/commands/amend.d.ts +1 -1
- package/build/src/cli/commands/amend.js +1 -1
- package/build/src/cli/commands/contract.d.ts +8 -8
- package/build/src/cli/commands/contract.js +3 -3
- package/build/src/cli/commands/install.js +2 -2
- package/build/src/cli/commands/task-invoke.js +98 -9
- package/build/src/cli/commands/task-query.d.ts +1 -1
- package/build/src/cli/commands/task-query.js +11 -5
- package/build/src/cli/coordinates.d.ts +2 -0
- package/build/src/cli/coordinates.js +12 -5
- package/build/src/cli/invoke.d.ts +1 -0
- package/build/src/cli/invoke.js +116 -75
- package/build/src/cli/main.d.ts +2 -0
- package/build/src/cli/main.js +29 -4
- package/build/src/cli/parse.d.ts +3 -2
- package/build/src/cli/parse.js +25 -8
- package/build/src/cli/render/akuma.d.ts +2 -2
- package/build/src/cli/render/akuma.js +138 -24
- package/build/src/cli/render/audit.js +18 -8
- package/build/src/cli/render/contract.d.ts +2 -0
- package/build/src/cli/render/contract.js +243 -36
- package/build/src/cli/render/kanshi.js +64 -29
- package/build/src/cli/render/receipt.d.ts +2 -1
- package/build/src/cli/render/receipt.js +37 -2
- package/build/src/cli/render/terminal.d.ts +0 -2
- package/build/src/cli/render/terminal.js +0 -29
- package/build/src/cli/render/text.js +3 -1
- package/build/src/cli/result.d.ts +52 -9
- package/build/src/cli/selectors.d.ts +1 -0
- package/build/src/cli/selectors.js +9 -6
- package/build/src/contract-worktree.d.ts +1 -2
- package/build/src/contract-worktree.js +7 -9
- package/build/src/core/facts/codec.js +9 -0
- package/build/src/core/facts/fold.js +13 -1
- package/build/src/core/facts/types.d.ts +8 -1
- package/build/src/core/subject.js +4 -3
- package/build/src/core/verbs/placement.d.ts +9 -1
- package/build/src/core/verbs/placement.js +24 -6
- package/build/src/core/verbs/reintegrate.d.ts +13 -0
- package/build/src/core/verbs/reintegrate.js +24 -0
- package/build/src/dispatch/index.d.ts +1 -1
- package/build/src/dispatch/index.js +50 -39
- package/build/src/git/admission.d.ts +2 -1
- package/build/src/git/hooks.d.ts +0 -4
- package/build/src/git/hooks.js +0 -36
- package/build/src/git/integration.d.ts +7 -8
- package/build/src/git/integration.js +62 -9
- package/build/src/git/observe.d.ts +2 -1
- package/build/src/git/observe.js +6 -5
- package/build/src/git/process.d.ts +26 -0
- package/build/src/git/process.js +94 -0
- package/build/src/git/read-observation.d.ts +2 -1
- package/build/src/git/read-observation.js +3 -2
- package/build/src/git/reconcile.d.ts +8 -2
- package/build/src/git/reconcile.js +63 -14
- package/build/src/git/repository.d.ts +2 -29
- package/build/src/git/repository.js +4 -118
- package/build/src/git/scratch.d.ts +1 -1
- package/build/src/git/scratch.js +1 -1
- package/build/src/git/target-placement.d.ts +1 -1
- package/build/src/git/target-placement.js +9 -7
- package/build/src/git/tender.d.ts +20 -5
- package/build/src/git/tender.js +45 -13
- package/build/src/git/terminal-seal.d.ts +16 -2
- package/build/src/git/terminal-seal.js +15 -5
- package/build/src/git/workspace.d.ts +2 -1
- package/build/src/git/workspace.js +13 -5
- package/build/src/index.d.ts +1 -2
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +9 -1
- package/build/src/kanshi/read.js +91 -37
- package/build/src/kanshi/report.d.ts +1 -0
- package/build/src/library/address.d.ts +5 -14
- package/build/src/library/address.js +27 -23
- package/build/src/library/akuma-creation.d.ts +4 -2
- package/build/src/library/akuma-creation.js +43 -26
- package/build/src/library/audit.d.ts +2 -1
- package/build/src/library/audit.js +1 -1
- package/build/src/library/bind.d.ts +2 -1
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -2
- package/build/src/library/catalog.js +11 -6
- package/build/src/library/configuration.d.ts +5 -1
- package/build/src/library/configuration.js +71 -18
- package/build/src/library/contract.d.ts +70 -3
- package/build/src/library/contract.js +213 -27
- package/build/src/library/delivery.d.ts +1 -1
- package/build/src/library/fleet.d.ts +70 -12
- package/build/src/library/fleet.js +236 -56
- package/build/src/library/input.d.ts +0 -1
- package/build/src/library/input.js +1 -5
- package/build/src/library/keiyaku.d.ts +4 -4
- package/build/src/library/keiyaku.js +1 -2
- package/build/src/library/mutation.d.ts +2 -1
- package/build/src/library/reconcile.d.ts +2 -1
- package/build/src/library/reconcile.js +3 -1
- package/build/src/library/region.d.ts +1 -1
- package/build/src/library/repo.d.ts +3 -1
- package/build/src/library/repo.js +8 -4
- package/build/src/protocol/abandon.d.ts +9 -0
- package/build/src/protocol/abandon.js +15 -0
- package/build/src/protocol/amend.d.ts +16 -0
- package/build/src/protocol/amend.js +77 -0
- package/build/src/protocol/arc.d.ts +6 -0
- package/build/src/protocol/arc.js +12 -0
- package/build/src/protocol/attempt.d.ts +2 -1
- package/build/src/protocol/audit.d.ts +53 -0
- package/build/src/protocol/audit.js +140 -0
- package/build/src/protocol/bind.d.ts +2 -3
- package/build/src/protocol/bind.js +2 -16
- package/build/src/protocol/completion.d.ts +32 -0
- package/build/src/protocol/completion.js +130 -0
- package/build/src/protocol/deliver.d.ts +37 -0
- package/build/src/protocol/deliver.js +160 -0
- package/build/src/protocol/intent.d.ts +1 -1
- package/build/src/protocol/intent.js +1 -1
- package/build/src/protocol/operations.d.ts +65 -198
- package/build/src/protocol/operations.js +21 -634
- package/build/src/protocol/placement.d.ts +4 -13
- package/build/src/protocol/placement.js +3 -15
- package/build/src/protocol/read/status.d.ts +4 -2
- package/build/src/protocol/read/status.js +27 -15
- package/build/src/protocol/reconcile.d.ts +35 -0
- package/build/src/protocol/reconcile.js +41 -0
- package/build/src/protocol/reintegrate.d.ts +31 -0
- package/build/src/protocol/reintegrate.js +74 -0
- package/build/src/protocol/review.d.ts +33 -0
- package/build/src/protocol/review.js +148 -0
- package/build/src/protocol/run.d.ts +1 -1
- package/build/src/runtime/proc/run.d.ts +1 -0
- package/build/src/runtime/proc/run.js +9 -2
- package/build/src/settlement/fence.d.ts +1 -1
- package/build/src/settlement/holder.d.ts +1 -1
- package/build/src/settlement/settle.d.ts +2 -1
- package/build/src/settlement/settle.js +4 -1
- package/build/src/task/board.d.ts +18 -4
- package/build/src/task/board.js +73 -29
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +11 -4
- package/build/src/task/index.d.ts +4 -4
- package/build/src/task/index.js +8 -131
- package/build/src/task/input.d.ts +18 -0
- package/build/src/task/input.js +189 -0
- package/build/src/task/mutation.d.ts +39 -0
- package/build/src/task/mutation.js +85 -0
- package/build/src/task/operations.d.ts +4 -19
- package/build/src/task/operations.js +64 -18
- package/build/src/task/query.d.ts +9 -2
- package/build/src/task/query.js +32 -64
- package/build/src/task/store.js +0 -2
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/verification/execution.js +2 -1
- package/build/src/workspace-place.d.ts +1 -4
- package/build/src/workspace-place.js +0 -15
- package/package.json +5 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { realpath, stat } from "node:fs/promises";
|
|
2
2
|
import { moveAlias } from "../alias/index.js";
|
|
3
|
-
import { Akuma, } from "../akuma/akuma.js";
|
|
3
|
+
import { Akuma, akumaCallExecution, callAkumaWithContext, } from "../akuma/akuma.js";
|
|
4
4
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
5
5
|
import { publishDispatch, readDispatch, } from "../dispatch/index.js";
|
|
6
6
|
import { parseAkumaAlias } from "../identity/selector.js";
|
|
@@ -28,6 +28,17 @@ function settingsOption(value) {
|
|
|
28
28
|
}
|
|
29
29
|
return value;
|
|
30
30
|
}
|
|
31
|
+
function homeOption(value) {
|
|
32
|
+
if (value === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
return nonblank(value, "home");
|
|
35
|
+
}
|
|
36
|
+
function akumaWorld(path, home, settings) {
|
|
37
|
+
return Akuma.of(path, {
|
|
38
|
+
...(home === undefined ? {} : { home }),
|
|
39
|
+
...(settings === undefined ? {} : { settings }),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
31
42
|
function onlyKeys(values, allowed, label) {
|
|
32
43
|
const accepted = new Set(allowed);
|
|
33
44
|
for (const key of Object.keys(values)) {
|
|
@@ -132,31 +143,33 @@ async function resolveCallExecution(input) {
|
|
|
132
143
|
source: "input",
|
|
133
144
|
};
|
|
134
145
|
}
|
|
135
|
-
if (input.contract
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
if (input.contract !== undefined) {
|
|
147
|
+
const seat = seatForKeiyaku(input.contract);
|
|
148
|
+
const state = await currentManagedContract(input.contract, seat.id);
|
|
149
|
+
const appointment = await readManagedWorktreeAppointment(seat.scope, state.id);
|
|
150
|
+
if (appointment.kind === "unappointed") {
|
|
151
|
+
throw unavailableWorkspace(state.id, "is unappointed; use reconcile");
|
|
152
|
+
}
|
|
153
|
+
if (appointment.kind === "failed") {
|
|
154
|
+
throw new Error(`${appointment.diagnostic}; use reconcile`);
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
cwd: await canonicalizeExistingDirectory(appointment.path, `Contract workspace is unavailable: ${appointment.path}`),
|
|
158
|
+
source: "contract-worktree",
|
|
159
|
+
};
|
|
145
160
|
}
|
|
146
|
-
return
|
|
147
|
-
cwd: await canonicalizeExistingDirectory(appointment.path, `Contract workspace is unavailable: ${appointment.path}`),
|
|
148
|
-
source: "contract-worktree",
|
|
149
|
-
};
|
|
161
|
+
return undefined;
|
|
150
162
|
}
|
|
151
163
|
export async function callKeiyaku(input) {
|
|
152
164
|
const values = requireInput(input, "Keiyaku.call input");
|
|
153
|
-
onlyKeys(values, ["path", "archetype", "body", "cwd", "mode", "timeoutMs", "settings", "contract", "alias"], "Keiyaku.call input");
|
|
165
|
+
onlyKeys(values, ["path", "archetype", "body", "cwd", "mode", "timeoutMs", "home", "settings", "contract", "alias", "allowed"], "Keiyaku.call input");
|
|
154
166
|
const path = nonblank(values.path, "path");
|
|
155
167
|
const archetype = nonblank(values.archetype, "archetype");
|
|
156
168
|
const body = text(values.body, "body");
|
|
157
169
|
const cwd = values.cwd === undefined ? undefined : nonblank(values.cwd, "cwd");
|
|
158
170
|
const mode = callMode(values.mode);
|
|
159
171
|
const timeoutMs = callTimeout(values.timeoutMs, mode);
|
|
172
|
+
const home = homeOption(values.home);
|
|
160
173
|
const settings = settingsOption(values.settings);
|
|
161
174
|
const alias = values.alias === undefined
|
|
162
175
|
? undefined
|
|
@@ -167,11 +180,19 @@ export async function callKeiyaku(input) {
|
|
|
167
180
|
...(cwd === undefined ? {} : { cwd }),
|
|
168
181
|
...(seat === undefined ? {} : { contract: values.contract }),
|
|
169
182
|
});
|
|
170
|
-
const
|
|
183
|
+
const world = akumaWorld(path, home, settings);
|
|
184
|
+
const call = {
|
|
171
185
|
archetype,
|
|
172
186
|
body,
|
|
173
|
-
|
|
174
|
-
|
|
187
|
+
...(values.allowed === undefined ? {} : { allowed: values.allowed }),
|
|
188
|
+
...(execution === undefined ? {} : { cwd: execution.cwd }),
|
|
189
|
+
};
|
|
190
|
+
const handle = execution === undefined
|
|
191
|
+
? await world.call(call)
|
|
192
|
+
: await callAkumaWithContext(world, call, { cwdCanonical: true });
|
|
193
|
+
const completedExecution = execution ?? akumaCallExecution(handle);
|
|
194
|
+
if (completedExecution === undefined)
|
|
195
|
+
throw new Error("Akuma call is missing its birth execution");
|
|
175
196
|
const readonly = (await handle.status()).readonly;
|
|
176
197
|
const dispatch = seat === undefined
|
|
177
198
|
? { kind: "none" }
|
|
@@ -195,7 +216,7 @@ export async function callKeiyaku(input) {
|
|
|
195
216
|
kind: "called",
|
|
196
217
|
akuma: handle.id,
|
|
197
218
|
...(readonly === undefined ? {} : { readonly }),
|
|
198
|
-
execution,
|
|
219
|
+
execution: completedExecution,
|
|
199
220
|
dispatch,
|
|
200
221
|
alias: aliasStage,
|
|
201
222
|
observation,
|
|
@@ -203,19 +224,15 @@ export async function callKeiyaku(input) {
|
|
|
203
224
|
}
|
|
204
225
|
export async function forkKeiyaku(input) {
|
|
205
226
|
const values = requireInput(input, "Keiyaku.fork input");
|
|
206
|
-
onlyKeys(values, ["path", "akuma", "at", "
|
|
227
|
+
onlyKeys(values, ["path", "akuma", "at", "repo"], "Keiyaku.fork input");
|
|
207
228
|
const path = nonblank(values.path, "path");
|
|
208
229
|
const at = nonblank(values.at, "at");
|
|
209
|
-
const settings = settingsOption(values.settings);
|
|
210
230
|
const akuma = (await addressAkuma({
|
|
211
231
|
path,
|
|
212
232
|
akuma: nonblank(values.akuma, "akuma"),
|
|
213
|
-
...(settings === undefined ? {} : { settings }),
|
|
214
233
|
})).id;
|
|
215
234
|
const repository = values.repo === undefined ? undefined : scopeForRepo(values.repo);
|
|
216
|
-
const receipt = await Akuma.of(path
|
|
217
|
-
.of({ id: akuma })
|
|
218
|
-
.fork({ at });
|
|
235
|
+
const receipt = await Akuma.of(path).of({ id: akuma }).fork({ at });
|
|
219
236
|
if (receipt.kind !== "forked")
|
|
220
237
|
return { ...receipt, parent: akuma };
|
|
221
238
|
const dispatch = repository === undefined
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ContractId } from "../core/facts/types.js";
|
|
2
|
-
import { type AuditReport
|
|
2
|
+
import { type AuditReport } from "../protocol/audit.js";
|
|
3
|
+
import type { RepositoryScope } from "../protocol/operations.js";
|
|
3
4
|
import { type WorktreeHooks } from "./configuration.js";
|
|
4
5
|
import { type MutationResult } from "./mutation.js";
|
|
5
6
|
export type AuditInput = Readonly<{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { decodeContractDocument } from "../body/decode.js";
|
|
2
2
|
import { withGitDecodeChannel } from "../git/read-observation.js";
|
|
3
|
-
import { auditOperation
|
|
3
|
+
import { auditOperation } from "../protocol/audit.js";
|
|
4
4
|
import { worktreeHooksOption } from "./configuration.js";
|
|
5
5
|
import { actorOption, documentDerivation, optionalBoolean, optionalSignal, requireInput, } from "./input.js";
|
|
6
6
|
import { completeMutation } from "./mutation.js";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ActorId, type ContractId } from "../core/facts/types.js";
|
|
2
2
|
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
3
|
-
import { bindOperation
|
|
3
|
+
import { bindOperation } from "../protocol/bind.js";
|
|
4
|
+
import type { IntentOutcome, RepositoryScope } from "../protocol/operations.js";
|
|
4
5
|
import type { TaskId } from "../task/identity.js";
|
|
5
6
|
import type { VerificationDeclarationPreparation } from "../verification/declaration.js";
|
|
6
7
|
import type { KeiyakuRefusal } from "./refusal.js";
|
|
@@ -2,7 +2,7 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { releaseContractWorktree, reserveContractWorktree, withContractWorktreeAppointment, } from "../contract-worktree.js";
|
|
3
3
|
import { contractIdFromSegment } from "../core/facts/types.js";
|
|
4
4
|
import { fitIdentityStem, normalizeIdentityStem } from "../identity/normalize.js";
|
|
5
|
-
import { bindOperation } from "../protocol/
|
|
5
|
+
import { bindOperation } from "../protocol/bind.js";
|
|
6
6
|
import { claimTaskHolder } from "../settlement/holder.js";
|
|
7
7
|
function candidateId(title, collision) {
|
|
8
8
|
const stem = fitIdentityStem({ stem: normalizeIdentityStem({ source: title }) || "contract", maxBytes: 48 });
|
|
@@ -13,7 +13,6 @@ async function attempt(input, id) {
|
|
|
13
13
|
return bindOperation({
|
|
14
14
|
scope: input.scope,
|
|
15
15
|
channel: input.channel,
|
|
16
|
-
title: input.title,
|
|
17
16
|
terms: input.terms,
|
|
18
17
|
verification: input.verification,
|
|
19
18
|
workspace: input.workspace,
|
|
@@ -26,6 +25,7 @@ async function attempt(input, id) {
|
|
|
26
25
|
});
|
|
27
26
|
}
|
|
28
27
|
async function attemptCandidates(input) {
|
|
28
|
+
let result;
|
|
29
29
|
for (let collision = 0; collision <= 3; collision += 1) {
|
|
30
30
|
const id = candidateId(input.title, collision);
|
|
31
31
|
let reserved = false;
|
|
@@ -40,7 +40,7 @@ async function attemptCandidates(input) {
|
|
|
40
40
|
}
|
|
41
41
|
reserved = true;
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
result = await attempt(input, id);
|
|
44
44
|
if (result.kind === "accepted")
|
|
45
45
|
return result;
|
|
46
46
|
if (reserved)
|
|
@@ -48,7 +48,7 @@ async function attemptCandidates(input) {
|
|
|
48
48
|
if (result.kind !== "refused" || result.refusal.kind !== "contract-exists")
|
|
49
49
|
return result;
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
return result;
|
|
52
52
|
}
|
|
53
53
|
export async function admitBindWithAppointment(input) {
|
|
54
54
|
const action = () => attemptCandidates(input);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type AkumaList } from "../akuma/akuma.js";
|
|
2
2
|
import { type ArchetypeCatalogRow } from "../akuma/archetype.js";
|
|
3
|
-
import type { Settings } from "../settings.js";
|
|
4
3
|
import type { TaskRow } from "../task/index.js";
|
|
5
4
|
import { type ContractBoard } from "./contract.js";
|
|
6
5
|
import { Repo } from "./repo.js";
|
|
@@ -29,7 +28,7 @@ export type CatalogInput = Readonly<{
|
|
|
29
28
|
query: Extract<CatalogQuery, {
|
|
30
29
|
kind: "archetypes";
|
|
31
30
|
}>;
|
|
32
|
-
|
|
31
|
+
home?: string;
|
|
33
32
|
}> | Readonly<{
|
|
34
33
|
query: Extract<CatalogQuery, {
|
|
35
34
|
kind: "akuma";
|
|
@@ -4,10 +4,11 @@ import { observeTaskCatalogRows } from "../task/operations.js";
|
|
|
4
4
|
import { listKeiyaku } from "./contract.js";
|
|
5
5
|
import { requireInput } from "./input.js";
|
|
6
6
|
import { Repo } from "./repo.js";
|
|
7
|
-
function
|
|
8
|
-
if (
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
function optionalHome(value) {
|
|
8
|
+
if (value === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
11
|
+
throw new TypeError("home must be a nonblank string");
|
|
11
12
|
}
|
|
12
13
|
return value;
|
|
13
14
|
}
|
|
@@ -40,7 +41,7 @@ export async function listCatalog(input) {
|
|
|
40
41
|
const values = requireInput(input, "Keiyaku.ls input");
|
|
41
42
|
const query = queryValue(values.query);
|
|
42
43
|
const allowed = query.kind === "contracts" ? ["query", "repo"]
|
|
43
|
-
: query.kind === "archetypes" ? ["query", "
|
|
44
|
+
: query.kind === "archetypes" ? ["query", "home"] : ["query", "path"];
|
|
44
45
|
for (const key of Object.keys(values)) {
|
|
45
46
|
if (!allowed.includes(key))
|
|
46
47
|
throw new TypeError(`Keiyaku.ls input has unknown field: ${key}`);
|
|
@@ -52,7 +53,11 @@ export async function listCatalog(input) {
|
|
|
52
53
|
return { kind: "contracts", root: board.root, state: board.state, rows: board.rows };
|
|
53
54
|
}
|
|
54
55
|
if (query.kind === "archetypes") {
|
|
55
|
-
|
|
56
|
+
const home = optionalHome(values.home);
|
|
57
|
+
return {
|
|
58
|
+
kind: "archetypes",
|
|
59
|
+
rows: await listArchetypeDefinitions(home === undefined ? {} : { home }),
|
|
60
|
+
};
|
|
56
61
|
}
|
|
57
62
|
const path = worldRoot(values.path);
|
|
58
63
|
if (query.kind === "tasks") {
|
|
@@ -4,14 +4,18 @@ export type { HookCommand, WorktreeHooks } from "../git/hooks.js";
|
|
|
4
4
|
export type Gate = string;
|
|
5
5
|
export type GatesFromInput = Readonly<{
|
|
6
6
|
settings: Settings;
|
|
7
|
-
|
|
7
|
+
names?: readonly string[];
|
|
8
8
|
}>;
|
|
9
9
|
export type RequireBranchesToBeUpToDateFromInput = Readonly<{
|
|
10
10
|
settings: Settings;
|
|
11
11
|
}>;
|
|
12
|
+
export type WorktreeHooksFromInput = Readonly<{
|
|
13
|
+
settings: Settings;
|
|
14
|
+
}>;
|
|
12
15
|
export { SettingsError };
|
|
13
16
|
export declare function gatesFrom(input: GatesFromInput): readonly Gate[];
|
|
14
17
|
export declare function requireBranchesToBeUpToDateFrom(input: RequireBranchesToBeUpToDateFromInput): boolean;
|
|
18
|
+
export declare function worktreeHooksFrom(input: WorktreeHooksFromInput): WorktreeHooks;
|
|
15
19
|
export declare function normalizedWorktreeHooks(value: unknown): WorktreeHooks;
|
|
16
20
|
export declare const EMPTY_WORKTREE_HOOKS: WorktreeHooks;
|
|
17
21
|
export declare function worktreeHooksOption(value: unknown): WorktreeHooks;
|
|
@@ -9,31 +9,65 @@ function namespaceFailure(view) {
|
|
|
9
9
|
throw new Error("settings namespace failure expected");
|
|
10
10
|
throw new SettingsError(view.failures.map((failure) => `${failure.scope}: ${failure.diagnostic}`).join("; "));
|
|
11
11
|
}
|
|
12
|
+
function bundleGates(name, value) {
|
|
13
|
+
if (!record(value))
|
|
14
|
+
throw new SettingsError(`gate bundle '${name}' must be an object`);
|
|
15
|
+
if (value.kind !== "bundle") {
|
|
16
|
+
throw new SettingsError(`gate bundle '${name}' has unsupported kind: ${String(value.kind)}`);
|
|
17
|
+
}
|
|
18
|
+
for (const field of Object.keys(value)) {
|
|
19
|
+
if (field !== "kind" && field !== "gates") {
|
|
20
|
+
throw new SettingsError(`gate bundle '${name}' has unknown field: ${field}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (!Array.isArray(value.gates)) {
|
|
24
|
+
throw new SettingsError(`gate bundle '${name}'.gates must be an array`);
|
|
25
|
+
}
|
|
26
|
+
return value.gates.map((gate) => {
|
|
27
|
+
if (!gateWord(gate)) {
|
|
28
|
+
throw new SettingsError(`gate bundle '${name}' contains an invalid gate word`);
|
|
29
|
+
}
|
|
30
|
+
if (gate !== "reviewed" && gate !== "verified") {
|
|
31
|
+
throw new SettingsError(`gate bundle '${name}' contains a gate without a producer: ${gate}`);
|
|
32
|
+
}
|
|
33
|
+
return gate;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
12
36
|
export function gatesFrom(input) {
|
|
13
37
|
if (!record(input))
|
|
14
38
|
throw new TypeError("gatesFrom input must be an object");
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
39
|
+
if (input.names !== undefined && !Array.isArray(input.names)) {
|
|
40
|
+
throw new TypeError("gatesFrom names must be an array");
|
|
41
|
+
}
|
|
42
|
+
const names = input.names ?? ["default"];
|
|
43
|
+
for (const name of names) {
|
|
44
|
+
if (!gateWord(name))
|
|
45
|
+
throw new SettingsError("gate bundle name must match ^[a-z][a-z0-9-]{0,63}$");
|
|
46
|
+
}
|
|
18
47
|
const view = input.settings.namespace("gates");
|
|
19
48
|
if (view.kind === "failed")
|
|
20
49
|
namespaceFailure(view);
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
50
|
+
const expanded = [];
|
|
51
|
+
const seen = new Set();
|
|
52
|
+
for (const name of names) {
|
|
53
|
+
const selected = view.entries.find((entry) => entry.name === name);
|
|
54
|
+
if (selected === undefined) {
|
|
55
|
+
if (input.names === undefined) {
|
|
56
|
+
if (!seen.has("reviewed"))
|
|
57
|
+
expanded.push("reviewed");
|
|
58
|
+
seen.add("reviewed");
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
throw new SettingsError(`unknown gate bundle: ${name}`);
|
|
62
|
+
}
|
|
63
|
+
for (const gate of bundleGates(name, selected.value)) {
|
|
64
|
+
if (seen.has(gate))
|
|
65
|
+
continue;
|
|
66
|
+
seen.add(gate);
|
|
67
|
+
expanded.push(gate);
|
|
68
|
+
}
|
|
26
69
|
}
|
|
27
|
-
|
|
28
|
-
throw new SettingsError(`gate set '${name}' must be an array`);
|
|
29
|
-
const values = selected.value.map((value) => {
|
|
30
|
-
if (!gateWord(value))
|
|
31
|
-
throw new SettingsError(`gate set '${name}' contains an invalid gate word`);
|
|
32
|
-
return value;
|
|
33
|
-
});
|
|
34
|
-
if (new Set(values).size !== values.length)
|
|
35
|
-
throw new SettingsError(`gate set '${name}' contains duplicate gates`);
|
|
36
|
-
return Object.freeze(values);
|
|
70
|
+
return Object.freeze(expanded);
|
|
37
71
|
}
|
|
38
72
|
function command(value, coordinate, ErrorType) {
|
|
39
73
|
if (!record(value))
|
|
@@ -76,6 +110,25 @@ export function requireBranchesToBeUpToDateFrom(input) {
|
|
|
76
110
|
}
|
|
77
111
|
return selected.value;
|
|
78
112
|
}
|
|
113
|
+
export function worktreeHooksFrom(input) {
|
|
114
|
+
if (!record(input))
|
|
115
|
+
throw new TypeError("worktreeHooksFrom input must be an object");
|
|
116
|
+
const view = input.settings.namespace("worktree");
|
|
117
|
+
if (view.kind === "failed")
|
|
118
|
+
namespaceFailure(view);
|
|
119
|
+
for (const entry of view.entries) {
|
|
120
|
+
if (entry.name !== "create" && entry.name !== "destroy") {
|
|
121
|
+
throw new SettingsError(`worktree has unknown entry: ${entry.name}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const selected = (phase) => {
|
|
125
|
+
const entry = view.entries.find((item) => item.name === phase);
|
|
126
|
+
if (entry === undefined)
|
|
127
|
+
return Object.freeze([]);
|
|
128
|
+
return commands(entry.value, `worktree.${phase}`, SettingsError);
|
|
129
|
+
};
|
|
130
|
+
return Object.freeze({ create: selected("create"), destroy: selected("destroy") });
|
|
131
|
+
}
|
|
79
132
|
export function normalizedWorktreeHooks(value) {
|
|
80
133
|
if (!record(value))
|
|
81
134
|
throw new TypeError("hooks must be an object");
|
|
@@ -3,20 +3,42 @@ import { type RegionObservation, type RegionOverlap } from "./region.js";
|
|
|
3
3
|
import { type Gate, type WorktreeHooks } from "./configuration.js";
|
|
4
4
|
import { type ChangeId, type ContractId, type ContractState, type JournalEntry, type SnapshotId } from "../core/facts/types.js";
|
|
5
5
|
export { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
6
|
-
import { type
|
|
6
|
+
import { type PlacementStop, type RepositoryScope, type VerificationStop, type DeliveryPreparationRefusal } from "../protocol/operations.js";
|
|
7
|
+
import type { ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractObservation, ContractPhase, ContractRow } from "../protocol/read/status.js";
|
|
8
|
+
import type { AuditReport } from "../protocol/audit.js";
|
|
9
|
+
import { type DeliverValue, type VerificationReuse } from "../protocol/deliver.js";
|
|
10
|
+
import type { ReconcileReport as ProtocolReconcileReport } from "../protocol/reconcile.js";
|
|
11
|
+
import { type ReviewValue } from "../protocol/review.js";
|
|
12
|
+
import type { FactKind } from "../core/facts/types.js";
|
|
13
|
+
import { type Dispatch } from "../dispatch/index.js";
|
|
7
14
|
import { type SettlementReport } from "../settlement/settle.js";
|
|
8
15
|
import { type TaskId } from "../task/identity.js";
|
|
9
16
|
import { Repo, type ReconcileInput } from "./repo.js";
|
|
10
17
|
import { type AuditInput } from "./audit.js";
|
|
11
18
|
import { Delivery } from "./delivery.js";
|
|
12
19
|
import { type MutationResult } from "./mutation.js";
|
|
13
|
-
|
|
20
|
+
import { KeiyakuRetry, type KeiyakuRefusal, type KeiyakuRetryReason } from "./refusal.js";
|
|
21
|
+
export { KeiyakuRefused, type ContractAppointmentRefusal, } from "./refusal.js";
|
|
22
|
+
export { KeiyakuRetry };
|
|
23
|
+
export type { KeiyakuRefusal, KeiyakuRetryReason };
|
|
14
24
|
export { gatesFrom, requireBranchesToBeUpToDateFrom, SettingsError } from "./configuration.js";
|
|
15
25
|
export type { Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, WorktreeHooks } from "./configuration.js";
|
|
16
26
|
export type { AuditReport, DeliveryPreparationRefusal, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractObservation, ContractPhase, ContractRow, FactKind, SnapshotId, };
|
|
17
27
|
export type { TaskId };
|
|
18
28
|
export type { RegionOverlap };
|
|
19
29
|
export type Fact = JournalEntry;
|
|
30
|
+
export type ContractHistoryEvent = Readonly<{
|
|
31
|
+
source: "journal";
|
|
32
|
+
fact: Fact;
|
|
33
|
+
}> | Readonly<{
|
|
34
|
+
source: "dispatch";
|
|
35
|
+
dispatch: Dispatch;
|
|
36
|
+
}>;
|
|
37
|
+
export type ContractHistory = Readonly<{
|
|
38
|
+
id: ContractId;
|
|
39
|
+
state: SnapshotId;
|
|
40
|
+
events: readonly ContractHistoryEvent[];
|
|
41
|
+
}>;
|
|
20
42
|
export type ActorId = string;
|
|
21
43
|
export type AttestationVerdict = "satisfied" | "unsatisfied";
|
|
22
44
|
export type Review = ReviewValue;
|
|
@@ -49,7 +71,7 @@ export type BindInput = Readonly<{
|
|
|
49
71
|
hooks?: WorktreeHooks;
|
|
50
72
|
}>;
|
|
51
73
|
export type AmendInput = Readonly<{
|
|
52
|
-
markdown
|
|
74
|
+
markdown?: string;
|
|
53
75
|
actor?: ActorId;
|
|
54
76
|
after?: readonly ContractId[];
|
|
55
77
|
gates?: readonly Gate[];
|
|
@@ -90,12 +112,57 @@ export type DeliverInput = ActorOptions & Readonly<{
|
|
|
90
112
|
includeDirty?: boolean;
|
|
91
113
|
signal?: AbortSignal;
|
|
92
114
|
}>;
|
|
115
|
+
type ForwardedDeliveryReceipt = Readonly<{
|
|
116
|
+
kind: "accepted";
|
|
117
|
+
result: MutationResult<DeliverValue>;
|
|
118
|
+
}> | Readonly<{
|
|
119
|
+
kind: "refused";
|
|
120
|
+
refusal: KeiyakuRefusal;
|
|
121
|
+
}> | Readonly<{
|
|
122
|
+
kind: "retry";
|
|
123
|
+
reason: KeiyakuRetryReason;
|
|
124
|
+
}>;
|
|
125
|
+
type ForwardedReviewReceipt = Readonly<{
|
|
126
|
+
kind: "accepted";
|
|
127
|
+
result: MutationResult<ReviewValue>;
|
|
128
|
+
}> | Readonly<{
|
|
129
|
+
kind: "refused";
|
|
130
|
+
refusal: KeiyakuRefusal;
|
|
131
|
+
}> | Readonly<{
|
|
132
|
+
kind: "retry";
|
|
133
|
+
reason: KeiyakuRetryReason;
|
|
134
|
+
}>;
|
|
93
135
|
export type { AuditInput };
|
|
136
|
+
export declare function executeForwardedDeliver(input: Readonly<{
|
|
137
|
+
repo: Repo;
|
|
138
|
+
contractId: string;
|
|
139
|
+
requester: string;
|
|
140
|
+
message?: string;
|
|
141
|
+
includeDirty: boolean;
|
|
142
|
+
requireBranchesToBeUpToDate: boolean;
|
|
143
|
+
hooks: WorktreeHooks;
|
|
144
|
+
signal?: AbortSignal;
|
|
145
|
+
}>): Promise<Readonly<{
|
|
146
|
+
result: ForwardedDeliveryReceipt;
|
|
147
|
+
deliveryFactId?: string;
|
|
148
|
+
}>>;
|
|
149
|
+
export declare function executeForwardedReview(input: Readonly<{
|
|
150
|
+
repo: Repo;
|
|
151
|
+
contractId: string;
|
|
152
|
+
requester: string;
|
|
153
|
+
verdict: AttestationVerdict;
|
|
154
|
+
summary?: string;
|
|
155
|
+
hooks: WorktreeHooks;
|
|
156
|
+
}>): Promise<Readonly<{
|
|
157
|
+
result: ForwardedReviewReceipt;
|
|
158
|
+
reviewFactId?: string;
|
|
159
|
+
}>>;
|
|
94
160
|
export declare class KeiyakuHandle {
|
|
95
161
|
private readonly id;
|
|
96
162
|
private readonly scope;
|
|
97
163
|
constructor(id: ContractId, scope: RepositoryScope);
|
|
98
164
|
state(): Promise<ContractState>;
|
|
165
|
+
history(): Promise<ContractHistory>;
|
|
99
166
|
guidance(): Promise<string>;
|
|
100
167
|
delivery(): Promise<Delivery | null>;
|
|
101
168
|
amend(input: AmendInput): Promise<AmendResult>;
|