@astrosheep/keiyaku 4.6.11 → 4.6.13
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/plugins/claude/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/plugins/codex/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +3 -1
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/skills/keiyaku/SKILL.md +3 -1
- package/build/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/skills/keiyaku-bind/SKILL.md +3 -2
- package/build/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/src/akuma/akuma-errors.d.ts +5 -0
- package/build/src/akuma/akuma-errors.js +9 -0
- package/build/src/akuma/akuma-owner.d.ts +14 -19
- package/build/src/akuma/akuma-owner.js +56 -54
- package/build/src/akuma/akuma-selection-execution.d.ts +5 -4
- package/build/src/akuma/akuma-selection-execution.js +59 -17
- package/build/src/akuma/akuma.d.ts +1 -2
- package/build/src/akuma/allowed.d.ts +2 -3
- package/build/src/akuma/allowed.js +1 -3
- package/build/src/akuma/body.js +17 -7
- package/build/src/akuma/call-initial-tell.d.ts +18 -0
- package/build/src/akuma/call-initial-tell.js +18 -0
- package/build/src/akuma/call-request.d.ts +20 -4
- package/build/src/akuma/heart/facts.d.ts +13 -0
- package/build/src/akuma/heart/facts.js +6 -0
- package/build/src/akuma/heart/index.d.ts +29 -14
- package/build/src/akuma/heart/index.js +75 -29
- package/build/src/akuma/heart/rows.d.ts +9 -2
- package/build/src/akuma/heart/rows.js +72 -11
- package/build/src/akuma/heart/storage.d.ts +2 -8
- package/build/src/akuma/heart/storage.js +13 -13
- package/build/src/akuma/heart/tells.d.ts +3 -1
- package/build/src/akuma/heart/tells.js +18 -2
- package/build/src/akuma/provider.d.ts +2 -4
- package/build/src/akuma/provider.js +29 -6
- package/build/src/akuma/providers/acp/core.js +23 -21
- package/build/src/akuma/providers/claude/index.js +0 -8
- package/build/src/akuma/providers/codex-app-server/index.js +9 -8
- package/build/src/akuma/providers/execution-environment.d.ts +1 -1
- package/build/src/akuma/providers/execution-environment.js +1 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +111 -81
- package/build/src/akuma/providers/opencode-sdk/index.js +179 -150
- package/build/src/akuma/providers/opencode-sdk/native-http.js +7 -3
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +5 -3
- package/build/src/akuma/providers/opencode-sdk/session.js +32 -27
- package/build/src/akuma/providers/paseo/index.js +0 -2
- package/build/src/akuma/providers/pi/index.js +23 -20
- package/build/src/akuma/selection-observation.d.ts +78 -9
- package/build/src/akuma/selection-owner-port.d.ts +2 -1
- package/build/src/akuma/selection-owner-port.js +6 -1
- package/build/src/akuma/selection-request.d.ts +1 -1
- package/build/src/akuma/selection-request.js +8 -3
- package/build/src/akuma/turn-drive.js +79 -48
- package/build/src/akuma-body.js +5 -3
- package/build/src/cli/commands/akuma-grammar.js +2 -2
- package/build/src/cli/commands/akuma.js +24 -16
- package/build/src/cli/commands/contract-grammar.d.ts +3 -7
- package/build/src/cli/commands/contract-grammar.js +12 -10
- package/build/src/cli/commands/contract-help.d.ts +3 -13
- package/build/src/cli/commands/contract-help.js +7 -16
- package/build/src/cli/commands/contract.js +19 -35
- package/build/src/cli/commands/debt.js +30 -29
- package/build/src/cli/parse.js +0 -1
- package/build/src/cli/render/akuma-activity.d.ts +36 -9
- package/build/src/cli/render/akuma-activity.js +142 -65
- package/build/src/cli/render/akuma.d.ts +6 -0
- package/build/src/cli/render/akuma.js +67 -24
- package/build/src/cli/render/catalog.js +0 -1
- package/build/src/cli/render/contract-observation.d.ts +16 -3
- package/build/src/cli/render/contract-observation.js +3 -0
- package/build/src/cli/render/contract.d.ts +2 -2
- package/build/src/cli/render/contract.js +4 -4
- package/build/src/cli/render/delivery-preview.d.ts +7 -0
- package/build/src/cli/render/{audit.js → delivery-preview.js} +29 -27
- package/build/src/cli/render/kanshi-akuma.d.ts +3 -1
- package/build/src/cli/render/kanshi-akuma.js +23 -8
- package/build/src/cli/render/kanshi.js +4 -1
- package/build/src/cli/render/receipt.js +3 -3
- package/build/src/cli/render/refusal.js +2 -2
- package/build/src/cli/render/terminal.d.ts +0 -1
- package/build/src/cli/render/terminal.js +1 -1
- package/build/src/cli/square-identity.d.ts +15 -0
- package/build/src/cli/square-identity.js +180 -0
- package/build/src/contract-worktree.js +1 -1
- package/build/src/core/verbs/placement.d.ts +2 -1
- package/build/src/core/verbs/placement.js +1 -1
- package/build/src/debt/context.d.ts +0 -5
- package/build/src/debt/context.js +32 -44
- package/build/src/git/process.d.ts +1 -0
- package/build/src/git/process.js +18 -1
- package/build/src/git/read-observation.js +2 -1
- package/build/src/git/scratch.d.ts +5 -1
- package/build/src/git/scratch.js +41 -12
- package/build/src/git/target-placement.d.ts +22 -4
- package/build/src/git/target-placement.js +44 -20
- package/build/src/index.d.ts +2 -2
- package/build/src/kanshi/read.js +187 -105
- package/build/src/kanshi/report.d.ts +5 -0
- package/build/src/library/address.d.ts +18 -4
- package/build/src/library/address.js +27 -6
- package/build/src/library/contract-address.d.ts +6 -0
- package/build/src/library/contract-address.js +12 -1
- package/build/src/library/contract-execution.d.ts +2 -2
- package/build/src/library/contract-execution.js +13 -17
- package/build/src/library/contract-operations.d.ts +59 -94
- package/build/src/library/contract-operations.js +23 -19
- package/build/src/library/contract-outcomes.d.ts +3 -3
- package/build/src/library/contract-settings.d.ts +1 -0
- package/build/src/library/contract-settings.js +1 -1
- package/build/src/library/invocation.d.ts +2 -2
- package/build/src/library/invocation.js +1 -1
- package/build/src/library/keiyaku.d.ts +2 -2
- package/build/src/library/keiyaku.js +2 -2
- package/build/src/library/outcome.d.ts +148 -268
- package/build/src/library/outcome.js +4 -8
- package/build/src/library/refusal.d.ts +2 -2
- package/build/src/library/refusal.js +2 -2
- package/build/src/plugin/runtime.js +15 -19
- package/build/src/protocol/{audit.d.ts → delivery-preview.d.ts} +62 -97
- package/build/src/protocol/delivery-preview.js +167 -0
- package/build/src/protocol/progress.d.ts +1 -1
- package/build/src/runtime/proc/run.js +22 -4
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/verification/execution.js +5 -3
- package/package.json +5 -2
- package/skills/keiyaku/SKILL.md +3 -1
- package/skills/keiyaku-babysit/SKILL.md +1 -1
- package/skills/keiyaku-bind/SKILL.md +3 -2
- package/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/src/cli/render/audit.d.ts +0 -7
- package/build/src/protocol/audit.js +0 -203
package/build/src/git/process.js
CHANGED
|
@@ -15,6 +15,21 @@ export class GitPlumbingError extends Error {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
const GIT_STDERR_BYTES = 16 * 1024;
|
|
18
|
+
export function gitChildEnvironment(environment) {
|
|
19
|
+
const inherited = { ...process.env };
|
|
20
|
+
for (const variable of [
|
|
21
|
+
"GIT_DIR",
|
|
22
|
+
"GIT_WORK_TREE",
|
|
23
|
+
"GIT_INDEX_FILE",
|
|
24
|
+
"GIT_OBJECT_DIRECTORY",
|
|
25
|
+
"GIT_ALTERNATE_OBJECT_DIRECTORIES",
|
|
26
|
+
"GIT_COMMON_DIR",
|
|
27
|
+
"GIT_NAMESPACE",
|
|
28
|
+
]) {
|
|
29
|
+
delete inherited[variable];
|
|
30
|
+
}
|
|
31
|
+
return { ...inherited, ...environment };
|
|
32
|
+
}
|
|
18
33
|
function commandError(command, error) {
|
|
19
34
|
const candidate = error;
|
|
20
35
|
const stderr = candidate.stderr === undefined ? Buffer.alloc(0) : Buffer.from(candidate.stderr);
|
|
@@ -39,7 +54,7 @@ export async function executeGit(repository, args, input, environment) {
|
|
|
39
54
|
const owned = spawnCancellableProcess({
|
|
40
55
|
argv: [repository.gitPath, ...args],
|
|
41
56
|
cwd: repository.effectiveCwd,
|
|
42
|
-
|
|
57
|
+
env: gitChildEnvironment(environment),
|
|
43
58
|
...(repository.signal === undefined ? {} : { signal: repository.signal }),
|
|
44
59
|
});
|
|
45
60
|
const child = owned.child;
|
|
@@ -115,6 +130,7 @@ export async function runGitPipe(repository, sourceArgs, sinkArgs) {
|
|
|
115
130
|
const owned = spawnCancellableProcess({
|
|
116
131
|
argv: [repository.gitPath, ...args],
|
|
117
132
|
cwd: repository.effectiveCwd,
|
|
133
|
+
env: gitChildEnvironment(),
|
|
118
134
|
...(repository.signal === undefined ? {} : { signal: repository.signal }),
|
|
119
135
|
});
|
|
120
136
|
processes.push(owned);
|
|
@@ -186,6 +202,7 @@ export async function consumeGitStdout(repository, args, consume) {
|
|
|
186
202
|
const result = await consumeProcessStdout({
|
|
187
203
|
argv: [repository.gitPath, ...args],
|
|
188
204
|
cwd: repository.effectiveCwd,
|
|
205
|
+
env: gitChildEnvironment(),
|
|
189
206
|
...(repository.signal === undefined ? {} : { signal: repository.signal }),
|
|
190
207
|
}, consume);
|
|
191
208
|
const { outcome } = result;
|
|
@@ -3,7 +3,7 @@ import { spawnCancellableProcess } from "../runtime/proc/run.js";
|
|
|
3
3
|
import { gitObjectId } from "./identity.js";
|
|
4
4
|
import { parseTreeObject, validPath } from "./tree.js";
|
|
5
5
|
import { GIT_FORMAT_BYTES, GIT_FORMAT_PATH, GIT_REF, readRef } from "./repository.js";
|
|
6
|
-
import { GitPlumbingError } from "./process.js";
|
|
6
|
+
import { gitChildEnvironment, GitPlumbingError } from "./process.js";
|
|
7
7
|
const gitReadObservationBrand = Symbol("GitReadObservation");
|
|
8
8
|
const gitDecodeChannelBrand = Symbol("GitDecodeChannel");
|
|
9
9
|
const BATCH_RETIREMENT_GRACE_MS = 5_000;
|
|
@@ -54,6 +54,7 @@ function batchChild(repository) {
|
|
|
54
54
|
return spawnCancellableProcess({
|
|
55
55
|
argv: [repository.gitPath, "cat-file", "--batch"],
|
|
56
56
|
cwd: repository.effectiveCwd,
|
|
57
|
+
env: gitChildEnvironment(),
|
|
57
58
|
...(repository.signal === undefined ? {} : { signal: repository.signal }),
|
|
58
59
|
});
|
|
59
60
|
}
|
|
@@ -10,9 +10,13 @@ export declare const worktreeLeakSchema: z.ZodObject<{
|
|
|
10
10
|
diagnostic: z.ZodString;
|
|
11
11
|
}, z.core.$strict>;
|
|
12
12
|
export type WorktreeLeak = z.infer<typeof worktreeLeakSchema>;
|
|
13
|
+
export declare class ScratchMaterializationError extends Error {
|
|
14
|
+
readonly leak: WorktreeLeak;
|
|
15
|
+
constructor(cause: unknown, leak: WorktreeLeak);
|
|
16
|
+
}
|
|
13
17
|
type CollectableScratchRemoval = Readonly<{
|
|
14
18
|
path: string;
|
|
15
|
-
/** False only when
|
|
19
|
+
/** False only when scratch custody is confirmed absent; retained removals own a diagnostic. */
|
|
16
20
|
retained: boolean;
|
|
17
21
|
diagnostic?: string;
|
|
18
22
|
}>;
|
package/build/src/git/scratch.js
CHANGED
|
@@ -6,12 +6,21 @@ import { basename, dirname, join } from "node:path";
|
|
|
6
6
|
import { acquireSqliteTransactionLock, tryAcquireSqliteTransactionLock, } from "../coordination/sqlite-transaction-lock.js";
|
|
7
7
|
import { contractLocator, gitRefLocator, gitObjectIdForSnapshot } from "./identity.js";
|
|
8
8
|
import { executeGit } from "./process.js";
|
|
9
|
+
import { registeredWorktreePaths } from "./repository.js";
|
|
9
10
|
const SCRATCH_PREFIX = "keiyaku-v4-verify-";
|
|
10
11
|
const SCRATCH_ROOT = await realpath(tmpdir());
|
|
11
12
|
const SCRATCH_PATTERN = /^keiyaku-v4-verify-([0-9a-f]{24}|[0-9a-f]{64}-[0-9a-f]{64})$/;
|
|
12
13
|
/** One bounded removal attempt per scratch; expiry is reported, never retried inside this call. */
|
|
13
14
|
const SCRATCH_REMOVAL_TIMEOUT_MS = 120_000;
|
|
14
15
|
export const worktreeLeakSchema = z.object({ path: z.string().optional(), diagnostic: z.string() }).strict();
|
|
16
|
+
export class ScratchMaterializationError extends Error {
|
|
17
|
+
leak;
|
|
18
|
+
constructor(cause, leak) {
|
|
19
|
+
super(`${cause instanceof Error ? cause.message : String(cause)}; scratch cleanup failed at ${leak.path}: ${leak.diagnostic}`, { cause });
|
|
20
|
+
this.name = "ScratchMaterializationError";
|
|
21
|
+
this.leak = { ...leak, diagnostic: this.message };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
15
24
|
function scratchPath() {
|
|
16
25
|
return join(SCRATCH_ROOT, `${SCRATCH_PREFIX}${randomBytes(12).toString("hex")}`);
|
|
17
26
|
}
|
|
@@ -58,22 +67,34 @@ async function pathExists(path) {
|
|
|
58
67
|
}
|
|
59
68
|
async function removeScratch(repository, path) {
|
|
60
69
|
const removal = AbortSignal.timeout(SCRATCH_REMOVAL_TIMEOUT_MS);
|
|
70
|
+
const retirementRepository = { ...repository, signal: removal };
|
|
71
|
+
let present = true;
|
|
72
|
+
let absenceDiagnostic;
|
|
73
|
+
try {
|
|
74
|
+
present = await pathExists(path);
|
|
75
|
+
if (!present && !(await registeredWorktreePaths(retirementRepository)).includes(path)) {
|
|
76
|
+
present = await pathExists(path);
|
|
77
|
+
if (!present)
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
absenceDiagnostic = `scratch absence could not be confirmed: ${error instanceof Error ? error.message : String(error)}`;
|
|
83
|
+
}
|
|
84
|
+
let diagnostic;
|
|
61
85
|
try {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
: null;
|
|
86
|
+
await executeGit(retirementRepository, ["worktree", "remove", ...(present ? ["--force"] : []), path]);
|
|
87
|
+
if (!(await pathExists(path)))
|
|
88
|
+
return null;
|
|
89
|
+
diagnostic = `Git reported scratch worktree removal but the path remains: ${path}`;
|
|
67
90
|
}
|
|
68
91
|
catch (error) {
|
|
69
92
|
const original = error instanceof Error ? error.message : String(error);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
? `scratch worktree removal timed out after ${SCRATCH_REMOVAL_TIMEOUT_MS}ms: ${original}`
|
|
74
|
-
: original,
|
|
75
|
-
};
|
|
93
|
+
diagnostic = removal.aborted
|
|
94
|
+
? `scratch worktree removal timed out after ${SCRATCH_REMOVAL_TIMEOUT_MS}ms: ${original}`
|
|
95
|
+
: original;
|
|
76
96
|
}
|
|
97
|
+
return { path, diagnostic: absenceDiagnostic === undefined ? diagnostic : `${absenceDiagnostic}; ${diagnostic}` };
|
|
77
98
|
}
|
|
78
99
|
/** Remove only abandoned Verification scratch worktrees whose ownership locks are held. */
|
|
79
100
|
export async function removeCollectableScratchWorktrees(repository, paths, terminalContract) {
|
|
@@ -158,7 +179,15 @@ export async function materializeScratchCandidate(repository, candidate, contrac
|
|
|
158
179
|
await executeGit(repository, ["worktree", "add", "--detach", cwd, gitObjectIdForSnapshot(candidate)]);
|
|
159
180
|
}
|
|
160
181
|
catch (error) {
|
|
161
|
-
|
|
182
|
+
let leak;
|
|
183
|
+
try {
|
|
184
|
+
leak = await removeScratch(repository, cwd);
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
ownership.close();
|
|
188
|
+
}
|
|
189
|
+
if (leak !== null)
|
|
190
|
+
throw new ScratchMaterializationError(error, leak);
|
|
162
191
|
await removeOwnershipLock(lockPath);
|
|
163
192
|
throw error;
|
|
164
193
|
}
|
|
@@ -72,19 +72,37 @@ type TargetPlacementObservationInput = Readonly<{
|
|
|
72
72
|
predecessor: SnapshotId;
|
|
73
73
|
candidate: SnapshotId;
|
|
74
74
|
}>;
|
|
75
|
+
declare const targetCheckoutObservationSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
76
|
+
kind: z.ZodLiteral<"followable">;
|
|
77
|
+
path: z.ZodString;
|
|
78
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
79
|
+
kind: z.ZodLiteral<"not-followable">;
|
|
80
|
+
path: z.ZodString;
|
|
81
|
+
diagnostic: z.ZodString;
|
|
82
|
+
}, z.core.$strict>]>;
|
|
83
|
+
type TargetCheckoutObservation = z.infer<typeof targetCheckoutObservationSchema>;
|
|
75
84
|
type TargetPlacementObservation = Readonly<{
|
|
76
85
|
kind: "ready";
|
|
77
86
|
arms: readonly FollowArm[];
|
|
87
|
+
checkouts: readonly TargetCheckoutObservation[];
|
|
78
88
|
}> | Readonly<{
|
|
79
89
|
kind: "refused";
|
|
80
90
|
refusal: TargetPlacementRefusal;
|
|
81
91
|
}>;
|
|
82
92
|
/** Observe whether registered target checkouts can follow a predecessor-to-candidate movement. */
|
|
83
93
|
export declare function observeTargetPlacement(repository: GitRepository, input: TargetPlacementObservationInput, changes?: TargetPlacementChanges): Promise<TargetPlacementObservation>;
|
|
84
|
-
export declare const
|
|
94
|
+
export declare const previewTargetAnswerSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
85
95
|
kind: z.ZodLiteral<"placeable">;
|
|
86
96
|
ref: z.ZodString;
|
|
87
97
|
head: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
|
|
98
|
+
checkouts: z.ZodReadonly<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
99
|
+
kind: z.ZodLiteral<"followable">;
|
|
100
|
+
path: z.ZodString;
|
|
101
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
102
|
+
kind: z.ZodLiteral<"not-followable">;
|
|
103
|
+
path: z.ZodString;
|
|
104
|
+
diagnostic: z.ZodString;
|
|
105
|
+
}, z.core.$strict>]>>>;
|
|
88
106
|
}, z.core.$strict>, z.ZodObject<{
|
|
89
107
|
kind: z.ZodLiteral<"moved">;
|
|
90
108
|
ref: z.ZodString;
|
|
@@ -104,9 +122,9 @@ export declare const auditTargetAnswerSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
104
122
|
kind: z.ZodLiteral<"failed">;
|
|
105
123
|
diagnostic: z.ZodString;
|
|
106
124
|
}, z.core.$strict>]>;
|
|
107
|
-
type
|
|
108
|
-
/** Adjudicate
|
|
109
|
-
export declare function
|
|
125
|
+
type PreviewTargetAnswer = z.infer<typeof previewTargetAnswerSchema>;
|
|
126
|
+
/** Adjudicate prospective target followability without placing or running Verification. */
|
|
127
|
+
export declare function adjudicatePreviewTarget(repository: GitRepository, input: TargetPlacementObservationInput): Promise<PreviewTargetAnswer>;
|
|
110
128
|
export declare function prepareTargetPlacement(repository: GitRepository, state: ContractState, target: RefOperation, changes?: TargetPlacementChanges): Promise<TargetPlacementPreparation>;
|
|
111
129
|
export declare function followTargetPlacement(repository: GitRepository, prepared: PreparedTargetPlacement, onPhysical?: (report: TargetPlacementPhysicalResult) => void): Promise<TargetPlacementPhysicalResult>;
|
|
112
130
|
/** Judge the target-checkout shape without mutating refs, worktrees, or indexes. */
|
|
@@ -183,9 +183,8 @@ async function matchesTreeOnPaths(repository, path, command, trees, paths) {
|
|
|
183
183
|
return (await gitPaths(repository, path, args)).length === 0;
|
|
184
184
|
}
|
|
185
185
|
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* git carries that by silently destroying the entry, so it is refused here instead.
|
|
186
|
+
* Retain the single dry-run's followability observation separately from ref-placement legality.
|
|
187
|
+
* Only a candidate write that silently destroys an ignored entry refuses placement here.
|
|
189
188
|
*/
|
|
190
189
|
async function ordinaryPrecheck(repository, contractId, target, path, changes) {
|
|
191
190
|
const predecessor = gitObjectIdForSnapshot(target.expectedOid);
|
|
@@ -197,10 +196,11 @@ async function ordinaryPrecheck(repository, contractId, target, path, changes) {
|
|
|
197
196
|
catch (error) {
|
|
198
197
|
if (!(error instanceof GitPlumbingError) || repository.signal?.aborted === true)
|
|
199
198
|
throw error;
|
|
200
|
-
return
|
|
199
|
+
return { kind: "not-followable", diagnostic: error.message };
|
|
201
200
|
}
|
|
202
201
|
const scopes = await destructionScopes(path, changes.writes);
|
|
203
|
-
|
|
202
|
+
const refusal = await untrackedRefusalWithinScopes(observation, scopes);
|
|
203
|
+
return refusal === null ? { kind: "followable" } : { kind: "refused", refusal };
|
|
204
204
|
}
|
|
205
205
|
export async function acquireTargetPlacementFence(repository, target) {
|
|
206
206
|
const locator = gitRefLocator(target);
|
|
@@ -211,6 +211,10 @@ export async function acquireTargetPlacementFence(repository, target) {
|
|
|
211
211
|
...(repository.signal === undefined ? {} : { signal: repository.signal }),
|
|
212
212
|
});
|
|
213
213
|
}
|
|
214
|
+
const targetCheckoutObservationSchema = z.union([
|
|
215
|
+
z.object({ kind: z.literal("followable"), path: z.string().min(1) }).strict(),
|
|
216
|
+
z.object({ kind: z.literal("not-followable"), path: z.string().min(1), diagnostic: z.string().min(1) }).strict(),
|
|
217
|
+
]);
|
|
214
218
|
/** Observe whether registered target checkouts can follow a predecessor-to-candidate movement. */
|
|
215
219
|
export async function observeTargetPlacement(repository, input, changes) {
|
|
216
220
|
const target = {
|
|
@@ -225,20 +229,23 @@ export async function observeTargetPlacement(repository, input, changes) {
|
|
|
225
229
|
.filter((worktree) => worktree.branch === target.target)
|
|
226
230
|
.sort((left, right) => left.path.localeCompare(right.path));
|
|
227
231
|
const arms = [];
|
|
232
|
+
const checkouts = [];
|
|
228
233
|
for (const worktree of worktrees) {
|
|
229
|
-
const
|
|
230
|
-
if (
|
|
231
|
-
return
|
|
234
|
+
const precheck = await ordinaryPrecheck(repository, input.contractId, target, worktree.path, changes);
|
|
235
|
+
if (precheck.kind === "refused")
|
|
236
|
+
return precheck;
|
|
237
|
+
checkouts.push({ ...precheck, path: worktree.path });
|
|
232
238
|
arms.push({ kind: "ordinary", path: worktree.path });
|
|
233
239
|
}
|
|
234
|
-
return { kind: "ready", arms };
|
|
240
|
+
return { kind: "ready", arms, checkouts };
|
|
235
241
|
}
|
|
236
|
-
export const
|
|
242
|
+
export const previewTargetAnswerSchema = z.union([
|
|
237
243
|
z
|
|
238
244
|
.object({
|
|
239
245
|
kind: z.literal("placeable"),
|
|
240
246
|
ref: z.string().refine((value) => value.trim() !== ""),
|
|
241
247
|
head: snapshotIdSchema,
|
|
248
|
+
checkouts: z.array(targetCheckoutObservationSchema).readonly(),
|
|
242
249
|
})
|
|
243
250
|
.strict(),
|
|
244
251
|
z
|
|
@@ -252,8 +259,8 @@ export const auditTargetAnswerSchema = z.union([
|
|
|
252
259
|
z.object({ kind: z.literal("refused"), refusal: checkoutNotFollowableRefusalSchema }).strict(),
|
|
253
260
|
z.object({ kind: z.literal("failed"), diagnostic: z.string().refine((value) => value.trim() !== "") }).strict(),
|
|
254
261
|
]);
|
|
255
|
-
/** Adjudicate
|
|
256
|
-
export async function
|
|
262
|
+
/** Adjudicate prospective target followability without placing or running Verification. */
|
|
263
|
+
export async function adjudicatePreviewTarget(repository, input) {
|
|
257
264
|
const ref = input.coordinates.target;
|
|
258
265
|
const expected = input.predecessor;
|
|
259
266
|
try {
|
|
@@ -266,11 +273,12 @@ export async function adjudicateAuditTarget(repository, input) {
|
|
|
266
273
|
return { kind: "moved", ref, expected, observed };
|
|
267
274
|
return follow.kind === "refused"
|
|
268
275
|
? { kind: "refused", refusal: follow.refusal }
|
|
269
|
-
: { kind: "placeable", ref, head: expected };
|
|
276
|
+
: { kind: "placeable", ref, head: expected, checkouts: follow.checkouts };
|
|
270
277
|
}
|
|
271
278
|
catch (error) {
|
|
272
279
|
if (!(error instanceof GitPlumbingError))
|
|
273
280
|
throw error;
|
|
281
|
+
repository.signal?.throwIfAborted();
|
|
274
282
|
return { kind: "failed", diagnostic: error.message };
|
|
275
283
|
}
|
|
276
284
|
}
|
|
@@ -345,9 +353,9 @@ export async function observeTargetCheckoutShape(repository, input) {
|
|
|
345
353
|
async function recoverCheckout(input) {
|
|
346
354
|
const classified = await classifyCheckout(input);
|
|
347
355
|
if (classified.kind === "complete")
|
|
348
|
-
return "complete";
|
|
356
|
+
return { kind: "complete" };
|
|
349
357
|
if (classified.kind === "retained")
|
|
350
|
-
return "retained";
|
|
358
|
+
return { kind: "retained", diagnostic: "target checkout entries are neither predecessor nor candidate" };
|
|
351
359
|
const { repository, path, predecessor, candidate } = input;
|
|
352
360
|
if (classified.action === "index-merge") {
|
|
353
361
|
await executeGit(repository, [
|
|
@@ -359,8 +367,15 @@ async function recoverCheckout(input) {
|
|
|
359
367
|
gitObjectIdForSnapshot(predecessor),
|
|
360
368
|
gitObjectIdForSnapshot(candidate),
|
|
361
369
|
]);
|
|
362
|
-
return "recovered";
|
|
370
|
+
return { kind: "recovered" };
|
|
363
371
|
}
|
|
372
|
+
const scopes = await destructionScopes(path, input.changes.writes);
|
|
373
|
+
const refusal = await untrackedRefusalWithinScopes(input, scopes);
|
|
374
|
+
if (refusal !== null)
|
|
375
|
+
return {
|
|
376
|
+
kind: "retained",
|
|
377
|
+
diagnostic: `target checkout would overwrite ignored local entries: ${refusal.paths.join(", ")}`,
|
|
378
|
+
};
|
|
364
379
|
await executeGit(repository, [
|
|
365
380
|
"-C",
|
|
366
381
|
path,
|
|
@@ -370,7 +385,7 @@ async function recoverCheckout(input) {
|
|
|
370
385
|
gitObjectIdForSnapshot(predecessor),
|
|
371
386
|
gitObjectIdForSnapshot(candidate),
|
|
372
387
|
]);
|
|
373
|
-
return "recovered";
|
|
388
|
+
return { kind: "recovered" };
|
|
374
389
|
}
|
|
375
390
|
export async function recoverTargetPlacement(repository, state, onPhysical) {
|
|
376
391
|
const target = state.coordinates.target;
|
|
@@ -380,6 +395,12 @@ export async function recoverTargetPlacement(repository, state, onPhysical) {
|
|
|
380
395
|
const integration = state.currentIntegration;
|
|
381
396
|
if (integration === null || (await readRef(repository, target)) !== integration.snapshot)
|
|
382
397
|
return { effects: [], lag: [] };
|
|
398
|
+
const movement = {
|
|
399
|
+
target,
|
|
400
|
+
expectedOid: integration.predecessor,
|
|
401
|
+
newOid: integration.snapshot,
|
|
402
|
+
};
|
|
403
|
+
const changes = await prepareTargetPlacementChanges(repository, movement);
|
|
383
404
|
const candidateTree = await commitTree(repository, integration.snapshot);
|
|
384
405
|
const predecessorTree = await commitTree(repository, integration.predecessor);
|
|
385
406
|
const worktrees = (await registeredWorktrees(repository))
|
|
@@ -392,18 +413,21 @@ export async function recoverTargetPlacement(repository, state, onPhysical) {
|
|
|
392
413
|
try {
|
|
393
414
|
const recovery = await recoverCheckout({
|
|
394
415
|
repository,
|
|
416
|
+
contractId: state.id,
|
|
417
|
+
target: movement,
|
|
418
|
+
changes,
|
|
395
419
|
path: worktree.path,
|
|
396
420
|
predecessor: integration.predecessor,
|
|
397
421
|
candidate: integration.snapshot,
|
|
398
422
|
predecessorTree,
|
|
399
423
|
candidateTree,
|
|
400
424
|
});
|
|
401
|
-
if (recovery === "retained") {
|
|
402
|
-
lag.push(recoveryLag(worktree.path, target,
|
|
425
|
+
if (recovery.kind === "retained") {
|
|
426
|
+
lag.push(recoveryLag(worktree.path, target, recovery.diagnostic));
|
|
403
427
|
onPhysical?.({ effects: [], lag: lag.slice(beforeLag) });
|
|
404
428
|
continue;
|
|
405
429
|
}
|
|
406
|
-
if (recovery === "recovered") {
|
|
430
|
+
if (recovery.kind === "recovered") {
|
|
407
431
|
effects.push({ kind: "target-checkout", path: worktree.path, target, action: "recovered" });
|
|
408
432
|
}
|
|
409
433
|
}
|
package/build/src/index.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export { AkumaAddressError, AkumaWorldScopeError, Akumas } from "./library/akuma
|
|
|
54
54
|
export type { AkumaAddressInput, AkumaAskInput, AkumaHistoryInput, AkumaHistoryResult, AkumaKillInput, AkumaKillResult, AkumaList, AkumaListInput, AkumaObservation, AkumaObservationStage, AkumaTellInput, AkumaWaitInput, AkumaWaitResult, AkumaWorldScopeRefusal, CallInput, CallResult, CallWaitHead, CreatedDebtObservation, DispatchAssociation, DispatchStage, ForkInput, ForkResult, TellResult, TellWake, } from "./library/akumas.js";
|
|
55
55
|
export type { ContinuationReport } from "./library/continuation.js";
|
|
56
56
|
export type { KeiyakuLibrary, ReconcileInput } from "./library/contract-composition.js";
|
|
57
|
-
export type { AbandonOutcome, AmendOutcome, ArcOutcome,
|
|
57
|
+
export type { AbandonOutcome, AmendOutcome, ArcOutcome, DeliveryPreviewInput, DeliveryPreviewOutcome, BindOutcome, BindResult, DeliverOutcome, ReviewOutcome, } from "./library/contract-outcomes.js";
|
|
58
58
|
export type { AbandonInput, AmendInput, ArcInput, BindInput, ContractHistory, ContractHistoryEvent, ContractList, ContractListInput, ContractObservationInput, ContractResolveInput, ContractResolution, ContractSelectorRefusal, DeliverInput, KeiyakuSelectInput, LocalContractComposition, ReviewInput, } from "./library/contract-types.js";
|
|
59
59
|
export { nukeKeiyaku as nuke } from "./library/nuke.js";
|
|
60
60
|
export type { NukeInput, NukeResult } from "./library/nuke.js";
|
|
@@ -64,7 +64,7 @@ export type { KeiyakuRefusal, KeiyakuRetryReason, NukeConfirmationRefusal, NukeC
|
|
|
64
64
|
export type { RegionOverlap } from "./library/region.js";
|
|
65
65
|
export type { RepoAtInput } from "./library/repo.js";
|
|
66
66
|
export type { KeiyakuPlugin, PluginAkumaCaller, PluginAkumaOrigin, PluginBodyEnd, PluginContext, PluginHooks, PluginInstance, PluginManifest, PluginOutcome, PluginSignal, PluginSignalMap, } from "./plugin/public.js";
|
|
67
|
-
export type {
|
|
67
|
+
export type { DeliveryPreviewReport } from "./protocol/delivery-preview.js";
|
|
68
68
|
export type { IntegrationConflictMaterialized, VerificationReuse } from "./protocol/deliver.js";
|
|
69
69
|
export type { ExecutionObservation, ExecutionObserver } from "./protocol/execution-observation.js";
|
|
70
70
|
export type { PlacementStop, VerificationStop } from "./protocol/operations.js";
|