@astrosheep/keiyaku 4.5.11 → 4.5.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/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +135 -377
- package/build/integrations/pi/keiyaku.ts +11 -116
- package/build/src/akuma/akuma-errors.d.ts +1 -0
- package/build/src/akuma/akuma-errors.js +1 -0
- package/build/src/akuma/akuma-handle.d.ts +1 -0
- package/build/src/akuma/akuma-handle.js +6 -7
- package/build/src/akuma/akuma-product.d.ts +6 -8
- package/build/src/akuma/akuma-product.js +141 -57
- package/build/src/akuma/akuma.d.ts +5 -7
- package/build/src/akuma/akuma.js +1 -22
- package/build/src/akuma/archetype.d.ts +6 -5
- package/build/src/akuma/archetype.js +137 -38
- package/build/src/akuma/body.d.ts +5 -5
- package/build/src/akuma/body.js +223 -63
- package/build/src/akuma/call-input.d.ts +4 -0
- package/build/src/akuma/call-input.js +21 -0
- package/build/src/akuma/call-request.d.ts +5 -8
- package/build/src/akuma/call-request.js +28 -73
- package/build/src/akuma/fleet-execution.d.ts +26 -0
- package/build/src/akuma/fleet-execution.js +109 -0
- package/build/src/{library/fleet-result.d.ts → akuma/fleet-observation.d.ts} +13 -57
- package/build/src/{library/fleet-result.js → akuma/fleet-observation.js} +4 -25
- package/build/src/akuma/fleet-request.d.ts +122 -0
- package/build/src/akuma/fleet-request.js +168 -0
- package/build/src/akuma/heart/facts.d.ts +23 -0
- package/build/src/akuma/heart/facts.js +7 -0
- package/build/src/akuma/heart/index.d.ts +43 -4
- package/build/src/akuma/heart/index.js +107 -7
- package/build/src/akuma/heart/request-authority.d.ts +2 -0
- package/build/src/akuma/heart/request-authority.js +28 -3
- package/build/src/akuma/heart/request-rows.d.ts +2 -0
- package/build/src/akuma/heart/request-rows.js +24 -5
- package/build/src/akuma/heart/rows.d.ts +4 -1
- package/build/src/akuma/heart/rows.js +46 -19
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +28 -6
- package/build/src/akuma/heart/storage.d.ts +1 -1
- package/build/src/akuma/heart/tells.d.ts +29 -0
- package/build/src/akuma/heart/tells.js +136 -5
- package/build/src/akuma/heart/timeline.js +9 -3
- package/build/src/akuma/projection-read.js +36 -3
- package/build/src/akuma/projection.js +3 -4
- package/build/src/akuma/provider.d.ts +4 -0
- package/build/src/akuma/provider.js +56 -3
- package/build/src/akuma/providers/claude/index.js +3 -0
- package/build/src/akuma/providers/codex-app-server/index.js +14 -12
- package/build/src/akuma/providers/pi/index.js +7 -1
- package/build/src/akuma/publication.js +65 -49
- package/build/src/akuma/request-lifecycle.d.ts +5 -4
- package/build/src/akuma/request-lifecycle.js +29 -16
- package/build/src/akuma/request-rendezvous.d.ts +15 -12
- package/build/src/akuma/request-rendezvous.js +80 -51
- package/build/src/akuma/request-serve.d.ts +1 -2
- package/build/src/akuma/request-serve.js +94 -39
- package/build/src/akuma/request-wire.d.ts +57 -26
- package/build/src/akuma/request-wire.js +64 -25
- package/build/src/akuma/turn-drive.d.ts +5 -4
- package/build/src/akuma/turn-drive.js +27 -11
- package/build/src/akuma-body.d.ts +4 -6
- package/build/src/akuma-body.js +19 -17
- package/build/src/bounded-list.d.ts +8 -0
- package/build/src/bounded-list.js +14 -0
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +1 -0
- package/build/src/cli/commands/akuma-invoke.js +1 -25
- package/build/src/cli/commands/contract-help.d.ts +5 -2
- package/build/src/cli/commands/contract-help.js +62 -12
- package/build/src/cli/commands/contract-invoke.d.ts +5 -0
- package/build/src/cli/commands/contract-invoke.js +26 -1
- package/build/src/cli/commands/contract.js +50 -18
- package/build/src/cli/commands/task-invoke.js +10 -2
- package/build/src/cli/commands/task-query.js +3 -4
- package/build/src/cli/coordinates.d.ts +13 -0
- package/build/src/cli/coordinates.js +38 -24
- package/build/src/cli/draft.d.ts +1 -1
- package/build/src/cli/invoke.js +14 -1
- package/build/src/cli/render/akuma-activity.d.ts +0 -1
- package/build/src/cli/render/akuma-activity.js +5 -38
- package/build/src/cli/render/akuma.js +4 -1
- package/build/src/cli/render/audit.js +4 -1
- package/build/src/cli/render/catalog.js +13 -39
- package/build/src/cli/render/contract.js +4 -14
- package/build/src/cli/render/kanshi-akuma.js +3 -8
- package/build/src/cli/render/kanshi.js +8 -34
- package/build/src/cli/render/nuke.js +7 -3
- package/build/src/cli/render/receipt.d.ts +1 -0
- package/build/src/cli/render/receipt.js +8 -0
- package/build/src/cli/render/refusal.js +4 -3
- package/build/src/cli/render/task.js +4 -37
- package/build/src/cli/render/terminal.d.ts +2 -6
- package/build/src/cli/render/terminal.js +4 -9
- package/build/src/cli/result.d.ts +2 -1
- package/build/src/contract-guidance.js +13 -3
- package/build/src/contract-worktree.d.ts +1 -0
- package/build/src/contract-worktree.js +26 -2
- package/build/src/core/facts/codec.d.ts +2 -1
- package/build/src/core/facts/codec.js +3 -0
- package/build/src/core/facts/gate.d.ts +2 -1
- package/build/src/core/facts/gate.js +63 -0
- package/build/src/core/verbs/abandon.d.ts +2 -1
- package/build/src/core/verbs/abandon.js +16 -0
- package/build/src/core/verbs/amend.d.ts +2 -1
- package/build/src/core/verbs/amend.js +20 -0
- package/build/src/core/verbs/arc.d.ts +2 -1
- package/build/src/core/verbs/arc.js +16 -0
- package/build/src/core/verbs/attestation.d.ts +2 -1
- package/build/src/core/verbs/attestation.js +16 -0
- package/build/src/core/verbs/bind.d.ts +2 -1
- package/build/src/core/verbs/bind.js +16 -0
- package/build/src/core/verbs/deliver.d.ts +2 -1
- package/build/src/core/verbs/deliver.js +16 -0
- package/build/src/core/verbs/placement.d.ts +2 -1
- package/build/src/core/verbs/placement.js +58 -1
- package/build/src/dispatch/association.d.ts +13 -0
- package/build/src/dispatch/association.js +20 -0
- package/build/src/dispatch/index.d.ts +6 -0
- package/build/src/dispatch/index.js +27 -3
- package/build/src/git/hooks.d.ts +9 -1
- package/build/src/git/hooks.js +79 -1
- package/build/src/git/nuke.d.ts +2 -1
- package/build/src/git/nuke.js +6 -11
- package/build/src/git/private-state-seat.d.ts +26 -1
- package/build/src/git/private-state-seat.js +78 -13
- package/build/src/git/process.d.ts +2 -0
- package/build/src/git/reconcile.d.ts +1 -2
- package/build/src/git/reconcile.js +0 -6
- package/build/src/git/repository.d.ts +0 -2
- package/build/src/git/repository.js +27 -25
- package/build/src/git/result-codec.d.ts +29 -0
- package/build/src/git/result-codec.js +306 -0
- package/build/src/git/target-placement.js +2 -8
- package/build/src/git/workspace.d.ts +2 -0
- package/build/src/git/workspace.js +4 -0
- package/build/src/index.d.ts +1 -0
- package/build/src/kanshi/fleet.js +1 -1
- package/build/src/kanshi/read.js +55 -28
- package/build/src/kanshi/report.d.ts +4 -3
- package/build/src/kanshi/select.js +14 -1
- package/build/src/library/address.d.ts +1 -0
- package/build/src/library/address.js +4 -7
- package/build/src/library/akuma-creation.d.ts +5 -3
- package/build/src/library/akuma-creation.js +90 -33
- package/build/src/library/audit.js +2 -1
- package/build/src/library/catalog.d.ts +10 -2
- package/build/src/library/catalog.js +65 -25
- package/build/src/library/composition.d.ts +1 -0
- package/build/src/library/composition.js +1 -0
- package/build/src/library/configuration.d.ts +4 -21
- package/build/src/library/configuration.js +2 -158
- package/build/src/library/continuation.d.ts +20 -1
- package/build/src/library/continuation.js +36 -0
- package/build/src/library/contract-bind.d.ts +1 -0
- package/build/src/library/contract-bind.js +16 -5
- package/build/src/library/contract-forwarding.d.ts +2 -2
- package/build/src/library/contract-forwarding.js +18 -4
- package/build/src/library/contract-handle.js +4 -3
- package/build/src/library/contract-operations.d.ts +5 -9
- package/build/src/library/contract-operations.js +34 -47
- package/build/src/library/contract.d.ts +11 -2
- package/build/src/library/contract.js +21 -1
- package/build/src/library/delivery.d.ts +4 -1
- package/build/src/library/delivery.js +47 -0
- package/build/src/library/fleet.d.ts +4 -136
- package/build/src/library/fleet.js +31 -315
- package/build/src/library/keiyaku.d.ts +7 -3
- package/build/src/library/keiyaku.js +1 -0
- package/build/src/library/mutation.d.ts +431 -3
- package/build/src/library/mutation.js +192 -19
- package/build/src/library/nuke.d.ts +7 -1
- package/build/src/library/nuke.js +18 -4
- package/build/src/library/reconcile.d.ts +14 -0
- package/build/src/library/reconcile.js +22 -8
- package/build/src/library/refusal.d.ts +9 -1
- package/build/src/library/refusal.js +76 -0
- package/build/src/library/region.d.ts +0 -8
- package/build/src/library/region.js +1 -29
- package/build/src/library/result-codec.d.ts +2 -0
- package/build/src/library/result-codec.js +12 -0
- package/build/src/markdown/lex.js +9 -2
- package/build/src/markdown/types.d.ts +2 -1
- package/build/src/markdown/types.js +3 -1
- package/build/src/plugin/akuma-signals.d.ts +12 -0
- package/build/src/plugin/akuma-signals.js +14 -0
- package/build/src/plugin/public.d.ts +51 -0
- package/build/src/plugin/public.js +1 -0
- package/build/src/plugin/runtime.d.ts +14 -0
- package/build/src/plugin/runtime.js +357 -0
- package/build/src/protocol/amend.js +3 -3
- package/build/src/protocol/attempt.d.ts +2 -1
- package/build/src/protocol/attempt.js +1 -1
- package/build/src/protocol/audit.d.ts +1 -1
- package/build/src/protocol/audit.js +1 -1
- package/build/src/protocol/bind.d.ts +3 -1
- package/build/src/protocol/bind.js +26 -0
- package/build/src/protocol/completion.js +0 -1
- package/build/src/protocol/deliver.d.ts +1 -1
- package/build/src/protocol/deliver.js +136 -57
- package/build/src/protocol/intent.d.ts +0 -1
- package/build/src/protocol/intent.js +0 -1
- package/build/src/protocol/operations.d.ts +9 -2
- package/build/src/protocol/operations.js +16 -1
- package/build/src/protocol/outcome.d.ts +3 -0
- package/build/src/protocol/outcome.js +17 -1
- package/build/src/protocol/placement.js +10 -3
- package/build/src/protocol/read/status.d.ts +8 -0
- package/build/src/protocol/read/status.js +49 -0
- package/build/src/protocol/reintegrate.js +10 -3
- package/build/src/protocol/result-codec.d.ts +22 -0
- package/build/src/protocol/result-codec.js +442 -0
- package/build/src/protocol/review.d.ts +1 -1
- package/build/src/protocol/review.js +81 -46
- package/build/src/protocol/run.d.ts +22 -2
- package/build/src/protocol/run.js +119 -29
- package/build/src/runtime/proc/lifecycle.js +1 -1
- package/build/src/runtime/proc/line-rpc.d.ts +7 -1
- package/build/src/runtime/proc/line-rpc.js +49 -9
- package/build/src/runtime/proc/run.d.ts +0 -1
- package/build/src/runtime/proc/run.js +1 -11
- package/build/src/runtime/proc/termination.d.ts +1 -0
- package/build/src/runtime/proc/termination.js +63 -18
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settings.d.ts +10 -0
- package/build/src/settings.js +88 -2
- package/build/src/settlement/result-codec.d.ts +2 -0
- package/build/src/settlement/result-codec.js +56 -0
- package/build/src/settlement/settle.d.ts +5 -12
- package/build/src/settlement/settle.js +60 -55
- package/build/src/task/board.d.ts +3 -0
- package/build/src/task/board.js +22 -4
- package/build/src/task/catalog.d.ts +13 -2
- package/build/src/task/catalog.js +59 -5
- package/build/src/task/compose.d.ts +4 -2
- package/build/src/task/compose.js +56 -30
- package/build/src/task/created-observation.d.ts +39 -0
- package/build/src/task/created-observation.js +26 -0
- package/build/src/task/identity.d.ts +6 -0
- package/build/src/task/identity.js +48 -7
- package/build/src/task/index.d.ts +4 -3
- package/build/src/task/index.js +19 -16
- package/build/src/task/input.d.ts +3 -1
- package/build/src/task/input.js +7 -4
- package/build/src/task/lifecycle-operations.d.ts +6 -0
- package/build/src/task/lifecycle-operations.js +116 -0
- package/build/src/task/mutation-result.d.ts +762 -20
- package/build/src/task/mutation-result.js +34 -9
- package/build/src/task/mutation.d.ts +4 -9
- package/build/src/task/mutation.js +17 -52
- package/build/src/task/operation-types.d.ts +114 -0
- package/build/src/task/operation-types.js +1 -0
- package/build/src/task/operations.d.ts +6 -113
- package/build/src/task/operations.js +75 -117
- package/build/src/task/query.d.ts +8 -11
- package/build/src/task/query.js +7 -14
- package/build/src/task/store.d.ts +11 -1
- package/build/src/task/store.js +169 -55
- package/build/src/task/view.d.ts +4 -0
- package/build/src/task/view.js +7 -0
- package/build/src/verification/declaration.d.ts +1 -0
- package/build/src/verification/declaration.js +18 -1
- package/build/src/verification/execution.d.ts +0 -1
- package/build/src/verification/execution.js +5 -5
- package/build/src/world.d.ts +0 -2
- package/build/src/world.js +3 -7
- package/package.json +17 -5
- package/build/src/cli/square-edge.d.ts +0 -7
- package/build/src/cli/square-edge.js +0 -159
- package/build/src/git/ref-migration.d.ts +0 -22
- package/build/src/git/ref-migration.js +0 -55
- package/build/src/library/contract-forwarding-reconciliation-result.d.ts +0 -102
- package/build/src/library/contract-forwarding-reconciliation-result.js +0 -92
- package/build/src/library/contract-forwarding-result.d.ts +0 -4270
- package/build/src/library/contract-forwarding-result.js +0 -521
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { pluginRuntime } from "./runtime.js";
|
|
2
|
+
export async function emitCalledPluginSignal(input) {
|
|
3
|
+
const runtime = await pluginRuntime({
|
|
4
|
+
world: input.world,
|
|
5
|
+
...(input.settings === undefined ? {} : { settings: input.settings }),
|
|
6
|
+
reportDiagnostic: input.reportDiagnostic,
|
|
7
|
+
});
|
|
8
|
+
runtime.emit({
|
|
9
|
+
kind: "akuma.called",
|
|
10
|
+
akumaId: input.akumaId,
|
|
11
|
+
...(input.callerAkumaId === undefined ? {} : { callerAkumaId: input.callerAkumaId }),
|
|
12
|
+
...(input.contractId === undefined ? {} : { contractId: input.contractId }),
|
|
13
|
+
}, input.reportDiagnostic);
|
|
14
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { WorldRoot } from "../world.js";
|
|
2
|
+
export type PluginManifest = Readonly<{
|
|
3
|
+
id: string;
|
|
4
|
+
apiVersion: 1;
|
|
5
|
+
writablePaths?: readonly Readonly<{
|
|
6
|
+
name: string;
|
|
7
|
+
path: string;
|
|
8
|
+
}>[];
|
|
9
|
+
}>;
|
|
10
|
+
export type PluginOutcome = Readonly<{
|
|
11
|
+
kind: "answered";
|
|
12
|
+
text: string;
|
|
13
|
+
}> | Readonly<{
|
|
14
|
+
kind: "failed";
|
|
15
|
+
reason: string;
|
|
16
|
+
}>;
|
|
17
|
+
export type PluginSignalMap = Readonly<{
|
|
18
|
+
"akuma.called": Readonly<{
|
|
19
|
+
akumaId: string;
|
|
20
|
+
callerAkumaId?: string;
|
|
21
|
+
contractId?: string;
|
|
22
|
+
}>;
|
|
23
|
+
"akuma.turn-outcome": Readonly<{
|
|
24
|
+
akumaId: string;
|
|
25
|
+
turnSequence: number;
|
|
26
|
+
outcome: PluginOutcome;
|
|
27
|
+
contractId?: string;
|
|
28
|
+
}>;
|
|
29
|
+
}>;
|
|
30
|
+
export type PluginSignal = {
|
|
31
|
+
[K in keyof PluginSignalMap]: Readonly<{
|
|
32
|
+
kind: K;
|
|
33
|
+
}> & PluginSignalMap[K];
|
|
34
|
+
}[keyof PluginSignalMap];
|
|
35
|
+
export type PluginHooks = Readonly<{
|
|
36
|
+
[K in keyof PluginSignalMap]?: (signal: Readonly<{
|
|
37
|
+
kind: K;
|
|
38
|
+
}> & PluginSignalMap[K]) => Promise<void> | void;
|
|
39
|
+
}>;
|
|
40
|
+
export type PluginContext = Readonly<{
|
|
41
|
+
world: WorldRoot;
|
|
42
|
+
config: unknown;
|
|
43
|
+
writablePath(name: string): string;
|
|
44
|
+
}>;
|
|
45
|
+
export type KeiyakuPlugin = Readonly<{
|
|
46
|
+
manifest: PluginManifest;
|
|
47
|
+
activate(context: PluginContext): Promise<PluginInstance> | PluginInstance;
|
|
48
|
+
}>;
|
|
49
|
+
export type PluginInstance = Readonly<{
|
|
50
|
+
signals?: PluginHooks;
|
|
51
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Settings } from "../settings.js";
|
|
2
|
+
import type { WorldRoot } from "../world.js";
|
|
3
|
+
import type { PluginSignal } from "./public.js";
|
|
4
|
+
type PluginDiagnostic = (diagnostic: string) => void;
|
|
5
|
+
type PluginRuntimeInput = Readonly<{
|
|
6
|
+
world: WorldRoot;
|
|
7
|
+
settings?: Settings;
|
|
8
|
+
reportDiagnostic?: PluginDiagnostic;
|
|
9
|
+
}>;
|
|
10
|
+
export type PluginRuntime = Readonly<{
|
|
11
|
+
emit(signal: PluginSignal, reportDiagnostic?: PluginDiagnostic): Promise<void>;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function pluginRuntime(input: PluginRuntimeInput): Promise<PluginRuntime>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { lstat, mkdir, realpath } from "node:fs/promises";
|
|
2
|
+
import { registerHooks } from "node:module";
|
|
3
|
+
import { isAbsolute, join, posix, relative, sep } from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { settings } from "../settings.js";
|
|
6
|
+
const DIAGNOSTIC_LIMIT = 500;
|
|
7
|
+
const PLUGIN_NAMESPACE = "plugins";
|
|
8
|
+
const SQUARE_PLUGIN_PACKAGE = "@astrosheep/keiyaku-plugin-square";
|
|
9
|
+
const BUILTIN_PLUGINS = Object.freeze([
|
|
10
|
+
Object.freeze({ id: "square", package: SQUARE_PLUGIN_PACKAGE, config: undefined }),
|
|
11
|
+
]);
|
|
12
|
+
const PROCESS_RUNTIMES = new Map();
|
|
13
|
+
function object(value) {
|
|
14
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function message(error) {
|
|
17
|
+
return (error instanceof Error ? error.message : String(error)).slice(0, DIAGNOSTIC_LIMIT);
|
|
18
|
+
}
|
|
19
|
+
function diagnostic(report, subject, stage, error) {
|
|
20
|
+
if (report === undefined)
|
|
21
|
+
return;
|
|
22
|
+
try {
|
|
23
|
+
report(`plugin ${subject} ${stage}: ${message(error)}`.slice(0, DIAGNOSTIC_LIMIT));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Diagnostics are optional side effects too.
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function selectedEntry(entry, report) {
|
|
30
|
+
if (entry.name.trim().length === 0) {
|
|
31
|
+
diagnostic(report, "<unnamed>", "selection", new TypeError("plugin setting name must be nonblank"));
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (!object(entry.value)) {
|
|
35
|
+
diagnostic(report, entry.name, "selection", new TypeError("plugin setting must be an object"));
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const names = Object.keys(entry.value);
|
|
39
|
+
if (!names.includes("package") || names.some((name) => !["package", "enabled", "config"].includes(name))) {
|
|
40
|
+
diagnostic(report, entry.name, "selection", new TypeError("plugin setting has unknown or missing fields"));
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const packageName = entry.value.package;
|
|
44
|
+
if (typeof packageName !== "string" || packageName.trim().length === 0) {
|
|
45
|
+
diagnostic(report, entry.name, "selection", new TypeError("plugin package must be a nonblank string"));
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (packageName !== packageName.trim()) {
|
|
49
|
+
diagnostic(report, entry.name, "selection", new TypeError("plugin package must not have surrounding whitespace"));
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const enabled = entry.value.enabled;
|
|
53
|
+
if (enabled !== undefined && typeof enabled !== "boolean") {
|
|
54
|
+
diagnostic(report, entry.name, "selection", new TypeError("plugin enabled must be a boolean"));
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
if (enabled === false)
|
|
58
|
+
return null;
|
|
59
|
+
return Object.freeze({ id: entry.name, package: packageName, config: entry.value.config });
|
|
60
|
+
}
|
|
61
|
+
function selectedPlugins(input, report) {
|
|
62
|
+
const view = input.namespace(PLUGIN_NAMESPACE);
|
|
63
|
+
if (view.kind === "failed") {
|
|
64
|
+
for (const failure of view.failures)
|
|
65
|
+
diagnostic(report, "settings", failure.scope, failure.diagnostic);
|
|
66
|
+
return BUILTIN_PLUGINS;
|
|
67
|
+
}
|
|
68
|
+
if (view.entries.length === 0)
|
|
69
|
+
return BUILTIN_PLUGINS;
|
|
70
|
+
const configured = new Map(view.entries
|
|
71
|
+
.map((entry) => [entry.name, selectedEntry(entry, report)])
|
|
72
|
+
.filter((entry) => entry[1] !== null));
|
|
73
|
+
const disabled = new Set(view.entries.filter((entry) => object(entry.value) && entry.value.enabled === false).map((entry) => entry.name));
|
|
74
|
+
const selected = [
|
|
75
|
+
...BUILTIN_PLUGINS.filter((entry) => !configured.has(entry.id) && !disabled.has(entry.id)),
|
|
76
|
+
...configured.values(),
|
|
77
|
+
]
|
|
78
|
+
.filter((entry) => entry !== null)
|
|
79
|
+
.sort((left, right) => left.id.localeCompare(right.id));
|
|
80
|
+
return Object.freeze(selected);
|
|
81
|
+
}
|
|
82
|
+
function manifest(value) {
|
|
83
|
+
if (!object(value))
|
|
84
|
+
throw new TypeError("plugin default export must be an object");
|
|
85
|
+
if (!object(value.manifest))
|
|
86
|
+
throw new TypeError("plugin manifest must be an object");
|
|
87
|
+
const candidate = value.manifest;
|
|
88
|
+
const names = Object.keys(candidate);
|
|
89
|
+
if (names.some((name) => !["id", "apiVersion", "writablePaths"].includes(name))) {
|
|
90
|
+
throw new TypeError("plugin manifest has unknown fields");
|
|
91
|
+
}
|
|
92
|
+
if (typeof candidate.id !== "string" || candidate.id.trim().length === 0) {
|
|
93
|
+
throw new TypeError("plugin manifest id must be nonblank");
|
|
94
|
+
}
|
|
95
|
+
if (candidate.apiVersion !== 1)
|
|
96
|
+
throw new TypeError("plugin apiVersion must equal 1");
|
|
97
|
+
if (candidate.writablePaths !== undefined && !Array.isArray(candidate.writablePaths)) {
|
|
98
|
+
throw new TypeError("plugin writablePaths must be an array");
|
|
99
|
+
}
|
|
100
|
+
if (typeof value.activate !== "function")
|
|
101
|
+
throw new TypeError("plugin activate must be a function");
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
function writablePathDeclaration(value, names) {
|
|
105
|
+
if (!object(value))
|
|
106
|
+
throw new TypeError("plugin writable path must be an object");
|
|
107
|
+
if (Object.keys(value).some((name) => name !== "name" && name !== "path")) {
|
|
108
|
+
throw new TypeError("plugin writable path has unknown fields");
|
|
109
|
+
}
|
|
110
|
+
if (typeof value.name !== "string" || value.name.trim().length === 0) {
|
|
111
|
+
throw new TypeError("plugin writable path name must be nonblank");
|
|
112
|
+
}
|
|
113
|
+
if (names.has(value.name))
|
|
114
|
+
throw new TypeError(`plugin writable path name is duplicated: ${value.name}`);
|
|
115
|
+
if (typeof value.path !== "string" || value.path.length === 0 || value.path.includes("\\")) {
|
|
116
|
+
throw new TypeError("plugin writable path must be a nonblank POSIX path");
|
|
117
|
+
}
|
|
118
|
+
if (posix.isAbsolute(value.path))
|
|
119
|
+
throw new TypeError("plugin writable path must be relative to the World");
|
|
120
|
+
const parts = value.path.split("/");
|
|
121
|
+
if (parts.some((part) => part.length === 0 || part === "." || part === ".." || part.toLowerCase() === ".keiyaku")) {
|
|
122
|
+
throw new TypeError("plugin writable path contains a reserved or traversal component");
|
|
123
|
+
}
|
|
124
|
+
names.add(value.name);
|
|
125
|
+
return Object.freeze({ name: value.name, parts: Object.freeze(parts) });
|
|
126
|
+
}
|
|
127
|
+
async function createTrustedPath(world, managementPath, declaration) {
|
|
128
|
+
let current = world;
|
|
129
|
+
for (const part of declaration.parts) {
|
|
130
|
+
current = join(current, part);
|
|
131
|
+
try {
|
|
132
|
+
await mkdir(current);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
if (error.code !== "EEXIST")
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
const entry = await lstat(current);
|
|
139
|
+
if (entry.isSymbolicLink())
|
|
140
|
+
throw new TypeError(`plugin writable path resolves through a symlink: ${current}`);
|
|
141
|
+
if (!entry.isDirectory())
|
|
142
|
+
throw new TypeError(`plugin writable path component is not a directory: ${current}`);
|
|
143
|
+
const resolved = await realpath(current);
|
|
144
|
+
const relation = relative(managementPath, resolved);
|
|
145
|
+
if (relation.length === 0 || (!isAbsolute(relation) && relation !== ".." && !relation.startsWith(`..${sep}`))) {
|
|
146
|
+
throw new TypeError(`plugin writable path resolves into Keiyaku management custody: ${current}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return current;
|
|
150
|
+
}
|
|
151
|
+
async function writablePaths(world, declarations) {
|
|
152
|
+
const names = new Set();
|
|
153
|
+
const paths = new Map();
|
|
154
|
+
const managementPath = await realpath(join(world, ".keiyaku"));
|
|
155
|
+
for (const value of declarations ?? []) {
|
|
156
|
+
const declaration = writablePathDeclaration(value, names);
|
|
157
|
+
paths.set(declaration.name, await createTrustedPath(world, managementPath, declaration));
|
|
158
|
+
}
|
|
159
|
+
return paths;
|
|
160
|
+
}
|
|
161
|
+
function handlers(pluginId, instance) {
|
|
162
|
+
if (!object(instance))
|
|
163
|
+
throw new TypeError("plugin activation must return an object");
|
|
164
|
+
if (Object.keys(instance).some((name) => name !== "signals"))
|
|
165
|
+
throw new TypeError("plugin instance has unknown fields");
|
|
166
|
+
if (instance.signals === undefined)
|
|
167
|
+
return [];
|
|
168
|
+
if (!object(instance.signals))
|
|
169
|
+
throw new TypeError("plugin signals must be an object");
|
|
170
|
+
const registered = [];
|
|
171
|
+
for (const [kind, handler] of Object.entries(instance.signals)) {
|
|
172
|
+
if (kind !== "akuma.called" && kind !== "akuma.turn-outcome") {
|
|
173
|
+
throw new TypeError(`plugin signal is unknown: ${kind}`);
|
|
174
|
+
}
|
|
175
|
+
if (typeof handler !== "function")
|
|
176
|
+
throw new TypeError(`plugin signal handler is not a function: ${kind}`);
|
|
177
|
+
registered.push({ pluginId, kind, handler });
|
|
178
|
+
}
|
|
179
|
+
return Object.freeze(registered);
|
|
180
|
+
}
|
|
181
|
+
function sourceUrl(world, packageName) {
|
|
182
|
+
if (packageName.startsWith("./")) {
|
|
183
|
+
const parts = packageName.slice(2).split("/");
|
|
184
|
+
if (parts.some((part) => part.length === 0 || part === "." || part === ".." || part.includes("\\"))) {
|
|
185
|
+
throw new TypeError("plugin source must be a World-relative POSIX path");
|
|
186
|
+
}
|
|
187
|
+
return new URL(packageName, pathToFileURL(`${world}/`)).href;
|
|
188
|
+
}
|
|
189
|
+
if (packageName.startsWith("/") || packageName.startsWith("file:") || packageName.startsWith("../")) {
|
|
190
|
+
throw new TypeError("plugin source must be a package or World-relative path");
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
async function importFromWorld(world, packageName) {
|
|
195
|
+
if (packageName === SQUARE_PLUGIN_PACKAGE)
|
|
196
|
+
return (await import(packageName));
|
|
197
|
+
const direct = sourceUrl(world, packageName);
|
|
198
|
+
if (direct !== null)
|
|
199
|
+
return (await import(direct));
|
|
200
|
+
const parentURL = pathToFileURL(join(world, "package.json")).href;
|
|
201
|
+
const request = `keiyaku-plugin:${encodeURIComponent(world)}:${encodeURIComponent(packageName)}`;
|
|
202
|
+
const hooks = registerHooks({
|
|
203
|
+
resolve(specifier, context, nextResolve) {
|
|
204
|
+
return specifier === request
|
|
205
|
+
? nextResolve(packageName, { ...context, parentURL })
|
|
206
|
+
: nextResolve(specifier, context);
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
try {
|
|
210
|
+
return (await import(request));
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
hooks.deregister();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async function activate(selected, world, activated, report, onStarted) {
|
|
217
|
+
let started = false;
|
|
218
|
+
const markStarted = () => {
|
|
219
|
+
if (started)
|
|
220
|
+
return;
|
|
221
|
+
started = true;
|
|
222
|
+
onStarted();
|
|
223
|
+
};
|
|
224
|
+
let module;
|
|
225
|
+
try {
|
|
226
|
+
module = await importFromWorld(world, selected.package);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
markStarted();
|
|
230
|
+
diagnostic(report, selected.id, "import", error);
|
|
231
|
+
return [];
|
|
232
|
+
}
|
|
233
|
+
let candidate;
|
|
234
|
+
try {
|
|
235
|
+
candidate = manifest(module.default);
|
|
236
|
+
if (candidate.manifest.id !== selected.id) {
|
|
237
|
+
throw new TypeError(`plugin manifest id does not match selected entry: ${candidate.manifest.id}`);
|
|
238
|
+
}
|
|
239
|
+
if (activated.has(candidate.manifest.id))
|
|
240
|
+
throw new TypeError(`plugin id is duplicated: ${candidate.manifest.id}`);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
markStarted();
|
|
244
|
+
diagnostic(report, selected.id, "validation", error);
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
247
|
+
let context;
|
|
248
|
+
try {
|
|
249
|
+
const declared = await writablePaths(world, candidate.manifest.writablePaths);
|
|
250
|
+
context = Object.freeze({
|
|
251
|
+
world,
|
|
252
|
+
config: selected.config,
|
|
253
|
+
writablePath(name) {
|
|
254
|
+
const path = declared.get(name);
|
|
255
|
+
if (path === undefined)
|
|
256
|
+
throw new TypeError(`plugin writable path is undeclared: ${name}`);
|
|
257
|
+
return path;
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
markStarted();
|
|
263
|
+
diagnostic(report, selected.id, "validation", error);
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
markStarted();
|
|
267
|
+
try {
|
|
268
|
+
const instance = await candidate.activate(context);
|
|
269
|
+
const registered = handlers(candidate.manifest.id, instance);
|
|
270
|
+
activated.add(candidate.manifest.id);
|
|
271
|
+
return registered;
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
diagnostic(report, selected.id, "activation", error);
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
export async function pluginRuntime(input) {
|
|
279
|
+
let runtime = PROCESS_RUNTIMES.get(input.world);
|
|
280
|
+
if (runtime === undefined) {
|
|
281
|
+
runtime = createPluginRuntime(input);
|
|
282
|
+
PROCESS_RUNTIMES.set(input.world, runtime);
|
|
283
|
+
}
|
|
284
|
+
return await runtime;
|
|
285
|
+
}
|
|
286
|
+
async function createPluginRuntime(input) {
|
|
287
|
+
const report = input.reportDiagnostic;
|
|
288
|
+
const selected = selectedPlugins(input.settings ?? (await settings({ root: input.world })), report);
|
|
289
|
+
const activated = new Set();
|
|
290
|
+
const registered = new Map();
|
|
291
|
+
const settled = new Set();
|
|
292
|
+
const pending = new Map();
|
|
293
|
+
const deliver = (entry, signal, reportDiagnostic) => {
|
|
294
|
+
try {
|
|
295
|
+
void Promise.resolve(entry.handler(signal)).catch((error) => diagnostic(reportDiagnostic, entry.pluginId, "signal", error));
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
diagnostic(reportDiagnostic, entry.pluginId, "signal", error);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
const deliverTo = (handlers, signal, reportDiagnostic) => {
|
|
302
|
+
for (const entry of handlers) {
|
|
303
|
+
if (entry.kind === signal.kind)
|
|
304
|
+
deliver(entry, signal, reportDiagnostic);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
let previousStarted = Promise.resolve();
|
|
308
|
+
for (const [index, entry] of selected.entries()) {
|
|
309
|
+
let releaseStarted;
|
|
310
|
+
const started = new Promise((resolve) => {
|
|
311
|
+
releaseStarted = resolve;
|
|
312
|
+
});
|
|
313
|
+
void previousStarted.then(async () => {
|
|
314
|
+
try {
|
|
315
|
+
const handlers = await activate(entry, input.world, activated, report, releaseStarted);
|
|
316
|
+
if (handlers.length > 0)
|
|
317
|
+
registered.set(index, handlers);
|
|
318
|
+
settled.add(index);
|
|
319
|
+
const queued = pending.get(index);
|
|
320
|
+
if (queued !== undefined) {
|
|
321
|
+
pending.delete(index);
|
|
322
|
+
for (const signal of queued)
|
|
323
|
+
deliverTo(handlers, signal, report);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
diagnostic(report, entry.id, "activation", error);
|
|
328
|
+
settled.add(index);
|
|
329
|
+
pending.delete(index);
|
|
330
|
+
}
|
|
331
|
+
finally {
|
|
332
|
+
releaseStarted();
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
previousStarted = started;
|
|
336
|
+
}
|
|
337
|
+
return Object.freeze({
|
|
338
|
+
emit(signal, reportDiagnostic = report) {
|
|
339
|
+
const deliveries = [...registered.entries()]
|
|
340
|
+
.sort(([left], [right]) => left - right)
|
|
341
|
+
.flatMap(([, handlers]) => handlers)
|
|
342
|
+
.filter((handler) => handler.kind === signal.kind);
|
|
343
|
+
for (const [index] of selected.entries()) {
|
|
344
|
+
if (!settled.has(index)) {
|
|
345
|
+
const queue = pending.get(index);
|
|
346
|
+
if (queue === undefined)
|
|
347
|
+
pending.set(index, [signal]);
|
|
348
|
+
else
|
|
349
|
+
queue.push(signal);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
for (const entry of deliveries)
|
|
353
|
+
deliver(entry, signal, reportDiagnostic);
|
|
354
|
+
return Promise.resolve();
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
}
|
|
@@ -3,7 +3,7 @@ import { withPrivateStatePublicationSeat } from "../git/private-state-seat.js";
|
|
|
3
3
|
import { contractState } from "../core/facts/observation.js";
|
|
4
4
|
import { decideAmend } from "../core/verbs/amend.js";
|
|
5
5
|
import { admitDecidedOffer, mintAttempts } from "./attempt.js";
|
|
6
|
-
import { admitted } from "./outcome.js";
|
|
6
|
+
import { admitted, intentOutcomeWithSeatClose } from "./outcome.js";
|
|
7
7
|
import { timestamp } from "./operations.js";
|
|
8
8
|
async function extendPrerequisiteClosureAt(channel, observation, seeds) {
|
|
9
9
|
let current = observation;
|
|
@@ -30,7 +30,7 @@ export async function amendOperation(input) {
|
|
|
30
30
|
const initial = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
|
|
31
31
|
source = contractState(initial.decision, input.contractId)?.terms;
|
|
32
32
|
}
|
|
33
|
-
return await withPrivateStatePublicationSeat(input.scope, async (seat) => {
|
|
33
|
+
return intentOutcomeWithSeatClose(await withPrivateStatePublicationSeat(input.scope, async (seat) => {
|
|
34
34
|
const attempts = mintAttempts({ entryCount: 1 });
|
|
35
35
|
for (let index = 0; index < attempts.length; index += 1) {
|
|
36
36
|
let observation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
|
|
@@ -81,5 +81,5 @@ export async function amendOperation(input) {
|
|
|
81
81
|
return { kind: "retry", reason: admission };
|
|
82
82
|
}
|
|
83
83
|
return { kind: "retry", reason: { kind: "exhausted" } };
|
|
84
|
-
});
|
|
84
|
+
}));
|
|
85
85
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type PublicationFailed } from "../git/admission.js";
|
|
2
2
|
import { type GitDecisionObservation } from "../git/observe.js";
|
|
3
|
-
import { type PrivateStatePublicationSeat } from "../git/private-state-seat.js";
|
|
3
|
+
import { type PrivateStatePublicationSeat, type PrivateStateSeatCloseLag } from "../git/private-state-seat.js";
|
|
4
4
|
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
5
5
|
import { type GitRefAssertion } from "../git/repository.js";
|
|
6
6
|
import type { GitRepository } from "../git/process.js";
|
|
@@ -28,6 +28,7 @@ export type AcceptedAdmission = Readonly<{
|
|
|
28
28
|
facts: readonly JournalEntry[];
|
|
29
29
|
state: ContractState;
|
|
30
30
|
journal: readonly JournalEntry[];
|
|
31
|
+
seatClose?: readonly PrivateStateSeatCloseLag[];
|
|
31
32
|
}>;
|
|
32
33
|
export type AttemptTerminal = Readonly<{
|
|
33
34
|
kind: "collision";
|
|
@@ -2,7 +2,7 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { encodeEntry } from "../core/facts/codec.js";
|
|
3
3
|
import { admit } from "../git/admission.js";
|
|
4
4
|
import { observeContractsForAdmissionAt } from "../git/observe.js";
|
|
5
|
-
import { confirmPrivateStatePublication } from "../git/private-state-seat.js";
|
|
5
|
+
import { confirmPrivateStatePublication, } from "../git/private-state-seat.js";
|
|
6
6
|
import { GIT_REF, readRefs } from "../git/repository.js";
|
|
7
7
|
import { foldJournal } from "../core/facts/fold.js";
|
|
8
8
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
@@ -2,6 +2,7 @@ import { type DeliveryDiffScope } from "../git/integration.js";
|
|
|
2
2
|
import type { ChangeId, ContractState, DeliverData } from "../core/facts/types.js";
|
|
3
3
|
import { type AuditTargetAnswer } from "../git/target-placement.js";
|
|
4
4
|
import type { DeliveryPreparationRefusal, DocumentDerivation, IntentOutcome, MutationOperationInput, VerificationStop } from "./operations.js";
|
|
5
|
+
export { decodeAuditReport } from "./result-codec.js";
|
|
5
6
|
type AuditWorkspace = Readonly<{
|
|
6
7
|
kind: "worktree";
|
|
7
8
|
path: string;
|
|
@@ -50,4 +51,3 @@ type AuditOperationInput = MutationOperationInput & Readonly<{
|
|
|
50
51
|
signal?: AbortSignal;
|
|
51
52
|
}>;
|
|
52
53
|
export declare function auditOperation(input: AuditOperationInput): Promise<IntentOutcome<AuditReport>>;
|
|
53
|
-
export {};
|
|
@@ -7,6 +7,7 @@ import { verifyDelivery } from "./intent.js";
|
|
|
7
7
|
import { accepted, admitted } from "./outcome.js";
|
|
8
8
|
import { prepareDelivery } from "./deliver.js";
|
|
9
9
|
import { timestamp, unpackVerificationOutcome } from "./operations.js";
|
|
10
|
+
export { decodeAuditReport } from "./result-codec.js";
|
|
10
11
|
async function auditWorkspace(repository, state) {
|
|
11
12
|
const appointed = await readManagedWorktreeAppointment(repository, state.id);
|
|
12
13
|
if (appointed.kind === "failed")
|
|
@@ -30,7 +31,6 @@ async function auditCandidateVerification(input, state, snapshot, definition) {
|
|
|
30
31
|
at: timestamp(),
|
|
31
32
|
state,
|
|
32
33
|
snapshot,
|
|
33
|
-
environment: process.env,
|
|
34
34
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
35
35
|
verification: definition,
|
|
36
36
|
});
|
|
@@ -2,7 +2,7 @@ import { type BindTargetSelection } from "../git/observe.js";
|
|
|
2
2
|
export type { BindTargetSelection };
|
|
3
3
|
import type { GitRepository } from "../git/process.js";
|
|
4
4
|
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
5
|
-
import type
|
|
5
|
+
import { type BindData, type ActorId, type ContractId } from "../core/facts/types.js";
|
|
6
6
|
import { type BindRefusal } from "../core/verbs/bind.js";
|
|
7
7
|
export type { BindRefusal } from "../core/verbs/bind.js";
|
|
8
8
|
import type { VerificationDeclarationPreparation, VerificationDeclarationRefusal } from "../verification/declaration.js";
|
|
@@ -19,6 +19,8 @@ export type ForkSourceMovedRefusal = Readonly<{
|
|
|
19
19
|
kind: "fork-source-moved";
|
|
20
20
|
contractId: ContractId;
|
|
21
21
|
}>;
|
|
22
|
+
export declare function decodeTargetInputRefusal(value: unknown): TargetInputRefusal;
|
|
23
|
+
export declare function decodeForkSourceMovedRefusal(value: unknown): ForkSourceMovedRefusal;
|
|
22
24
|
type BindOperationInput = Readonly<{
|
|
23
25
|
scope: GitRepository;
|
|
24
26
|
channel: GitDecodeChannel;
|
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
import { normalizeTargetBranch, observeBindCoordinates } from "../git/observe.js";
|
|
2
2
|
import { gitObjectIdForSnapshot } from "../git/identity.js";
|
|
3
|
+
import { contractId } from "../core/facts/types.js";
|
|
3
4
|
import { decideBind } from "../core/verbs/bind.js";
|
|
4
5
|
import { admitIntent } from "./intent.js";
|
|
5
6
|
import { complete } from "./outcome.js";
|
|
7
|
+
export function decodeTargetInputRefusal(value) {
|
|
8
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
9
|
+
throw new Error("malformed target input refusal");
|
|
10
|
+
const object = value;
|
|
11
|
+
if (object.kind !== "invalid-target" && object.kind !== "target-missing" && object.kind !== "unborn-head")
|
|
12
|
+
throw new Error("malformed target input refusal");
|
|
13
|
+
if (Object.keys(object).length !== 1)
|
|
14
|
+
throw new Error("malformed target input refusal");
|
|
15
|
+
return { kind: object.kind };
|
|
16
|
+
}
|
|
17
|
+
export function decodeForkSourceMovedRefusal(value) {
|
|
18
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
19
|
+
throw new Error("malformed fork-source refusal");
|
|
20
|
+
const object = value;
|
|
21
|
+
if (object.kind !== "fork-source-moved")
|
|
22
|
+
throw new Error("malformed fork-source refusal");
|
|
23
|
+
if (Object.keys(object).some((key) => key !== "kind" && key !== "contractId"))
|
|
24
|
+
throw new Error("malformed fork-source refusal");
|
|
25
|
+
try {
|
|
26
|
+
return { kind: "fork-source-moved", contractId: contractId(String(object.contractId)) };
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new Error("malformed fork-source refusal");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
6
32
|
async function bindPreparation(input, selection, seed) {
|
|
7
33
|
if (input.verification.kind === "refused") {
|
|
8
34
|
return { kind: "prepared", input: { ...seed, preparation: input.verification } };
|
|
@@ -35,7 +35,6 @@ async function verificationFor(input, admission, snapshot) {
|
|
|
35
35
|
at: timestamp(),
|
|
36
36
|
state: admission.state,
|
|
37
37
|
snapshot,
|
|
38
|
-
environment: process.env,
|
|
39
38
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
40
39
|
...(input.verification.data === null ? {} : { verification: input.verification.data }),
|
|
41
40
|
});
|
|
@@ -16,6 +16,7 @@ export type IntegrationConflictMaterialized = Readonly<{
|
|
|
16
16
|
conflictPaths: readonly string[];
|
|
17
17
|
workspace: AppointedWorkspace;
|
|
18
18
|
}>;
|
|
19
|
+
export { decodeMaterializedConflict } from "./result-codec.js";
|
|
19
20
|
type DeliverOperationInput = MutationOperationInput & Readonly<{
|
|
20
21
|
deriveDocument: (state: ContractState) => DocumentDerivation;
|
|
21
22
|
message?: string;
|
|
@@ -54,4 +55,3 @@ export declare function continueDeliveryOperation(input: Readonly<{
|
|
|
54
55
|
signal?: AbortSignal;
|
|
55
56
|
}>): Promise<CompletionResult>;
|
|
56
57
|
export declare function deliverOperation(input: DeliverOperationInput): Promise<IntentOutcome<DeliverValue> | IntegrationConflictMaterialized>;
|
|
57
|
-
export {};
|