@astrosheep/keiyaku 4.0.4 → 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 +3 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +14 -0
- package/build/src/akuma/akuma.d.ts +0 -1
- package/build/src/akuma/akuma.js +1 -6
- package/build/src/akuma/allowed.d.ts +1 -1
- package/build/src/akuma/allowed.js +3 -10
- package/build/src/akuma/body.d.ts +5 -2
- package/build/src/akuma/body.js +29 -23
- package/build/src/akuma/heart/facts.d.ts +35 -9
- package/build/src/akuma/heart/index.d.ts +4 -13
- package/build/src/akuma/heart/index.js +2 -133
- 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 -28
- package/build/src/akuma/heart/rows.js +0 -137
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +9 -2
- package/build/src/akuma/heart/soul.js +0 -36
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/provider-recipe.js +1 -11
- package/build/src/akuma/provider.d.ts +1 -6
- package/build/src/akuma/providers/acp/core.js +6 -2
- package/build/src/akuma/providers/acp/index.js +0 -1
- 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/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.js +0 -1
- 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/index.js +11 -4
- 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 +28 -94
- package/build/src/akuma/requests.js +52 -562
- package/build/src/akuma-body.d.ts +7 -0
- package/build/src/akuma-body.js +54 -1
- 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.js +17 -9
- package/build/src/cli/commands/akuma.js +2 -2
- package/build/src/cli/commands/contract.d.ts +6 -6
- package/build/src/cli/commands/contract.js +3 -3
- package/build/src/cli/commands/task-invoke.js +98 -9
- package/build/src/cli/coordinates.d.ts +1 -0
- package/build/src/cli/coordinates.js +7 -4
- package/build/src/cli/invoke.js +28 -4
- package/build/src/cli/parse.d.ts +2 -2
- package/build/src/cli/parse.js +21 -8
- package/build/src/cli/render/akuma.js +56 -13
- package/build/src/cli/render/audit.js +2 -6
- package/build/src/cli/render/contract.js +40 -0
- package/build/src/cli/render/receipt.js +28 -1
- package/build/src/cli/render/terminal.d.ts +0 -2
- package/build/src/cli/render/terminal.js +0 -29
- package/build/src/cli/result.d.ts +15 -7
- package/build/src/contract-worktree.d.ts +1 -2
- package/build/src/contract-worktree.js +4 -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/git/admission.d.ts +2 -1
- package/build/src/git/integration.d.ts +5 -2
- package/build/src/git/integration.js +54 -1
- 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 +2 -1
- package/build/src/git/reconcile.js +9 -6
- 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 +1 -1
- package/build/src/git/tender.js +2 -1
- package/build/src/git/terminal-seal.d.ts +2 -2
- package/build/src/git/terminal-seal.js +3 -6
- package/build/src/git/workspace.d.ts +1 -1
- package/build/src/git/workspace.js +1 -1
- package/build/src/index.d.ts +1 -2
- package/build/src/index.js +1 -1
- package/build/src/library/address.js +7 -1
- 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 +1 -1
- package/build/src/library/configuration.d.ts +1 -1
- package/build/src/library/configuration.js +52 -18
- package/build/src/library/contract.d.ts +55 -2
- package/build/src/library/contract.js +162 -23
- package/build/src/library/delivery.d.ts +1 -1
- package/build/src/library/fleet.d.ts +27 -7
- package/build/src/library/fleet.js +79 -39
- package/build/src/library/input.d.ts +0 -1
- package/build/src/library/input.js +0 -5
- package/build/src/library/keiyaku.d.ts +1 -1
- 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 +1 -1
- 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 +64 -200
- package/build/src/protocol/operations.js +21 -640
- 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 +1 -1
- package/build/src/protocol/read/status.js +3 -1
- 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/settlement/fence.d.ts +1 -1
- package/build/src/settlement/holder.d.ts +1 -1
- package/build/src/settlement/settle.d.ts +1 -1
- package/build/src/task/board.d.ts +0 -1
- package/build/src/task/board.js +0 -3
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +11 -4
- package/build/src/task/index.d.ts +1 -1
- package/build/src/task/index.js +2 -127
- 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 +2 -0
- package/build/src/task/operations.js +35 -11
- package/build/src/task/store.js +0 -2
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/workspace-place.d.ts +1 -4
- package/build/src/workspace-place.js +0 -15
- package/package.json +3 -3
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
1
|
import { isAbsolute, resolve } from "node:path";
|
|
3
2
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
4
|
-
import { consumeProcessStdout } from "../runtime/proc/run.js";
|
|
5
3
|
import { gitObjectId } from "./identity.js";
|
|
4
|
+
import { GitPlumbingError, runGit, runGitWithEnvironment } from "./process.js";
|
|
6
5
|
import { parseTreeObject, prepareTreeUpdate, treeUpdate, validPath, } from "./tree.js";
|
|
7
6
|
export const GIT_REF = "refs/heads/keiyaku-state";
|
|
8
7
|
export const DELIVERY_REF_NAMESPACE = "refs/heads/keiyaku-delivery";
|
|
@@ -25,21 +24,6 @@ export class NoGitWorldError extends Error {
|
|
|
25
24
|
this.path = path;
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
|
-
export class GitPlumbingError extends Error {
|
|
29
|
-
stdout;
|
|
30
|
-
stderr;
|
|
31
|
-
status;
|
|
32
|
-
pid;
|
|
33
|
-
constructor(input) {
|
|
34
|
-
super(input.message);
|
|
35
|
-
this.name = "GitPlumbingError";
|
|
36
|
-
this.stdout = Buffer.from(input.stdout ?? "");
|
|
37
|
-
this.stderr = Buffer.from(input.stderr);
|
|
38
|
-
this.status = input.status;
|
|
39
|
-
this.pid = input.pid ?? null;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
const GIT_STDERR_BYTES = 16 * 1024;
|
|
43
27
|
function worktreesFromPorcelain(output) {
|
|
44
28
|
const fields = output.toString("utf8").split("\0");
|
|
45
29
|
const worktrees = [];
|
|
@@ -79,12 +63,13 @@ export async function registeredWorktrees(repository) {
|
|
|
79
63
|
export async function registeredWorktreePaths(repository) {
|
|
80
64
|
return (await registeredWorktrees(repository)).map((worktree) => worktree.path);
|
|
81
65
|
}
|
|
82
|
-
export async function repositoryAt(cwd) {
|
|
66
|
+
export async function repositoryAt(cwd, gitPath = "git") {
|
|
83
67
|
if (typeof cwd !== "string" || cwd.length === 0) {
|
|
84
68
|
throw new Error("repository path must be a nonempty string");
|
|
85
69
|
}
|
|
86
70
|
const effectiveCwd = resolve(cwd);
|
|
87
71
|
const provisional = {
|
|
72
|
+
gitPath,
|
|
88
73
|
effectiveCwd,
|
|
89
74
|
primaryWorktree: effectiveCwd,
|
|
90
75
|
commonDirectory: effectiveCwd,
|
|
@@ -101,7 +86,7 @@ export async function repositoryAt(cwd) {
|
|
|
101
86
|
}
|
|
102
87
|
throw error;
|
|
103
88
|
}
|
|
104
|
-
return { effectiveCwd, primaryWorktree, commonDirectory };
|
|
89
|
+
return { gitPath, effectiveCwd, primaryWorktree, commonDirectory };
|
|
105
90
|
}
|
|
106
91
|
async function absoluteGitPath(repository, args, label) {
|
|
107
92
|
const value = (await runGit(repository, ["rev-parse", "--path-format=absolute", ...args])).toString("utf8").trim();
|
|
@@ -119,83 +104,6 @@ export async function worktreeGitDirectory(repository, worktree) {
|
|
|
119
104
|
export async function worktreeRoot(repository) {
|
|
120
105
|
return await absoluteGitPath(repository, ["--show-toplevel"], "worktree root");
|
|
121
106
|
}
|
|
122
|
-
function commandError(command, error) {
|
|
123
|
-
const candidate = error;
|
|
124
|
-
const stderr = candidate.stderr === undefined ? Buffer.alloc(0) : Buffer.from(candidate.stderr);
|
|
125
|
-
const stdout = candidate.stdout === undefined ? Buffer.alloc(0) : Buffer.from(candidate.stdout);
|
|
126
|
-
const detail = stderr.length === 0 ? candidate.message ?? "git command failed" : stderr.toString("utf8");
|
|
127
|
-
return new GitPlumbingError({
|
|
128
|
-
stdout,
|
|
129
|
-
stderr,
|
|
130
|
-
status: candidate.status ?? null,
|
|
131
|
-
message: `${command.join(" ")}: ${detail}`,
|
|
132
|
-
pid: candidate.pid ?? null,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
async function executeGit(repository, args, input, environment) {
|
|
136
|
-
const stdout = [];
|
|
137
|
-
const stderr = [];
|
|
138
|
-
let stderrBytes = 0;
|
|
139
|
-
let inputError;
|
|
140
|
-
const child = spawn("git", [...args], {
|
|
141
|
-
cwd: repository.effectiveCwd,
|
|
142
|
-
...(environment === undefined ? {} : { env: { ...process.env, ...environment } }),
|
|
143
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
144
|
-
windowsHide: true,
|
|
145
|
-
});
|
|
146
|
-
child.stdout.on("data", (chunk) => stdout.push(chunk));
|
|
147
|
-
child.stderr.on("data", (chunk) => {
|
|
148
|
-
if (stderrBytes >= GIT_STDERR_BYTES)
|
|
149
|
-
return;
|
|
150
|
-
const retained = chunk.subarray(0, GIT_STDERR_BYTES - stderrBytes);
|
|
151
|
-
stderr.push(retained);
|
|
152
|
-
stderrBytes += retained.length;
|
|
153
|
-
});
|
|
154
|
-
child.stdin.on("error", (error) => { inputError = error; });
|
|
155
|
-
child.stdin.end(input);
|
|
156
|
-
const terminal = await new Promise((resolveTerminal) => {
|
|
157
|
-
child.once("error", (error) => resolveTerminal({ code: null, error }));
|
|
158
|
-
child.once("close", (code) => resolveTerminal({ code }));
|
|
159
|
-
});
|
|
160
|
-
const output = Buffer.concat(stdout);
|
|
161
|
-
if (terminal.code === 0 && inputError === undefined)
|
|
162
|
-
return output;
|
|
163
|
-
throw commandError(args, {
|
|
164
|
-
message: terminal.error?.message ?? inputError?.message ?? `git exited with status ${terminal.code ?? "unknown"}`,
|
|
165
|
-
stdout: output,
|
|
166
|
-
stderr: Buffer.concat(stderr),
|
|
167
|
-
status: terminal.code,
|
|
168
|
-
pid: child.pid,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
export async function runGit(repository, args, input) {
|
|
172
|
-
return await executeGit(repository, args, input);
|
|
173
|
-
}
|
|
174
|
-
export async function consumeGitStdout(repository, args, consume) {
|
|
175
|
-
const result = await consumeProcessStdout({
|
|
176
|
-
argv: ["git", ...args],
|
|
177
|
-
cwd: repository.effectiveCwd,
|
|
178
|
-
}, consume);
|
|
179
|
-
const { outcome } = result;
|
|
180
|
-
if (outcome.kind === "terminal" && outcome.code === 0)
|
|
181
|
-
return;
|
|
182
|
-
const status = outcome.kind === "terminal" ? outcome.code : null;
|
|
183
|
-
const stderr = outcome.kind === "terminal" ? outcome.stderr : "";
|
|
184
|
-
const message = outcome.kind === "terminal"
|
|
185
|
-
? `git exited with status ${outcome.code}`
|
|
186
|
-
: outcome.kind === "spawn-error" || outcome.kind === "stream-error"
|
|
187
|
-
? outcome.diagnostic
|
|
188
|
-
: `git process ended with ${outcome.kind}`;
|
|
189
|
-
throw commandError(args, {
|
|
190
|
-
message,
|
|
191
|
-
stderr,
|
|
192
|
-
status,
|
|
193
|
-
pid: result.pid ?? undefined,
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
export async function runGitWithEnvironment(repository, args, input, environment) {
|
|
197
|
-
return await executeGit(repository, args, input, environment);
|
|
198
|
-
}
|
|
199
107
|
function assertOid(oid, label) {
|
|
200
108
|
gitObjectId(oid, label);
|
|
201
109
|
}
|
|
@@ -282,28 +190,6 @@ export async function readGitPaths(repository, requestedPaths) {
|
|
|
282
190
|
await validateGitFormat(repository, paths);
|
|
283
191
|
return { commit, tree, paths };
|
|
284
192
|
}
|
|
285
|
-
/** Add paths from the same immutable Git tree without rereading its ref. */
|
|
286
|
-
export async function extendGitPaths(repository, snapshot, requestedPaths) {
|
|
287
|
-
for (const path of requestedPaths)
|
|
288
|
-
validPath(path);
|
|
289
|
-
if (snapshot.tree === null || requestedPaths.length === 0)
|
|
290
|
-
return snapshot;
|
|
291
|
-
const additions = parseTreeEntries(await runGit(repository, [
|
|
292
|
-
"ls-tree",
|
|
293
|
-
"-z",
|
|
294
|
-
"--full-tree",
|
|
295
|
-
snapshot.tree,
|
|
296
|
-
"--",
|
|
297
|
-
...requestedPaths,
|
|
298
|
-
]));
|
|
299
|
-
return { ...snapshot, paths: new Map([...snapshot.paths, ...additions]) };
|
|
300
|
-
}
|
|
301
|
-
/** Expand a targeted immutable snapshot to its complete already-pinned tree. */
|
|
302
|
-
export async function expandGitSnapshot(repository, snapshot) {
|
|
303
|
-
if (snapshot.tree === null)
|
|
304
|
-
return snapshot;
|
|
305
|
-
return { ...snapshot, paths: await readTreeEntries(repository, snapshot.tree) };
|
|
306
|
-
}
|
|
307
193
|
export async function writeBlob(repository, bytes) {
|
|
308
194
|
const oid = (await runGit(repository, ["hash-object", "-w", "--stdin"], bytes)).toString("utf8").trim();
|
|
309
195
|
assertOid(oid, "written blob");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SnapshotId } from "../core/facts/types.js";
|
|
2
|
-
import { type GitRepository } from "./
|
|
2
|
+
import { type GitRepository } from "./process.js";
|
|
3
3
|
export type MaterializedScratchCandidate = Readonly<{
|
|
4
4
|
cwd: string;
|
|
5
5
|
dispose: () => Promise<WorktreeLeak | null>;
|
package/build/src/git/scratch.js
CHANGED
|
@@ -4,7 +4,7 @@ import { tmpdir } from "node:os";
|
|
|
4
4
|
import { basename, dirname, join } from "node:path";
|
|
5
5
|
import { tryAcquireSqliteTransactionLock, } from "../coordination/sqlite-transaction-lock.js";
|
|
6
6
|
import { gitObjectIdForSnapshot } from "./identity.js";
|
|
7
|
-
import { runGit } from "./
|
|
7
|
+
import { runGit } from "./process.js";
|
|
8
8
|
const SCRATCH_PREFIX = "keiyaku-v4-verify-";
|
|
9
9
|
const SCRATCH_ROOT = await realpath(tmpdir());
|
|
10
10
|
const SCRATCH_PATTERN = /^keiyaku-v4-verify-([0-9a-f]{24})$/;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type HeldSqliteTransactionLock } from "../coordination/sqlite-transaction-lock.js";
|
|
2
2
|
import type { ContractId, ContractState, SnapshotId } from "../core/facts/types.js";
|
|
3
3
|
import type { RefOperation } from "../core/facts/offer.js";
|
|
4
|
-
import { type GitRepository } from "./
|
|
4
|
+
import { type GitRepository } from "./process.js";
|
|
5
5
|
export type WorkspaceNotOnTargetRefusal = Readonly<{
|
|
6
6
|
kind: "workspace-not-on-target";
|
|
7
7
|
contractId: ContractId;
|
|
@@ -3,7 +3,8 @@ import { resolve } from "node:path";
|
|
|
3
3
|
import { acquireSqliteTransactionLock } from "../coordination/sqlite-transaction-lock.js";
|
|
4
4
|
import { gitObjectId, gitObjectIdForSnapshot, gitRefLocator, mintSnapshotId } from "./identity.js";
|
|
5
5
|
import { currentBranch } from "./observe.js";
|
|
6
|
-
import { commonGitDirectory,
|
|
6
|
+
import { commonGitDirectory, readRef, registeredWorktrees, } from "./repository.js";
|
|
7
|
+
import { consumeGitStdout, GitPlumbingError, runGit, } from "./process.js";
|
|
7
8
|
import { captureWorkspaceTree } from "./workspace.js";
|
|
8
9
|
export async function observeTargetHead(repository, target) {
|
|
9
10
|
const value = await readRef(repository, target);
|
|
@@ -254,7 +255,7 @@ export async function adjudicateAuditTarget(repository, input) {
|
|
|
254
255
|
}
|
|
255
256
|
}
|
|
256
257
|
export async function prepareTargetPlacement(repository, state, target) {
|
|
257
|
-
if (state.coordinates.target !== target.target || state.
|
|
258
|
+
if (state.coordinates.target !== target.target || state.currentIntegration?.snapshot !== target.newOid) {
|
|
258
259
|
throw new Error("placement state does not match its offered target movement");
|
|
259
260
|
}
|
|
260
261
|
const observation = await observeTargetPlacement(repository, {
|
|
@@ -340,10 +341,11 @@ export async function recoverTargetPlacement(repository, state) {
|
|
|
340
341
|
const delivery = state.delivery;
|
|
341
342
|
if (state.terminal?.kind !== "claimed" || target === undefined || delivery === null)
|
|
342
343
|
return { effects: [], lag: [] };
|
|
343
|
-
|
|
344
|
+
const integration = state.currentIntegration;
|
|
345
|
+
if (integration === null || await readRef(repository, target) !== integration.snapshot)
|
|
344
346
|
return { effects: [], lag: [] };
|
|
345
|
-
const candidateTree = await commitTree(repository,
|
|
346
|
-
const predecessorTree = await commitTree(repository,
|
|
347
|
+
const candidateTree = await commitTree(repository, integration.snapshot);
|
|
348
|
+
const predecessorTree = await commitTree(repository, integration.predecessor);
|
|
347
349
|
const worktrees = (await registeredWorktrees(repository))
|
|
348
350
|
.filter((worktree) => worktree.branch === target)
|
|
349
351
|
.sort((left, right) => left.path.localeCompare(right.path));
|
|
@@ -354,8 +356,8 @@ export async function recoverTargetPlacement(repository, state) {
|
|
|
354
356
|
const recovery = await recoverCheckout({
|
|
355
357
|
repository,
|
|
356
358
|
path: worktree.path,
|
|
357
|
-
predecessor:
|
|
358
|
-
candidate:
|
|
359
|
+
predecessor: integration.predecessor,
|
|
360
|
+
candidate: integration.snapshot,
|
|
359
361
|
predecessorTree,
|
|
360
362
|
candidateTree,
|
|
361
363
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Preparation } from "../core/decide.js";
|
|
2
2
|
import type { ActorId, ContractCoordinates, ContractId, SnapshotId } from "../core/facts/types.js";
|
|
3
3
|
import { type GitObjectId } from "./identity.js";
|
|
4
|
-
import { type GitRepository } from "./
|
|
4
|
+
import { type GitRepository } from "./process.js";
|
|
5
5
|
import { captureWorkspaceTree } from "./workspace.js";
|
|
6
6
|
export type TenderCaptureCoordinates = Readonly<{
|
|
7
7
|
contractId: ContractId;
|
package/build/src/git/tender.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { access } from "node:fs/promises";
|
|
2
2
|
import { gitObjectIdForSnapshot, mintSnapshotId } from "./identity.js";
|
|
3
|
-
import { decodeGitNumstat,
|
|
3
|
+
import { decodeGitNumstat, registeredWorktreePaths, } from "./repository.js";
|
|
4
|
+
import { GitPlumbingError, runGit, runGitWithEnvironment, } from "./process.js";
|
|
4
5
|
import { captureWorkspaceTree, worktreePath } from "./workspace.js";
|
|
5
6
|
async function workspaceExists(repository, workspace, path) {
|
|
6
7
|
const exists = await access(path).then(() => true, () => false);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ContractState, SnapshotId } from "../core/facts/types.js";
|
|
2
2
|
import { type GitObjectId } from "./identity.js";
|
|
3
|
-
import {
|
|
3
|
+
import type { GitOid } from "./repository.js";
|
|
4
|
+
import { type GitRepository } from "./process.js";
|
|
4
5
|
import { captureWorkspaceTree } from "./workspace.js";
|
|
5
6
|
export type UnsealedBytes = Readonly<{
|
|
6
7
|
kind: "unsealed-bytes";
|
|
@@ -33,6 +34,5 @@ export type TerminalWorkspaceObservation = Readonly<{
|
|
|
33
34
|
export declare function terminalSealSnapshots(state: ContractState): readonly SnapshotId[];
|
|
34
35
|
export declare function terminalSealExpectations(state: ContractState, objects: ReadonlyMap<GitOid, TerminalSealObject>): TerminalSealExpectations;
|
|
35
36
|
export declare function unsealedWorkspaceBytes(repository: GitRepository, path: string, expected: TerminalSealExpectations, workspace: WorkspaceTree): Promise<UnsealedBytes | null>;
|
|
36
|
-
export declare function unsealedBytes(repository: GitRepository, path: string, expected: TerminalSealExpectations): Promise<UnsealedBytes | null>;
|
|
37
37
|
export declare function observeTerminalWorkspace(repository: GitRepository, path: string, expected: TerminalSealExpectations): Promise<TerminalWorkspaceObservation>;
|
|
38
38
|
export {};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { gitObjectId, gitObjectIdForSnapshot, mintSnapshotId } from "./identity.js";
|
|
2
|
-
import { runGit } from "./
|
|
2
|
+
import { runGit } from "./process.js";
|
|
3
3
|
import { captureWorkspaceTree } from "./workspace.js";
|
|
4
4
|
export function terminalSealSnapshots(state) {
|
|
5
5
|
return [...new Set([
|
|
6
6
|
state.coordinates.start,
|
|
7
7
|
...(state.delivery === null ? [] : [
|
|
8
8
|
state.delivery.data.tenderSnapshot,
|
|
9
|
-
state.
|
|
9
|
+
...(state.currentIntegration === null ? [] : [state.currentIntegration.snapshot]),
|
|
10
10
|
]),
|
|
11
11
|
])];
|
|
12
12
|
}
|
|
@@ -51,7 +51,7 @@ export function terminalSealExpectations(state, objects) {
|
|
|
51
51
|
state.coordinates.start,
|
|
52
52
|
...(tenderParent === undefined ? [] : [tenderParent]),
|
|
53
53
|
tender,
|
|
54
|
-
state.delivery.data.integration.snapshot,
|
|
54
|
+
state.currentIntegration?.snapshot ?? state.delivery.data.integration.snapshot,
|
|
55
55
|
])],
|
|
56
56
|
trees: [...treeBySnapshot.values()],
|
|
57
57
|
treeBySnapshot,
|
|
@@ -86,9 +86,6 @@ export async function unsealedWorkspaceBytes(repository, path, expected, workspa
|
|
|
86
86
|
...(headIsSealed ? {} : { head: workspace.head }),
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
|
-
export async function unsealedBytes(repository, path, expected) {
|
|
90
|
-
return (await observeTerminalWorkspace(repository, path, expected)).unsealed;
|
|
91
|
-
}
|
|
92
89
|
export async function observeTerminalWorkspace(repository, path, expected) {
|
|
93
90
|
const captured = await captureWorkspaceTree(repository, path);
|
|
94
91
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SnapshotId } from "../core/facts/types.js";
|
|
2
2
|
import { type GitObjectId } from "./identity.js";
|
|
3
|
-
import { type GitRepository } from "./
|
|
3
|
+
import { type GitRepository } from "./process.js";
|
|
4
4
|
export type WorkspaceChanges = Readonly<{
|
|
5
5
|
staged: readonly string[];
|
|
6
6
|
unstaged: readonly string[];
|
|
@@ -2,7 +2,7 @@ import { mkdtemp, rm } from "node:fs/promises";
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { gitObjectId, mintSnapshotId } from "./identity.js";
|
|
5
|
-
import { runGit, runGitWithEnvironment } from "./
|
|
5
|
+
import { runGit, runGitWithEnvironment } from "./process.js";
|
|
6
6
|
const WORKTREE_DIRECTORY = ["keiyaku", "wt"];
|
|
7
7
|
export function worktreePath(repository, place) {
|
|
8
8
|
return resolve(repository.commonDirectory, ...WORKTREE_DIRECTORY, place);
|
package/build/src/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "./library/keiyaku.js";
|
|
2
2
|
export { settings } from "./settings.js";
|
|
3
3
|
export { World, WorldError } from "./world.js";
|
|
4
4
|
export type { WorldResolution, WorldResolutionInput, WorldRoot } from "./world.js";
|
|
5
5
|
export type { Settings, SettingsEntry, SettingsInput, SettingsNamespaceFailure, SettingsNamespaceView, SettingsScope, SettingsScopeState, } from "./settings.js";
|
|
6
|
-
export type { AttestationVerdict, AbandonInput, ActorId, AkuId, AllowedAction, AllowedActions, AkumaAddressInput, AkumaAlias, AkumaGlob, AkumaHistoryInput, AkumaHistoryResult, AkumaInterruptInput, AkumaInterruptResult, AkumaKillResult, AkumaObservation, AkumaSetAddressInput, AkumaStatus, AkumaTellInput, CreatedTaskObservation, AkumaTellResult, AkumaWaitInput, AkumaWaitResult, AkumaWorldScopeRefusal, AliasBinding, AliasStage, AmendResult, AmendInput, ArcInput, AuditReport, DeliveryPreparationRefusal, BindInput, BindResult, CallInput, CallObservation, CallResult, Catalog, CatalogInput, CatalogQuery, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractHistory, ContractHistoryEvent, ContractListInput, ContractObservation, ContractObservationInput, ContractPhase, ContractRow, DeliverInput, Fact, FactKind, Dispatch, DispatchFailure, DispatchStage, DirectAkumaSelector, Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, KeiyakuOfInput, KeiyakuRefusal, KeiyakuRetryReason, ForkInput, ForkResult, IntegrationFailure, Lag, MutationResult, PlacementStop, RegionOverlap, ReconcileInput, RepoReconcileReport, Review, ReconcileReport, ReviewInput, RepoAtInput, AuditInput, SnapshotId, SettlementAction, SettlementLag, SettlementReport, SetAkumaSelector, TaskId, TopologyEffect, VerificationReuse, VerificationStop, WorktreeHooks, } from "./library/keiyaku.js";
|
package/build/src/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "./library/keiyaku.js";
|
|
2
2
|
export { settings } from "./settings.js";
|
|
3
3
|
export { World, WorldError } from "./world.js";
|
|
@@ -116,7 +116,13 @@ function addSelectorIds(selector, sources, selected, contractMembers) {
|
|
|
116
116
|
selected.add(selector.value);
|
|
117
117
|
}
|
|
118
118
|
async function contractMemberInWorld(path, id) {
|
|
119
|
-
|
|
119
|
+
try {
|
|
120
|
+
return await probeBornAkuma(path, id);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// A dispatched physical member remains selected when its Heart cannot be read.
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
120
126
|
}
|
|
121
127
|
async function refuseForeignContractMembers(path, ids, contractMembers) {
|
|
122
128
|
const foreign = [];
|
|
@@ -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 });
|
|
@@ -4,7 +4,7 @@ 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;
|
|
@@ -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))
|
|
@@ -3,7 +3,13 @@ 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";
|
|
7
13
|
import { type Dispatch } from "../dispatch/index.js";
|
|
8
14
|
import { type SettlementReport } from "../settlement/settle.js";
|
|
9
15
|
import { type TaskId } from "../task/identity.js";
|
|
@@ -11,7 +17,10 @@ import { Repo, type ReconcileInput } from "./repo.js";
|
|
|
11
17
|
import { type AuditInput } from "./audit.js";
|
|
12
18
|
import { Delivery } from "./delivery.js";
|
|
13
19
|
import { type MutationResult } from "./mutation.js";
|
|
14
|
-
|
|
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 };
|
|
15
24
|
export { gatesFrom, requireBranchesToBeUpToDateFrom, SettingsError } from "./configuration.js";
|
|
16
25
|
export type { Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, WorktreeHooks } from "./configuration.js";
|
|
17
26
|
export type { AuditReport, DeliveryPreparationRefusal, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractObservation, ContractPhase, ContractRow, FactKind, SnapshotId, };
|
|
@@ -103,7 +112,51 @@ export type DeliverInput = ActorOptions & Readonly<{
|
|
|
103
112
|
includeDirty?: boolean;
|
|
104
113
|
signal?: AbortSignal;
|
|
105
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
|
+
}>;
|
|
106
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
|
+
}>>;
|
|
107
160
|
export declare class KeiyakuHandle {
|
|
108
161
|
private readonly id;
|
|
109
162
|
private readonly scope;
|