@astrosheep/keiyaku 4.5.7 → 4.5.9
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/README.md +10 -0
- 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/opencode.js +3 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +12 -11
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +33 -12
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +35 -96
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +28 -49
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +21 -15
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +148 -89
- package/build/src/akuma/abort.d.ts +2 -1
- package/build/src/akuma/abort.js +6 -23
- package/build/src/akuma/akuma-handle.js +4 -2
- package/build/src/akuma/akuma-observe.d.ts +2 -0
- package/build/src/akuma/akuma-observe.js +1 -0
- package/build/src/akuma/akuma-product.js +9 -7
- package/build/src/akuma/akuma.d.ts +392 -9
- package/build/src/akuma/akuma.js +31 -1
- package/build/src/akuma/allowed.d.ts +1 -1
- package/build/src/akuma/allowed.js +1 -0
- package/build/src/akuma/archetype.js +1 -1
- package/build/src/akuma/body.d.ts +8 -5
- package/build/src/akuma/body.js +12 -5
- package/build/src/akuma/call-request.d.ts +80 -0
- package/build/src/akuma/call-request.js +211 -0
- package/build/src/akuma/heart/facts.d.ts +16 -78
- package/build/src/akuma/heart/facts.js +11 -0
- package/build/src/akuma/heart/index.d.ts +3 -2
- package/build/src/akuma/heart/index.js +4 -1
- package/build/src/akuma/heart/request-authority.d.ts +5 -4
- package/build/src/akuma/heart/request-authority.js +20 -34
- package/build/src/akuma/heart/request-rows.js +12 -23
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +5 -13
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/projection-read.d.ts +1 -0
- package/build/src/akuma/projection-read.js +8 -1
- package/build/src/akuma/projection.d.ts +907 -137
- package/build/src/akuma/projection.js +193 -9
- package/build/src/akuma/provider.d.ts +30 -3
- package/build/src/akuma/provider.js +111 -0
- package/build/src/akuma/providers/acp/core.d.ts +2 -2
- package/build/src/akuma/providers/acp/core.js +13 -6
- package/build/src/akuma/providers/acp/index.js +5 -4
- package/build/src/akuma/providers/claude/events.d.ts +2 -2
- package/build/src/akuma/providers/claude/events.js +16 -3
- package/build/src/akuma/providers/claude/index.d.ts +3 -3
- package/build/src/akuma/providers/claude/index.js +16 -5
- package/build/src/akuma/providers/codex-app-server/events.d.ts +2 -2
- package/build/src/akuma/providers/codex-app-server/events.js +25 -4
- package/build/src/akuma/providers/codex-app-server/index.js +18 -6
- package/build/src/akuma/providers/grok-build/index.js +5 -4
- package/build/src/akuma/providers/opencode-sdk/index.js +66 -25
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/session.js +28 -11
- package/build/src/akuma/providers/pi/index.js +72 -58
- package/build/src/akuma/request-lifecycle.d.ts +4 -10
- package/build/src/akuma/request-lifecycle.js +7 -5
- package/build/src/akuma/request-rendezvous.d.ts +26 -0
- package/build/src/akuma/request-rendezvous.js +100 -0
- package/build/src/akuma/request-serve.d.ts +6 -66
- package/build/src/akuma/request-serve.js +83 -210
- package/build/src/akuma/request-wire.d.ts +109 -115
- package/build/src/akuma/request-wire.js +63 -318
- package/build/src/akuma/requests.d.ts +19 -47
- package/build/src/akuma/requests.js +51 -107
- package/build/src/akuma/turn-drive.d.ts +5 -3
- package/build/src/akuma/turn-drive.js +39 -11
- package/build/src/akuma-body.d.ts +7 -2
- package/build/src/akuma-body.js +68 -46
- package/build/src/body/amend.js +18 -19
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +2 -2
- package/build/src/cli/commands/akuma-invoke.d.ts +2 -0
- package/build/src/cli/commands/akuma-invoke.js +17 -9
- package/build/src/cli/commands/akuma.js +8 -8
- package/build/src/cli/commands/contract-invoke.d.ts +3 -2
- package/build/src/cli/commands/contract-invoke.js +42 -30
- package/build/src/cli/commands/contract.d.ts +16 -20
- package/build/src/cli/commands/contract.js +58 -25
- package/build/src/cli/commands/install.d.ts +2 -1
- package/build/src/cli/commands/install.js +3 -2
- package/build/src/cli/commands/task-invoke.d.ts +3 -0
- package/build/src/cli/commands/task-invoke.js +23 -140
- package/build/src/cli/commands/task.js +54 -20
- package/build/src/cli/invoke.js +39 -25
- package/build/src/cli/main.js +2 -1
- package/build/src/cli/parse.d.ts +2 -2
- package/build/src/cli/parse.js +56 -27
- package/build/src/cli/render/akuma-activity.d.ts +3 -0
- package/build/src/cli/render/akuma-activity.js +45 -29
- package/build/src/cli/render/akuma-tool.d.ts +5 -1
- package/build/src/cli/render/akuma.js +4 -8
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/catalog.js +80 -21
- package/build/src/cli/render/contract-observation.d.ts +2 -0
- package/build/src/cli/render/contract-observation.js +11 -0
- package/build/src/cli/render/contract.js +35 -62
- package/build/src/cli/render/kanshi-akuma.d.ts +8 -0
- package/build/src/cli/render/kanshi-akuma.js +132 -0
- package/build/src/cli/render/kanshi.js +131 -213
- package/build/src/cli/render/receipt.d.ts +1 -2
- package/build/src/cli/render/receipt.js +76 -26
- package/build/src/cli/render/refusal.js +2 -10
- package/build/src/cli/render/region.js +5 -2
- package/build/src/cli/render/settings.d.ts +1 -1
- package/build/src/cli/render/settings.js +27 -8
- package/build/src/cli/render/task.js +22 -5
- package/build/src/cli/render/terminal.d.ts +32 -1
- package/build/src/cli/render/terminal.js +77 -1
- package/build/src/cli/result.d.ts +3 -3
- package/build/src/cli/runtime.js +4 -2
- package/build/src/cli/selectors.d.ts +2 -1
- package/build/src/cli/selectors.js +4 -3
- package/build/src/cli/square-edge.js +120 -36
- package/build/src/cli/usage.js +2 -1
- package/build/src/contract-guidance.d.ts +5 -0
- package/build/src/contract-guidance.js +121 -0
- package/build/src/contract-worktree.d.ts +0 -1
- package/build/src/contract-worktree.js +32 -83
- package/build/src/coordination/sqlite-transaction-lock.d.ts +1 -0
- package/build/src/coordination/sqlite-transaction-lock.js +5 -0
- package/build/src/core/facts/codec.d.ts +2 -0
- package/build/src/core/facts/codec.js +4 -0
- package/build/src/core/verbs/placement.d.ts +6 -1
- package/build/src/core/verbs/placement.js +5 -3
- package/build/src/dispatch/index.d.ts +0 -2
- package/build/src/dispatch/index.js +54 -55
- package/build/src/git/admission.js +2 -2
- package/build/src/git/hooks.d.ts +9 -15
- package/build/src/git/hooks.js +23 -317
- package/build/src/git/nuke.d.ts +2 -1
- package/build/src/git/nuke.js +39 -21
- package/build/src/git/private-state-seat.d.ts +12 -0
- package/build/src/git/private-state-seat.js +39 -0
- package/build/src/git/process.d.ts +6 -0
- package/build/src/git/process.js +26 -11
- package/build/src/git/read-observation.js +29 -20
- package/build/src/git/reconcile.d.ts +13 -1
- package/build/src/git/reconcile.js +70 -11
- package/build/src/git/ref-migration.d.ts +22 -0
- package/build/src/git/ref-migration.js +55 -0
- package/build/src/git/repository.d.ts +10 -6
- package/build/src/git/repository.js +16 -8
- package/build/src/git/target-placement.d.ts +1 -0
- package/build/src/git/target-placement.js +5 -0
- package/build/src/git/tender.d.ts +1 -0
- package/build/src/git/terminal-reconcile.d.ts +1 -1
- package/build/src/git/terminal-reconcile.js +22 -20
- package/build/src/git/workspace.d.ts +14 -0
- package/build/src/git/workspace.js +44 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +16 -16
- package/build/src/kanshi/report.d.ts +2 -2
- package/build/src/library/address.d.ts +9 -3
- package/build/src/library/address.js +3 -2
- package/build/src/library/akuma-creation.d.ts +4 -3
- package/build/src/library/akuma-creation.js +19 -13
- package/build/src/library/audit.d.ts +14 -6
- package/build/src/library/audit.js +13 -23
- package/build/src/library/catalog.d.ts +3 -1
- package/build/src/library/catalog.js +20 -6
- package/build/src/library/composition.d.ts +385 -0
- package/build/src/library/composition.js +28 -0
- package/build/src/library/configuration.js +8 -2
- package/build/src/library/continuation.js +66 -30
- package/build/src/library/contract-bind.js +10 -2
- package/build/src/library/contract-forwarding-reconciliation-result.d.ts +102 -0
- package/build/src/library/contract-forwarding-reconciliation-result.js +92 -0
- package/build/src/library/contract-forwarding-result.d.ts +4464 -0
- package/build/src/library/contract-forwarding-result.js +521 -0
- package/build/src/library/contract-forwarding.d.ts +71 -0
- package/build/src/library/contract-forwarding.js +114 -0
- package/build/src/library/contract-handle.d.ts +38 -0
- package/build/src/library/contract-handle.js +314 -0
- package/build/src/library/contract-operations.d.ts +214 -69
- package/build/src/library/contract-operations.js +189 -118
- package/build/src/library/contract-types.d.ts +7 -3
- package/build/src/library/contract.d.ts +21 -34
- package/build/src/library/contract.js +29 -287
- package/build/src/library/fleet-result.d.ts +1580 -0
- package/build/src/library/fleet-result.js +98 -0
- package/build/src/library/fleet.d.ts +112 -54
- package/build/src/library/fleet.js +211 -71
- package/build/src/library/input.d.ts +3 -1
- package/build/src/library/input.js +11 -1
- package/build/src/library/keiyaku.d.ts +388 -20
- package/build/src/library/keiyaku.js +13 -21
- package/build/src/library/mutation.d.ts +3 -3
- package/build/src/library/mutation.js +5 -9
- package/build/src/library/nuke.d.ts +1 -1
- package/build/src/library/nuke.js +4 -3
- package/build/src/library/reconcile.d.ts +4 -0
- package/build/src/library/reconcile.js +2 -0
- package/build/src/library/refusal.d.ts +0 -9
- package/build/src/library/refusal.js +0 -7
- package/build/src/protocol/amend.js +56 -50
- package/build/src/protocol/attempt.d.ts +2 -0
- package/build/src/protocol/attempt.js +8 -1
- package/build/src/protocol/completion.js +7 -0
- package/build/src/protocol/deliver.js +6 -2
- package/build/src/protocol/operations.d.ts +4 -1
- package/build/src/protocol/operations.js +5 -2
- package/build/src/protocol/placement.d.ts +1 -0
- package/build/src/protocol/placement.js +52 -38
- package/build/src/protocol/read/observation.d.ts +1 -4
- package/build/src/protocol/read/observation.js +2 -15
- package/build/src/protocol/reintegrate.js +62 -58
- package/build/src/protocol/review.js +5 -0
- package/build/src/protocol/run.js +17 -13
- package/build/src/runtime/proc/run.d.ts +9 -0
- package/build/src/runtime/proc/run.js +51 -4
- package/build/src/runtime/proc/termination.js +26 -22
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/holder.d.ts +2 -1
- package/build/src/settlement/holder.js +15 -4
- package/build/src/settlement/settle.js +99 -33
- package/build/src/task/board.d.ts +68 -27
- package/build/src/task/board.js +31 -1
- package/build/src/task/catalog.d.ts +4 -0
- package/build/src/task/catalog.js +23 -0
- package/build/src/task/compose-language.js +33 -7
- package/build/src/task/compose-parser.d.ts +1 -1
- package/build/src/task/compose-parser.js +1 -1
- package/build/src/task/compose.js +2 -0
- package/build/src/task/index.d.ts +12 -4
- package/build/src/task/index.js +97 -16
- package/build/src/task/mutation-result.d.ts +923 -0
- package/build/src/task/mutation-result.js +140 -0
- package/build/src/task/mutation.d.ts +552 -28
- package/build/src/task/mutation.js +304 -97
- package/build/src/task/operations.d.ts +1 -4
- package/build/src/task/operations.js +0 -6
- package/build/src/task/public.d.ts +2 -0
- package/build/src/task/public.js +1 -0
- package/build/src/workspace-place.d.ts +7 -2
- package/build/src/workspace-place.js +34 -24
- package/build/src/world.d.ts +1 -0
- package/build/src/world.js +11 -0
- package/package.json +8 -6
- package/build/src/akuma/request-execution.d.ts +0 -8
- package/build/src/akuma/request-execution.js +0 -98
|
@@ -1,49 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readonly diagnostic: string;
|
|
7
|
-
readonly kind = "akuma-body-request";
|
|
8
|
-
constructor(outcome: "refused" | "voided", diagnostic: string);
|
|
9
|
-
}
|
|
10
|
-
export declare function injectedBodyRequests(): string | null;
|
|
11
|
-
export declare function requestBodyCall(input: Omit<CallRequestClaim, "action"> & Readonly<{
|
|
1
|
+
export { AkumaBodyRequestError, requestBodyCommand } from "./request-rendezvous.js";
|
|
2
|
+
export type ExecutionChannel = Readonly<{
|
|
3
|
+
kind: "local";
|
|
4
|
+
}> | Readonly<{
|
|
5
|
+
kind: "body-request";
|
|
12
6
|
directory: string;
|
|
13
|
-
}>): Promise<import("./identity.js").AkuId>;
|
|
14
|
-
export declare function requestBodyTask(input: Readonly<{
|
|
15
|
-
directory: string;
|
|
16
|
-
world: string;
|
|
17
|
-
request: TaskMutationRequest;
|
|
18
|
-
id?: string;
|
|
19
|
-
}>): Promise<unknown>;
|
|
20
|
-
export declare function requestBodyWait(input: Omit<WaitRequestClaim, "action" | "id"> & Readonly<{
|
|
21
|
-
directory: string;
|
|
22
|
-
id?: string;
|
|
23
|
-
}>): Promise<UpstreamRequestOutcome>;
|
|
24
|
-
export declare function requestBodyTell(input: Omit<TellRequestClaim, "action" | "id"> & Readonly<{
|
|
25
|
-
directory: string;
|
|
26
|
-
id?: string;
|
|
27
|
-
}>): Promise<UpstreamRequestOutcome>;
|
|
28
|
-
export declare function requestBodyKill(input: Omit<KillRequestClaim, "action" | "id"> & Readonly<{
|
|
29
|
-
directory: string;
|
|
30
|
-
id?: string;
|
|
31
|
-
}>): Promise<UpstreamRequestOutcome>;
|
|
32
|
-
type ContractRequestInput<T extends DeliverRequestClaim | ReviewRequestClaim> = Omit<T, "action" | "id"> & Readonly<{
|
|
33
|
-
directory: string;
|
|
34
|
-
signal?: AbortSignal;
|
|
35
7
|
}>;
|
|
36
|
-
type
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
export declare function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
export declare function
|
|
48
|
-
|
|
49
|
-
|
|
8
|
+
export type ExecutionContext = Readonly<{
|
|
9
|
+
channel: ExecutionChannel;
|
|
10
|
+
}>;
|
|
11
|
+
export type LibraryExecution = ExecutionContext;
|
|
12
|
+
export declare function localExecutionContext(): ExecutionContext;
|
|
13
|
+
export declare function bodyRequestExecutionContext(directory: unknown): ExecutionContext;
|
|
14
|
+
/** Constructs the one direct-parent route a caller may explicitly compose. */
|
|
15
|
+
export declare function bodyRequestExecution(input: Readonly<{
|
|
16
|
+
directory: string;
|
|
17
|
+
}>): LibraryExecution;
|
|
18
|
+
/** Normalizes the public carrier before a composition captures its immutable channel. */
|
|
19
|
+
export declare function libraryExecution(value: unknown): LibraryExecution;
|
|
20
|
+
export declare function libraryExecutionInput(input: unknown): LibraryExecution;
|
|
21
|
+
export declare function executionChannel(context?: ExecutionContext): ExecutionChannel;
|
|
@@ -1,120 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { isTaskMutationAction } from "../task/mutation.js";
|
|
7
|
-
const POLL_MS = 100;
|
|
8
|
-
export class AkumaBodyRequestError extends Error {
|
|
9
|
-
outcome;
|
|
10
|
-
diagnostic;
|
|
11
|
-
kind = "akuma-body-request";
|
|
12
|
-
constructor(outcome, diagnostic) {
|
|
13
|
-
super(`Akuma body request ${outcome}: ${diagnostic}`);
|
|
14
|
-
this.outcome = outcome;
|
|
15
|
-
this.diagnostic = diagnostic;
|
|
16
|
-
this.name = "AkumaBodyRequestError";
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
export function injectedBodyRequests() {
|
|
20
|
-
const directory = process.env[AKUMA_REQUESTS_ENV];
|
|
21
|
-
if (directory === undefined)
|
|
22
|
-
return null;
|
|
23
|
-
if (!absolute(directory))
|
|
24
|
-
throw new Error(`${AKUMA_REQUESTS_ENV} must be an absolute normalized path`);
|
|
25
|
-
return directory;
|
|
1
|
+
import { isAbsolute, resolve } from "node:path";
|
|
2
|
+
export { AkumaBodyRequestError, requestBodyCommand } from "./request-rendezvous.js";
|
|
3
|
+
const LOCAL_CHANNEL = Object.freeze({ kind: "local" });
|
|
4
|
+
export function localExecutionContext() {
|
|
5
|
+
return Object.freeze({ channel: LOCAL_CHANNEL });
|
|
26
6
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
await atomicJson(requestPath(input.directory, transportId), {
|
|
31
|
-
id: input.claim.id,
|
|
32
|
-
action: input.claim.action,
|
|
33
|
-
payload: requestPayload(input.claim),
|
|
34
|
-
});
|
|
35
|
-
const path = receiptPath(input.directory, transportId);
|
|
36
|
-
for (;;) {
|
|
37
|
-
try {
|
|
38
|
-
const receipt = decodeReceipt(await readFile(path, "utf8"), input.claim.id, input.claim.action);
|
|
39
|
-
if (receipt === null)
|
|
40
|
-
throw new Error(`Akuma body request ${input.claim.id} has an invalid receipt`);
|
|
41
|
-
if (receipt.state === "refused")
|
|
42
|
-
throw new AkumaBodyRequestError("refused", receipt.diagnostic);
|
|
43
|
-
if (receipt.state === "voided")
|
|
44
|
-
throw new AkumaBodyRequestError("voided", receipt.evidence);
|
|
45
|
-
return receipt;
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
if (error.code !== "ENOENT")
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
if (!(await access(input.directory).then(() => true, () => false))) {
|
|
52
|
-
throw new AkumaBodyRequestError("voided", "parent request channel closed before a receipt");
|
|
53
|
-
}
|
|
54
|
-
await abortableDelay(POLL_MS, input.signal);
|
|
7
|
+
export function bodyRequestExecutionContext(directory) {
|
|
8
|
+
if (typeof directory !== "string" || !isAbsolute(directory) || resolve(directory) !== directory) {
|
|
9
|
+
throw new Error("AKUMA_REQUESTS must be an absolute normalized path");
|
|
55
10
|
}
|
|
11
|
+
return Object.freeze({ channel: Object.freeze({ kind: "body-request", directory }) });
|
|
56
12
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (receipt.action !== "akuma.call" || receipt.state !== "served") {
|
|
61
|
-
throw new Error(`Akuma body request ${input.id} returned the wrong action`);
|
|
13
|
+
function valueRecord(value, label) {
|
|
14
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
15
|
+
throw new TypeError(`${label} must be an object`);
|
|
62
16
|
}
|
|
63
|
-
return
|
|
17
|
+
return value;
|
|
64
18
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
19
|
+
function closed(value, keys, label) {
|
|
20
|
+
for (const key of Object.keys(value)) {
|
|
21
|
+
if (!keys.includes(key))
|
|
22
|
+
throw new TypeError(`${label} has unknown field: ${key}`);
|
|
69
23
|
}
|
|
70
|
-
return receipt.outcome;
|
|
71
24
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
25
|
+
/** Constructs the one direct-parent route a caller may explicitly compose. */
|
|
26
|
+
export function bodyRequestExecution(input) {
|
|
27
|
+
const value = valueRecord(input, "body request execution input");
|
|
28
|
+
closed(value, ["directory"], "body request execution input");
|
|
29
|
+
if (typeof value.directory !== "string")
|
|
30
|
+
throw new TypeError("body request execution directory must be a string");
|
|
31
|
+
try {
|
|
32
|
+
return bodyRequestExecutionContext(value.directory);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw new TypeError(error instanceof Error ? error.message : String(error));
|
|
80
36
|
}
|
|
81
|
-
if ("reference" in receipt)
|
|
82
|
-
return receipt.reference;
|
|
83
|
-
if (receipt.outcome.kind === "returned")
|
|
84
|
-
return receipt.outcome.result;
|
|
85
|
-
throw new Error(receipt.outcome.failure.kind === "failed"
|
|
86
|
-
? receipt.outcome.failure.diagnostic
|
|
87
|
-
: "Akuma body request parent is not born");
|
|
88
|
-
}
|
|
89
|
-
export async function requestBodyWait(input) {
|
|
90
|
-
const { directory, id = randomUUID(), ...claim } = input;
|
|
91
|
-
return await requestUpstream(directory, { ...claim, id, action: "akuma.wait" });
|
|
92
|
-
}
|
|
93
|
-
export async function requestBodyTell(input) {
|
|
94
|
-
const { directory, id = randomUUID(), ...claim } = input;
|
|
95
|
-
return await requestUpstream(directory, { ...claim, id, action: "akuma.tell" });
|
|
96
|
-
}
|
|
97
|
-
export async function requestBodyKill(input) {
|
|
98
|
-
const { directory, id = randomUUID(), ...claim } = input;
|
|
99
|
-
return await requestUpstream(directory, { ...claim, id, action: "akuma.kill" });
|
|
100
37
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
38
|
+
/** Normalizes the public carrier before a composition captures its immutable channel. */
|
|
39
|
+
export function libraryExecution(value) {
|
|
40
|
+
const context = valueRecord(value, "execution");
|
|
41
|
+
closed(context, ["channel"], "execution");
|
|
42
|
+
const channel = valueRecord(context.channel, "execution channel");
|
|
43
|
+
if (channel.kind === "local") {
|
|
44
|
+
closed(channel, ["kind"], "execution channel");
|
|
45
|
+
return localExecutionContext();
|
|
46
|
+
}
|
|
47
|
+
if (channel.kind === "body-request") {
|
|
48
|
+
closed(channel, ["directory", "kind"], "execution channel");
|
|
49
|
+
if (typeof channel.directory !== "string")
|
|
50
|
+
throw new TypeError("execution channel directory must be a string");
|
|
51
|
+
return bodyRequestExecution({ directory: channel.directory });
|
|
110
52
|
}
|
|
111
|
-
|
|
112
|
-
? receipt.reference
|
|
113
|
-
: receipt.outcome;
|
|
53
|
+
throw new TypeError("execution channel must be local or body-request");
|
|
114
54
|
}
|
|
115
|
-
export
|
|
116
|
-
|
|
55
|
+
export function libraryExecutionInput(input) {
|
|
56
|
+
const value = valueRecord(input, "Keiyaku.withExecution input");
|
|
57
|
+
closed(value, ["execution"], "Keiyaku.withExecution input");
|
|
58
|
+
if (value.execution === undefined)
|
|
59
|
+
throw new TypeError("Keiyaku.withExecution input requires execution");
|
|
60
|
+
return libraryExecution(value.execution);
|
|
117
61
|
}
|
|
118
|
-
export
|
|
119
|
-
return
|
|
62
|
+
export function executionChannel(context) {
|
|
63
|
+
return context?.channel ?? LOCAL_CHANNEL;
|
|
120
64
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type ResumeCoordinate, type Soul, type TellFact } from "./heart/index.js";
|
|
2
2
|
import type { AkumaPaths } from "./identity.js";
|
|
3
3
|
import { type ProviderAdapter, type TurnResult } from "./provider.js";
|
|
4
|
-
import
|
|
4
|
+
import type { AkumaCallRequestChildLaunch } from "./call-request.js";
|
|
5
|
+
import type { ErasedRequestCommand } from "./request-wire.js";
|
|
5
6
|
import { BodySupervisor } from "./body-supervisor.js";
|
|
6
7
|
import type { OwnedProcess } from "../runtime/proc/run.js";
|
|
7
8
|
export declare function turnRecipe(paths: AkumaPaths, soul: Soul): Promise<Readonly<{
|
|
@@ -25,8 +26,9 @@ export type DriveTurnInput = Readonly<{
|
|
|
25
26
|
call?: string;
|
|
26
27
|
launchTells: readonly TellFact[];
|
|
27
28
|
supervisor: BodySupervisor;
|
|
28
|
-
runtimeSpawn(launch:
|
|
29
|
-
upstream?:
|
|
29
|
+
runtimeSpawn(launch: AkumaCallRequestChildLaunch): Promise<OwnedProcess | void>;
|
|
30
|
+
upstream?: unknown;
|
|
31
|
+
commands: Readonly<Record<string, ErasedRequestCommand>>;
|
|
30
32
|
now(): string;
|
|
31
33
|
}>;
|
|
32
34
|
export declare function driveTurn(input: DriveTurnInput): Promise<(DrivenTurn & Readonly<{
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { abortableDelay } from "./abort.js";
|
|
2
|
+
/* eslint-disable max-lines-per-function -- Turn setup and consumption each preserve one ordered lifecycle transaction. */
|
|
2
3
|
import { appendActivity, beginTurn, breakBody, heartExists, readHeart, recordSession, recordTellDeliveries, recordTellReceipt, } from "./heart/index.js";
|
|
3
|
-
import { encodeAgentEvent } from "./provider.js";
|
|
4
|
+
import { encodeAgentEvent, } from "./provider.js";
|
|
4
5
|
import { BodyRequestPump } from "./request-serve.js";
|
|
5
6
|
import { CONTROL_RESPONSE_MS } from "./body-supervisor.js";
|
|
6
7
|
function serializeEffects() {
|
|
@@ -79,6 +80,7 @@ async function startTurnDrive(input) {
|
|
|
79
80
|
now: input.now,
|
|
80
81
|
spawn: input.runtimeSpawn,
|
|
81
82
|
...(input.upstream === undefined ? {} : { upstream: input.upstream }),
|
|
83
|
+
commands: input.commands,
|
|
82
84
|
signal: input.supervisor.signal,
|
|
83
85
|
});
|
|
84
86
|
const driveController = new AbortController();
|
|
@@ -101,14 +103,15 @@ async function startTurnDrive(input) {
|
|
|
101
103
|
signal: driveController.signal,
|
|
102
104
|
requests: { dir: requests.directory },
|
|
103
105
|
};
|
|
104
|
-
const
|
|
106
|
+
const attempt = session === undefined
|
|
105
107
|
? input.adapter.start({ ...driveInput, session: { kind: "fresh" } })
|
|
106
108
|
: input.adapter.resume({ ...driveInput, session: { kind: "resume", coordinate: session } });
|
|
109
|
+
const custodyFailure = observeFailure(attempt.closed);
|
|
107
110
|
try {
|
|
108
|
-
const selected = await Promise.race([
|
|
111
|
+
const selected = await Promise.race([attempt.result, requests.failure, custodyFailure]);
|
|
109
112
|
if (input.supervisor.signal.aborted) {
|
|
110
113
|
try {
|
|
111
|
-
const retirement = await retireProviderCustody(input, turn.sequence,
|
|
114
|
+
const retirement = await retireProviderCustody(input, turn.sequence, attempt);
|
|
112
115
|
await requests.close();
|
|
113
116
|
if (retirement.kind === "hung")
|
|
114
117
|
return retirement;
|
|
@@ -129,6 +132,8 @@ async function startTurnDrive(input) {
|
|
|
129
132
|
void selected.completion.then(() => requests.stopAdmission(), () => undefined);
|
|
130
133
|
return {
|
|
131
134
|
turnSequence: turn.sequence,
|
|
135
|
+
attempt,
|
|
136
|
+
custodyFailure,
|
|
132
137
|
drive: selected,
|
|
133
138
|
requests,
|
|
134
139
|
cwd,
|
|
@@ -138,21 +143,39 @@ async function startTurnDrive(input) {
|
|
|
138
143
|
};
|
|
139
144
|
}
|
|
140
145
|
catch (error) {
|
|
146
|
+
const retirement = await retireProviderCustody(input, turn.sequence, attempt);
|
|
147
|
+
if (retirement.kind === "hung") {
|
|
148
|
+
try {
|
|
149
|
+
await requests.close();
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
input.supervisor.signal.removeEventListener("abort", cancelDrive);
|
|
153
|
+
}
|
|
154
|
+
return retirement;
|
|
155
|
+
}
|
|
141
156
|
return await failedTurnSetup(input, turn.sequence, requests, cancelDrive, error);
|
|
142
157
|
}
|
|
143
158
|
}
|
|
144
|
-
async function retireProviderCustody(input, turnSequence,
|
|
159
|
+
async function retireProviderCustody(input, turnSequence, attempt) {
|
|
145
160
|
const dispose = async (operation) => await Promise.race([
|
|
146
|
-
operation().then(
|
|
161
|
+
operation().then(async () => {
|
|
162
|
+
try {
|
|
163
|
+
await attempt.closed;
|
|
164
|
+
return { kind: "retired" };
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
return { kind: "held", error };
|
|
168
|
+
}
|
|
169
|
+
}, (error) => ({ kind: "held", error })),
|
|
147
170
|
abortableDelay(CONTROL_RESPONSE_MS).then(() => ({
|
|
148
171
|
kind: "held",
|
|
149
172
|
error: new Error(`provider custody remained live after ${CONTROL_RESPONSE_MS}ms`),
|
|
150
173
|
})),
|
|
151
174
|
]);
|
|
152
|
-
let outcome = await dispose(
|
|
175
|
+
let outcome = await dispose(attempt.abort);
|
|
153
176
|
if (outcome.kind === "retired")
|
|
154
177
|
return outcome;
|
|
155
|
-
outcome = await dispose(
|
|
178
|
+
outcome = await dispose(attempt.forceDispose);
|
|
156
179
|
if (outcome.kind === "retired")
|
|
157
180
|
return outcome;
|
|
158
181
|
if (await heartExists(input.paths)) {
|
|
@@ -191,8 +214,11 @@ function pumpReceipts(writers) {
|
|
|
191
214
|
}
|
|
192
215
|
})();
|
|
193
216
|
}
|
|
217
|
+
function observeFailure(settlement) {
|
|
218
|
+
return settlement.then(() => new Promise(() => { }), (error) => Promise.reject(error));
|
|
219
|
+
}
|
|
194
220
|
function observeReceiptFailure(receiptPump) {
|
|
195
|
-
return receiptPump
|
|
221
|
+
return observeFailure(receiptPump);
|
|
196
222
|
}
|
|
197
223
|
function observeCompletionFailure(drive) {
|
|
198
224
|
return drive.completion.then(() => new Promise(() => { }), (error) => ({ kind: "completion-failed", error }));
|
|
@@ -226,7 +252,7 @@ async function submitPendingLiveTells(writers, pending, attempted, tellLive) {
|
|
|
226
252
|
}
|
|
227
253
|
async function stopActiveDrive(input, active) {
|
|
228
254
|
try {
|
|
229
|
-
const retirement = await retireProviderCustody(input, active.turnSequence, active.
|
|
255
|
+
const retirement = await retireProviderCustody(input, active.turnSequence, active.attempt);
|
|
230
256
|
await active.requests.close();
|
|
231
257
|
return retirement;
|
|
232
258
|
}
|
|
@@ -285,6 +311,7 @@ async function consumeTurnDrive(input, active) {
|
|
|
285
311
|
receiptFailure,
|
|
286
312
|
requests.failure,
|
|
287
313
|
completionFailure,
|
|
314
|
+
active.custodyFailure,
|
|
288
315
|
]);
|
|
289
316
|
if (next.kind === "completion-failed") {
|
|
290
317
|
requests.stopAdmission();
|
|
@@ -308,6 +335,7 @@ async function consumeTurnDrive(input, active) {
|
|
|
308
335
|
pending = iterator.next();
|
|
309
336
|
}
|
|
310
337
|
const result = await drive.completion;
|
|
338
|
+
await active.attempt.closed;
|
|
311
339
|
if (tellPump !== null)
|
|
312
340
|
await tellPump;
|
|
313
341
|
await writeWitness.drain();
|
|
@@ -320,7 +348,7 @@ async function consumeTurnDrive(input, active) {
|
|
|
320
348
|
const retirement = await stopActiveDrive(input, active);
|
|
321
349
|
return retirement.kind === "hung" ? retirement : { kind: "stopped" };
|
|
322
350
|
}
|
|
323
|
-
const retirement = await retireProviderCustody(input, turnSequence,
|
|
351
|
+
const retirement = await retireProviderCustody(input, turnSequence, active.attempt);
|
|
324
352
|
try {
|
|
325
353
|
await requests.close();
|
|
326
354
|
}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { type BodyLaunch } from "./akuma/body.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type WorldRoot } from "./world.js";
|
|
3
|
+
import { type FleetRequestPort } from "./library/fleet.js";
|
|
4
|
+
import { type ContractRequestPort } from "./library/contract-operations.js";
|
|
5
|
+
import { type TaskMutationRequestPort } from "./task/mutation.js";
|
|
3
6
|
type BodyProcessConfiguration = Readonly<{
|
|
4
7
|
home?: string;
|
|
5
8
|
gitPath?: string;
|
|
6
9
|
}>;
|
|
7
|
-
export declare function upstreamFor(launch: BodyLaunch, processConfiguration: BodyProcessConfiguration):
|
|
10
|
+
export declare function upstreamFor(launch: BodyLaunch, processConfiguration: BodyProcessConfiguration): Promise<FleetRequestPort & ContractRequestPort & TaskMutationRequestPort & Readonly<{
|
|
11
|
+
launchWorld(): WorldRoot;
|
|
12
|
+
}>>;
|
|
8
13
|
export {};
|
package/build/src/akuma-body.js
CHANGED
|
@@ -1,47 +1,45 @@
|
|
|
1
1
|
import { LEASH_HELD_EXIT, runAkumaBody } from "./akuma/body.js";
|
|
2
|
+
import { akumaCallRequestCommands } from "./akuma/call-request.js";
|
|
2
3
|
import { worldRootForAkumaPaths } from "./akuma/identity.js";
|
|
4
|
+
import { World } from "./world.js";
|
|
3
5
|
import { executeKillAkuma, executeTellAkuma, executeWaitAkuma } from "./library/fleet.js";
|
|
6
|
+
import { fleetRequestCommands } from "./library/fleet.js";
|
|
4
7
|
import { requireBranchesToBeUpToDateFrom, worktreeHooksFrom } from "./library/configuration.js";
|
|
5
|
-
import { executeForwardedDeliver, executeForwardedReview } from "./library/contract.js";
|
|
8
|
+
import { contractRequestCommands, executeForwardedAudit, executeForwardedDeliver, executeForwardedReview, } from "./library/contract-operations.js";
|
|
6
9
|
import { Repo } from "./library/repo.js";
|
|
7
10
|
import { settings } from "./settings.js";
|
|
8
|
-
import { executeTaskMutation } from "./task/mutation.js";
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
+
import { executeTaskMutation, taskMutationRequestCommands } from "./task/mutation.js";
|
|
12
|
+
async function contractDependencies(repoRoot, processConfiguration) {
|
|
13
|
+
const repo = await Repo.at({
|
|
14
|
+
path: repoRoot,
|
|
15
|
+
...(processConfiguration.gitPath === undefined ? {} : { gitPath: processConfiguration.gitPath }),
|
|
16
|
+
});
|
|
17
|
+
if (repo.root !== repoRoot)
|
|
18
|
+
throw new TypeError("forwarded Contract repoRoot must equal the canonical primary worktree");
|
|
19
|
+
const world = await World.prove(repo.root);
|
|
20
|
+
const configuration = await settings({
|
|
21
|
+
root: world,
|
|
22
|
+
...(processConfiguration.home === undefined ? {} : { home: processConfiguration.home }),
|
|
23
|
+
});
|
|
24
|
+
return [repo, configuration];
|
|
25
|
+
}
|
|
26
|
+
function contractUpstream(processConfiguration) {
|
|
11
27
|
return {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
recordedAt: input.recordedAt,
|
|
25
|
-
signal: input.signal,
|
|
26
|
-
}),
|
|
27
|
-
kill: async (input) => {
|
|
28
|
-
const result = await executeKillAkuma({ path, ids: input.targets, signal: input.signal });
|
|
29
|
-
return {
|
|
30
|
-
result,
|
|
31
|
-
service: result.results.map(({ id, evidence }) => ({ id, evidence })),
|
|
32
|
-
};
|
|
28
|
+
audit: async (input) => {
|
|
29
|
+
const [repo, configuration] = await contractDependencies(input.repoRoot, processConfiguration);
|
|
30
|
+
return await executeForwardedAudit({
|
|
31
|
+
repo,
|
|
32
|
+
contractId: input.contractId,
|
|
33
|
+
requester: input.requester,
|
|
34
|
+
includeDirty: input.includeDirty,
|
|
35
|
+
showDiff: input.showDiff,
|
|
36
|
+
requireBranchesToBeUpToDate: requireBranchesToBeUpToDateFrom({ settings: configuration }),
|
|
37
|
+
hooks: worktreeHooksFrom({ settings: configuration }),
|
|
38
|
+
signal: input.signal,
|
|
39
|
+
});
|
|
33
40
|
},
|
|
34
41
|
deliver: async (input) => {
|
|
35
|
-
const [repo, configuration] = await
|
|
36
|
-
Repo.at({
|
|
37
|
-
path: input.repoRoot,
|
|
38
|
-
...(processConfiguration.gitPath === undefined ? {} : { gitPath: processConfiguration.gitPath }),
|
|
39
|
-
}),
|
|
40
|
-
settings({
|
|
41
|
-
root: input.repoRoot,
|
|
42
|
-
...(processConfiguration.home === undefined ? {} : { home: processConfiguration.home }),
|
|
43
|
-
}),
|
|
44
|
-
]);
|
|
42
|
+
const [repo, configuration] = await contractDependencies(input.repoRoot, processConfiguration);
|
|
45
43
|
return await executeForwardedDeliver({
|
|
46
44
|
repo,
|
|
47
45
|
contractId: input.contractId,
|
|
@@ -55,16 +53,7 @@ export function upstreamFor(launch, processConfiguration) {
|
|
|
55
53
|
});
|
|
56
54
|
},
|
|
57
55
|
review: async (input) => {
|
|
58
|
-
const [repo, configuration] = await
|
|
59
|
-
Repo.at({
|
|
60
|
-
path: input.repoRoot,
|
|
61
|
-
...(processConfiguration.gitPath === undefined ? {} : { gitPath: processConfiguration.gitPath }),
|
|
62
|
-
}),
|
|
63
|
-
settings({
|
|
64
|
-
root: input.repoRoot,
|
|
65
|
-
...(processConfiguration.home === undefined ? {} : { home: processConfiguration.home }),
|
|
66
|
-
}),
|
|
67
|
-
]);
|
|
56
|
+
const [repo, configuration] = await contractDependencies(input.repoRoot, processConfiguration);
|
|
68
57
|
return await executeForwardedReview({
|
|
69
58
|
repo,
|
|
70
59
|
contractId: input.contractId,
|
|
@@ -74,6 +63,32 @@ export function upstreamFor(launch, processConfiguration) {
|
|
|
74
63
|
hooks: worktreeHooksFrom({ settings: configuration }),
|
|
75
64
|
});
|
|
76
65
|
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export async function upstreamFor(launch, processConfiguration) {
|
|
69
|
+
const world = await World.prove(worldRootForAkumaPaths(launch.paths));
|
|
70
|
+
return {
|
|
71
|
+
launchWorld: () => world,
|
|
72
|
+
...contractUpstream(processConfiguration),
|
|
73
|
+
wait: async (input) => await executeWaitAkuma({
|
|
74
|
+
path: world,
|
|
75
|
+
ids: input.targets,
|
|
76
|
+
completion: input.completion,
|
|
77
|
+
...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
|
|
78
|
+
signal: input.signal,
|
|
79
|
+
}),
|
|
80
|
+
tell: async (input) => await executeTellAkuma({
|
|
81
|
+
path: world,
|
|
82
|
+
id: input.target,
|
|
83
|
+
body: input.body,
|
|
84
|
+
tellId: input.tellId,
|
|
85
|
+
recordedAt: input.recordedAt,
|
|
86
|
+
signal: input.signal,
|
|
87
|
+
}),
|
|
88
|
+
kill: async (input) => {
|
|
89
|
+
const result = await executeKillAkuma({ path: world, ids: input.targets, signal: input.signal });
|
|
90
|
+
return result;
|
|
91
|
+
},
|
|
77
92
|
task: async (input) => await executeTaskMutation({
|
|
78
93
|
world: input.world,
|
|
79
94
|
request: input.request,
|
|
@@ -95,5 +110,12 @@ const configuration = {
|
|
|
95
110
|
...(mappedHome === undefined || mappedHome.length === 0 ? {} : { home: mappedHome }),
|
|
96
111
|
...(mappedGitPath === undefined ? {} : { gitPath: mappedGitPath }),
|
|
97
112
|
};
|
|
98
|
-
|
|
113
|
+
const upstream = await upstreamFor(launch, configuration);
|
|
114
|
+
const commands = {
|
|
115
|
+
...akumaCallRequestCommands(),
|
|
116
|
+
...fleetRequestCommands(),
|
|
117
|
+
...contractRequestCommands(),
|
|
118
|
+
...taskMutationRequestCommands(),
|
|
119
|
+
};
|
|
120
|
+
if ((await runAkumaBody(launch, upstream, commands)) === "held")
|
|
99
121
|
process.exitCode = LEASH_HELD_EXIT;
|
package/build/src/body/amend.js
CHANGED
|
@@ -22,10 +22,11 @@ function operationSections(document) {
|
|
|
22
22
|
refusal("amend operations contain bytes outside H2 sections");
|
|
23
23
|
}
|
|
24
24
|
return sections(document).map((section) => {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const title = section.title.trim();
|
|
26
|
+
const match = /^(Add|Update|Replace|Append|Remove):[ ]+(.+)$/.exec(title);
|
|
27
|
+
return match
|
|
28
|
+
? { kind: match[1], target: match[2].trim(), section }
|
|
29
|
+
: { kind: "Set", target: title, section };
|
|
29
30
|
});
|
|
30
31
|
}
|
|
31
32
|
function prose(document, section, label) {
|
|
@@ -112,7 +113,7 @@ function completeBody(body) {
|
|
|
112
113
|
objective: body.objective,
|
|
113
114
|
design: body.design,
|
|
114
115
|
region: body.region,
|
|
115
|
-
criteria: body.criteria
|
|
116
|
+
criteria: body.criteria,
|
|
116
117
|
verification: body.verification,
|
|
117
118
|
extensions: body.extensions.filter((extension) => extension !== undefined),
|
|
118
119
|
};
|
|
@@ -137,15 +138,6 @@ function alteredText(body, target, value) {
|
|
|
137
138
|
}
|
|
138
139
|
function applyRemove(body, operation, document) {
|
|
139
140
|
requireEmpty(document, operation.section);
|
|
140
|
-
if (operation.target.startsWith("Criterion ")) {
|
|
141
|
-
const title = operation.target.slice("Criterion ".length);
|
|
142
|
-
const index = criterionIndex(body, title);
|
|
143
|
-
if (index < 0)
|
|
144
|
-
refusal(`unknown criterion '${title}'`);
|
|
145
|
-
body.criteria[index] = undefined;
|
|
146
|
-
body.criterionIndexes.delete(normalizeTitle(title));
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
141
|
const index = extensionIndex(body, operation.target);
|
|
150
142
|
if (index < 0)
|
|
151
143
|
refusal(`unknown extension '${operation.target}'`);
|
|
@@ -236,6 +228,13 @@ function applyReplace(body, operation, document) {
|
|
|
236
228
|
const extension = body.extensions[index];
|
|
237
229
|
body.extensions[index] = { ...extension, content: prose(document, operation.section, "extension") };
|
|
238
230
|
}
|
|
231
|
+
function applySet(body, operation, document) {
|
|
232
|
+
if (contractSectionName(operation.target) !== null || extensionIndex(body, operation.target) >= 0) {
|
|
233
|
+
applyReplace(body, operation, document);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
applyAdd(body, operation, document);
|
|
237
|
+
}
|
|
239
238
|
function applyOperation(body, operation, document) {
|
|
240
239
|
switch (operation.kind) {
|
|
241
240
|
case "Add":
|
|
@@ -253,13 +252,13 @@ function applyOperation(body, operation, document) {
|
|
|
253
252
|
case "Remove":
|
|
254
253
|
applyRemove(body, operation, document);
|
|
255
254
|
return;
|
|
255
|
+
case "Set":
|
|
256
|
+
applySet(body, operation, document);
|
|
257
|
+
return;
|
|
256
258
|
}
|
|
257
259
|
}
|
|
258
260
|
function operationKey(operation) {
|
|
259
|
-
|
|
260
|
-
? `Criterion ${normalizeTitle(operation.target.slice("Criterion ".length))}`
|
|
261
|
-
: operation.target;
|
|
262
|
-
return `${operation.kind}:${target}`;
|
|
261
|
+
return `${operation.kind}:${operation.target}`;
|
|
263
262
|
}
|
|
264
263
|
function apply(source, current) {
|
|
265
264
|
const document = parseToAST(source);
|
|
@@ -274,7 +273,7 @@ function apply(source, current) {
|
|
|
274
273
|
if (seen.has(key))
|
|
275
274
|
refusal(`duplicate amend operation '${key}'`);
|
|
276
275
|
seen.add(key);
|
|
277
|
-
changed.add(normalizeTitle(operation.target
|
|
276
|
+
changed.add(normalizeTitle(operation.target));
|
|
278
277
|
applyOperation(body, operation, document);
|
|
279
278
|
}
|
|
280
279
|
return { body: completeBody(body), changed };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AmendResult, type AuditReport, type BindResult, type ContractId, type Delivery, type MutationResult, type Review } from "../index.js";
|
|
2
2
|
import type { AcceptedAbandonResult, AcceptedAmendResult, AcceptedArcResult, AcceptedAuditResult, AcceptedBindResult, AcceptedDeliverResult, AcceptedResult, AcceptedReviewResult, InvocationResult } from "./result.js";
|
|
3
|
-
type MutationObservation = Pick<MutationResult<unknown>, "facts" | "head" | "
|
|
3
|
+
type MutationObservation = Pick<MutationResult<unknown>, "facts" | "head" | "lags" | "settlementLags" | "recoverySnapshot">;
|
|
4
4
|
type MutationCallOptions = Readonly<{
|
|
5
5
|
coordinate?: ContractId;
|
|
6
6
|
projectRefusal?: (refusal: unknown) => unknown;
|