@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
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { access, readFile } from "node:fs/promises";
|
|
3
|
+
import { abortableDelay } from "./abort.js";
|
|
4
|
+
import { atomicJson, decodeReceiptEnvelope, receiptPath, requestPath } from "./request-wire.js";
|
|
5
|
+
const POLL_MS = 100;
|
|
6
|
+
export class AkumaBodyRequestError extends Error {
|
|
7
|
+
action;
|
|
8
|
+
outcome;
|
|
9
|
+
diagnostic;
|
|
10
|
+
kind = "akuma-body-request";
|
|
11
|
+
constructor(action, outcome, diagnostic) {
|
|
12
|
+
super(`${action} ${outcome === "voided" ? "failed" : "refused"}: ${diagnostic}`);
|
|
13
|
+
this.action = action;
|
|
14
|
+
this.outcome = outcome;
|
|
15
|
+
this.diagnostic = diagnostic;
|
|
16
|
+
this.name = "AkumaBodyRequestError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function throwVoidedRequestFailure(action, evidence, failure, decodeFailure) {
|
|
20
|
+
const ownerFailure = decodeVoidedOwnerFailure(failure, decodeFailure);
|
|
21
|
+
if (ownerFailure !== null)
|
|
22
|
+
throw ownerFailure;
|
|
23
|
+
throw new AkumaBodyRequestError(action, "voided", evidence);
|
|
24
|
+
}
|
|
25
|
+
function decodeVoidedOwnerFailure(failure, decodeFailure) {
|
|
26
|
+
if (failure === undefined || decodeFailure === undefined)
|
|
27
|
+
return null;
|
|
28
|
+
try {
|
|
29
|
+
return decodeFailure(failure);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function withRequestMetadata(response, id, action) {
|
|
36
|
+
Object.defineProperties(response, {
|
|
37
|
+
requestId: { value: id, enumerable: false },
|
|
38
|
+
action: { value: action, enumerable: false },
|
|
39
|
+
});
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
/** Generic rendezvous only: operation owners supply their own request and result codecs. */
|
|
43
|
+
export async function requestBodyCommand(input) {
|
|
44
|
+
const id = input.id ?? randomUUID();
|
|
45
|
+
input.signal?.throwIfAborted();
|
|
46
|
+
const transportId = randomUUID();
|
|
47
|
+
await atomicJson(requestPath(input.directory, transportId), {
|
|
48
|
+
id,
|
|
49
|
+
action: input.command.action,
|
|
50
|
+
payload: input.command.encodeRequest(input.value),
|
|
51
|
+
});
|
|
52
|
+
const path = receiptPath(input.directory, transportId);
|
|
53
|
+
for (;;) {
|
|
54
|
+
try {
|
|
55
|
+
const receipt = decodeReceiptEnvelope(await readFile(path, "utf8"), id, input.command.action);
|
|
56
|
+
if (receipt === null)
|
|
57
|
+
throw new Error(`Akuma body request ${id} has an invalid receipt`);
|
|
58
|
+
if (receipt.state === "refused")
|
|
59
|
+
throw new AkumaBodyRequestError(receipt.action, "refused", receipt.diagnostic);
|
|
60
|
+
if (receipt.state === "voided") {
|
|
61
|
+
throwVoidedRequestFailure(receipt.action, receipt.evidence, receipt.failure, input.command.decodeFailure);
|
|
62
|
+
}
|
|
63
|
+
if ("reference" in receipt) {
|
|
64
|
+
let reference;
|
|
65
|
+
try {
|
|
66
|
+
reference = input.command.decodeReference(receipt.reference);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const diagnostic = error instanceof Error ? error.message : String(error);
|
|
70
|
+
throw new Error(`transport integrity: request ${id} action ${input.command.action} returned an invalid durable reference: ${diagnostic}`);
|
|
71
|
+
}
|
|
72
|
+
return withRequestMetadata({
|
|
73
|
+
kind: "reference",
|
|
74
|
+
reference,
|
|
75
|
+
}, id, input.command.action);
|
|
76
|
+
}
|
|
77
|
+
if (receipt.outcome.kind === "failed") {
|
|
78
|
+
const failure = receipt.outcome.failure;
|
|
79
|
+
throw new Error(failure.kind === "failed" ? failure.diagnostic : `Akuma ${failure.id} was not born`);
|
|
80
|
+
}
|
|
81
|
+
let result;
|
|
82
|
+
try {
|
|
83
|
+
result = input.command.decodeResult(receipt.outcome.result);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
const diagnostic = error instanceof Error ? error.message : String(error);
|
|
87
|
+
throw new Error(`transport integrity: request ${id} action ${input.command.action} returned an invalid live result: ${diagnostic}`);
|
|
88
|
+
}
|
|
89
|
+
return withRequestMetadata({ kind: "returned", result }, id, input.command.action);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
if (error.code !== "ENOENT")
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
if (!(await access(input.directory).then(() => true, () => false))) {
|
|
96
|
+
throw new AkumaBodyRequestError(input.command.action, "voided", "parent request channel closed before a receipt");
|
|
97
|
+
}
|
|
98
|
+
await abortableDelay(POLL_MS, input.signal);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -1,77 +1,17 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type
|
|
3
|
-
import { type StructuralRequestClaim } from "./request-wire.js";
|
|
4
|
-
import { type TaskMutationRequest } from "../task/mutation.js";
|
|
5
|
-
import { BodyRequestPump as LifecycleBodyRequestPump, type RequestChildLaunch as LifecycleRequestChildLaunch, type PumpInput as LifecyclePumpInput } from "./request-lifecycle.js";
|
|
1
|
+
import { type ErasedRequestCommand, type RequestEnvelope } from "./request-wire.js";
|
|
2
|
+
import { BodyRequestPump as LifecycleBodyRequestPump, type PumpInput as LifecyclePumpInput } from "./request-lifecycle.js";
|
|
6
3
|
export { clearBodyRequestTransport, settleBodyRequests } from "./request-lifecycle.js";
|
|
7
|
-
export type RequestChildLaunch = LifecycleRequestChildLaunch;
|
|
8
|
-
type UpstreamCall = Readonly<{
|
|
9
|
-
signal: AbortSignal;
|
|
10
|
-
}>;
|
|
11
|
-
type RequesterCall = UpstreamCall & Readonly<{
|
|
12
|
-
requester: AkuId;
|
|
13
|
-
}>;
|
|
14
|
-
type ContractCall = RequesterCall & Readonly<{
|
|
15
|
-
repoRoot: string;
|
|
16
|
-
contractId: string;
|
|
17
|
-
}>;
|
|
18
|
-
export type UpstreamExecutionPort = Readonly<{
|
|
19
|
-
wait(input: UpstreamCall & Readonly<{
|
|
20
|
-
targets: readonly AkuId[];
|
|
21
|
-
completion: "any" | "all";
|
|
22
|
-
timeoutMs?: number;
|
|
23
|
-
}>): Promise<unknown>;
|
|
24
|
-
tell(input: UpstreamCall & Readonly<{
|
|
25
|
-
target: AkuId;
|
|
26
|
-
body: string;
|
|
27
|
-
tellId: string;
|
|
28
|
-
recordedAt: string;
|
|
29
|
-
}>): Promise<unknown>;
|
|
30
|
-
kill(input: Readonly<{
|
|
31
|
-
targets: readonly AkuId[];
|
|
32
|
-
signal: AbortSignal;
|
|
33
|
-
}>): Promise<Readonly<{
|
|
34
|
-
result: unknown;
|
|
35
|
-
service: readonly Readonly<{
|
|
36
|
-
id: AkuId;
|
|
37
|
-
evidence: KillEvidence;
|
|
38
|
-
}>[];
|
|
39
|
-
}>>;
|
|
40
|
-
deliver(input: ContractCall & Readonly<{
|
|
41
|
-
message?: string;
|
|
42
|
-
includeDirty: boolean;
|
|
43
|
-
materializeConflict: boolean;
|
|
44
|
-
}>): Promise<Readonly<{
|
|
45
|
-
result: unknown;
|
|
46
|
-
deliveryFactId?: string;
|
|
47
|
-
}>>;
|
|
48
|
-
review(input: ContractCall & Readonly<{
|
|
49
|
-
verdict: "satisfied" | "unsatisfied";
|
|
50
|
-
summary?: string;
|
|
51
|
-
}>): Promise<Readonly<{
|
|
52
|
-
result: unknown;
|
|
53
|
-
reviewFactId?: string;
|
|
54
|
-
}>>;
|
|
55
|
-
task(input: RequesterCall & Readonly<{
|
|
56
|
-
world: string;
|
|
57
|
-
request: TaskMutationRequest;
|
|
58
|
-
}>): Promise<unknown>;
|
|
59
|
-
}>;
|
|
60
4
|
type PumpInput = Omit<LifecyclePumpInput, "upstream"> & Readonly<{
|
|
61
|
-
upstream?:
|
|
5
|
+
upstream?: unknown;
|
|
6
|
+
commands: Readonly<Record<string, ErasedRequestCommand>>;
|
|
62
7
|
}>;
|
|
63
8
|
export type ServeInput = Omit<PumpInput, "bodySequence"> & Readonly<{
|
|
64
9
|
directory: string;
|
|
65
10
|
transportId: string;
|
|
66
|
-
claim:
|
|
11
|
+
claim: RequestEnvelope;
|
|
67
12
|
admissionOpen(): boolean;
|
|
68
13
|
}>;
|
|
69
|
-
export
|
|
70
|
-
state: "admitted";
|
|
71
|
-
}>, Extract<RequestFact, {
|
|
72
|
-
action: "akuma.call";
|
|
73
|
-
}>>;
|
|
74
|
-
export declare function serveRequest(input: ServeInput): Promise<void>;
|
|
14
|
+
export declare function serveRequest(input: ServeInput): Promise<boolean>;
|
|
75
15
|
export declare class BodyRequestPump extends LifecycleBodyRequestPump {
|
|
76
16
|
static open(input: PumpInput): Promise<BodyRequestPump>;
|
|
77
17
|
}
|
|
@@ -1,252 +1,124 @@
|
|
|
1
|
-
import { admitRequest, isRequestInputConflict, readRequest,
|
|
2
|
-
import {
|
|
3
|
-
import { publishAkuma } from "./publication.js";
|
|
4
|
-
import { atomicJson, canonicalAkuId, decodeRecipe, receiptPath, } from "./request-wire.js";
|
|
5
|
-
import { isTaskMutationAction } from "../task/mutation.js";
|
|
6
|
-
import { executeRequest } from "./request-execution.js";
|
|
1
|
+
import { admitRequest, isRequestInputConflict, readRequest, serveRequest as serveChildRequest, serveUpstreamRequest, voidRequest, } from "./heart/index.js";
|
|
2
|
+
import { atomicJson, receiptPath, } from "./request-wire.js";
|
|
7
3
|
import { BodyRequestPump as LifecycleBodyRequestPump, } from "./request-lifecycle.js";
|
|
8
4
|
export { clearBodyRequestTransport, settleBodyRequests } from "./request-lifecycle.js";
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return isTaskMutationAction(value.action);
|
|
14
|
-
}
|
|
15
|
-
function refusalRecipe(value) {
|
|
16
|
-
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
17
|
-
const recipe = value;
|
|
18
|
-
if (Array.isArray(recipe.allowed))
|
|
19
|
-
return recipe;
|
|
20
|
-
return { ...recipe, allowed: [] };
|
|
21
|
-
}
|
|
22
|
-
return { allowed: [] };
|
|
23
|
-
}
|
|
24
|
-
function acceptedReceipt(fact, service) {
|
|
25
|
-
return {
|
|
26
|
-
id: fact.id,
|
|
27
|
-
action: fact.action,
|
|
28
|
-
state: fact.state,
|
|
29
|
-
reference: service.action === "contract.deliver"
|
|
5
|
+
async function projectCommandReceipt(input, fact, command, outcome, failure) {
|
|
6
|
+
const receipt = fact.state === "refused"
|
|
7
|
+
? { id: fact.id, action: fact.action, state: "refused", diagnostic: fact.diagnostic }
|
|
8
|
+
: fact.state === "voided"
|
|
30
9
|
? {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
10
|
+
id: fact.id,
|
|
11
|
+
action: fact.action,
|
|
12
|
+
state: "voided",
|
|
13
|
+
evidence: fact.evidence,
|
|
14
|
+
...(failure === undefined ? {} : { failure }),
|
|
35
15
|
}
|
|
36
|
-
:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
if (fact.state !== "served")
|
|
55
|
-
return null;
|
|
56
|
-
if (fact.action === "contract.deliver") {
|
|
57
|
-
return acceptedReceipt(fact, fact.service);
|
|
58
|
-
}
|
|
59
|
-
if (fact.action === "contract.review") {
|
|
60
|
-
return acceptedReceipt(fact, fact.service);
|
|
61
|
-
}
|
|
62
|
-
if (isTask(fact)) {
|
|
63
|
-
return {
|
|
64
|
-
id: fact.id,
|
|
65
|
-
action: fact.action,
|
|
66
|
-
state: fact.state,
|
|
67
|
-
reference: { kind: "served-reference", action: fact.action },
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
async function projectReceipt(directory, transportId, fact, outcome) {
|
|
73
|
-
const receipt = outcome === undefined
|
|
74
|
-
? receiptFor(fact)
|
|
75
|
-
: fact.action === "akuma.call"
|
|
76
|
-
? null
|
|
77
|
-
: { id: fact.id, action: fact.action, state: "served", outcome };
|
|
16
|
+
: outcome === undefined
|
|
17
|
+
? "serviceJson" in fact
|
|
18
|
+
? {
|
|
19
|
+
id: fact.id,
|
|
20
|
+
action: fact.action,
|
|
21
|
+
state: "served",
|
|
22
|
+
reference: command.projectServiceJson(fact.serviceJson),
|
|
23
|
+
}
|
|
24
|
+
: "child" in fact
|
|
25
|
+
? {
|
|
26
|
+
id: fact.id,
|
|
27
|
+
action: fact.action,
|
|
28
|
+
state: "served",
|
|
29
|
+
reference: command.projectChild(fact.child),
|
|
30
|
+
}
|
|
31
|
+
: null
|
|
32
|
+
: { id: fact.id, action: fact.action, state: "served", outcome };
|
|
78
33
|
if (receipt === null)
|
|
79
34
|
return;
|
|
80
35
|
try {
|
|
81
|
-
await atomicJson(receiptPath(directory, transportId), receipt);
|
|
36
|
+
await atomicJson(receiptPath(input.directory, input.transportId), receipt);
|
|
82
37
|
}
|
|
83
38
|
catch (error) {
|
|
84
39
|
if (error.code !== "ENOENT")
|
|
85
40
|
throw error;
|
|
86
41
|
}
|
|
87
42
|
}
|
|
88
|
-
async function
|
|
43
|
+
async function serveCommand(input, command) {
|
|
44
|
+
const request = command.resolve(input.claim.payload);
|
|
45
|
+
if (request === null)
|
|
46
|
+
return false;
|
|
89
47
|
let fact = await admitRequest(input.paths, {
|
|
90
|
-
|
|
91
|
-
|
|
48
|
+
id: input.claim.id,
|
|
49
|
+
action: input.claim.action,
|
|
50
|
+
payloadJson: request.payloadJson,
|
|
92
51
|
admittedAt: input.now(),
|
|
52
|
+
permitted: request.isPermitted(input.parent.allowed),
|
|
93
53
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
fact = await refuseRequest(input.paths, input.claim.id, "invalid akuma.call recipe");
|
|
100
|
-
await projectReceipt(input.directory, input.transportId, fact);
|
|
101
|
-
}
|
|
102
|
-
async function serveCall(input) {
|
|
103
|
-
input.signal.throwIfAborted();
|
|
104
|
-
if (!input.admissionOpen())
|
|
105
|
-
return;
|
|
106
|
-
const recipe = decodeRecipe(input.claim.recipe);
|
|
107
|
-
if (recipe === null) {
|
|
108
|
-
await refuseInvalidCall(input);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
let fact = await admitRequest(input.paths, { ...input.claim, recipe, admittedAt: input.now() });
|
|
112
|
-
const existing = receiptFor(fact);
|
|
113
|
-
if (existing !== null) {
|
|
114
|
-
await projectReceipt(input.directory, input.transportId, fact);
|
|
115
|
-
return;
|
|
54
|
+
if (fact.state !== "admitted") {
|
|
55
|
+
await projectCommandReceipt(input, fact, request);
|
|
56
|
+
return true;
|
|
116
57
|
}
|
|
117
58
|
if (!input.admissionOpen()) {
|
|
118
|
-
fact = await voidRequest(input.paths,
|
|
119
|
-
await
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
if (fact.action !== "akuma.call" || fact.state !== "admitted") {
|
|
123
|
-
throw new Error(`Akuma request ${fact.id} cannot be replayed from ${fact.state}`);
|
|
124
|
-
}
|
|
125
|
-
const request = fact;
|
|
126
|
-
const world = worldRootForAkumaPaths(input.paths);
|
|
127
|
-
if (request.world !== world) {
|
|
128
|
-
fact = await refuseRequest(input.paths, request.id, `request world ${request.world} does not match ${world}`);
|
|
129
|
-
await projectReceipt(input.directory, input.transportId, fact);
|
|
130
|
-
return;
|
|
59
|
+
fact = await voidRequest(input.paths, fact.id, "body closed request admission");
|
|
60
|
+
await projectCommandReceipt(input, fact, request);
|
|
61
|
+
return true;
|
|
131
62
|
}
|
|
132
63
|
try {
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
64
|
+
const served = await request.execute({
|
|
65
|
+
id: fact.id,
|
|
66
|
+
admittedAt: fact.admittedAt,
|
|
67
|
+
requester: fact.requester,
|
|
136
68
|
signal: input.signal,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
paths: allocated.paths,
|
|
143
|
-
seed: {
|
|
144
|
-
id: allocated.id,
|
|
145
|
-
archetype: allocated.archetype,
|
|
146
|
-
...(request.recipe.description === undefined ? {} : { description: request.recipe.description }),
|
|
147
|
-
provider: request.recipe.provider,
|
|
148
|
-
options: request.recipe.options,
|
|
149
|
-
...(request.recipe.readonly === undefined ? {} : { readonly: request.recipe.readonly }),
|
|
150
|
-
allowed: request.recipe.allowed,
|
|
151
|
-
cwd: request.cwd ?? input.parent.cwd,
|
|
152
|
-
origin: {
|
|
153
|
-
kind: "request",
|
|
154
|
-
parent: input.parent.id,
|
|
155
|
-
requestId: request.id,
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
initialBody: request.body,
|
|
159
|
-
});
|
|
160
|
-
},
|
|
69
|
+
upstream: input.upstream,
|
|
70
|
+
paths: input.paths,
|
|
71
|
+
parent: input.parent,
|
|
72
|
+
spawn: input.spawn,
|
|
73
|
+
admissionOpen: input.admissionOpen,
|
|
161
74
|
});
|
|
162
|
-
fact =
|
|
75
|
+
fact =
|
|
76
|
+
"child" in served
|
|
77
|
+
? await serveChildRequest(input.paths, fact.id, served.child)
|
|
78
|
+
: await serveUpstreamRequest(input.paths, fact.id, served.serviceJson);
|
|
79
|
+
await projectCommandReceipt(input, fact, request, { kind: "returned", result: served.result });
|
|
163
80
|
}
|
|
164
81
|
catch (error) {
|
|
165
|
-
const
|
|
82
|
+
const failure = encodedFailure(request, error);
|
|
83
|
+
const current = await readRequest(input.paths, fact.id);
|
|
166
84
|
if (current === null)
|
|
167
85
|
throw error;
|
|
168
86
|
fact =
|
|
169
87
|
current.state === "admitted" || current.state === "reserved"
|
|
170
|
-
? await voidRequest(input.paths,
|
|
88
|
+
? await voidRequest(input.paths, fact.id, diagnostic(error))
|
|
171
89
|
: current;
|
|
90
|
+
await projectCommandReceipt(input, fact, request, undefined, failure);
|
|
172
91
|
}
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
function failure(error) {
|
|
176
|
-
const value = error !== null && typeof error === "object" ? error : null;
|
|
177
|
-
if (value?.kind === "akuma-not-born") {
|
|
178
|
-
const id = canonicalAkuId(value.id);
|
|
179
|
-
if (id !== null)
|
|
180
|
-
return { kind: "akuma-not-born", id };
|
|
181
|
-
}
|
|
182
|
-
return { kind: "failed", diagnostic: diagnostic(error) };
|
|
92
|
+
return true;
|
|
183
93
|
}
|
|
184
|
-
function
|
|
185
|
-
|
|
186
|
-
return { action: request.action };
|
|
187
|
-
if (request.action === "akuma.tell") {
|
|
188
|
-
return { action: request.action, target: request.target, tellId: request.id };
|
|
189
|
-
}
|
|
190
|
-
return request.action === "akuma.kill" ? { action: request.action, results: [] } : undefined;
|
|
94
|
+
function diagnostic(error) {
|
|
95
|
+
return error instanceof Error ? error.message : String(error);
|
|
191
96
|
}
|
|
192
|
-
|
|
193
|
-
input.signal.throwIfAborted();
|
|
194
|
-
let fact = await admitRequest(input.paths, {
|
|
195
|
-
...input.claim,
|
|
196
|
-
admittedAt: input.now(),
|
|
197
|
-
});
|
|
198
|
-
const existing = receiptFor(fact);
|
|
199
|
-
if (existing !== null) {
|
|
200
|
-
await projectReceipt(input.directory, input.transportId, fact);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
if (fact.state === "served") {
|
|
204
|
-
await projectReceipt(input.directory, input.transportId, fact, {
|
|
205
|
-
kind: "failed",
|
|
206
|
-
failure: {
|
|
207
|
-
kind: "failed",
|
|
208
|
-
diagnostic: "served request receipt is no longer available",
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
if (!input.admissionOpen()) {
|
|
214
|
-
fact = await voidRequest(input.paths, input.claim.id, "body closed request admission");
|
|
215
|
-
await projectReceipt(input.directory, input.transportId, fact);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
if (fact.state !== "admitted" || fact.action === "akuma.call") {
|
|
219
|
-
throw new Error(`Akuma request ${fact.id} cannot be served from ${fact.state}`);
|
|
220
|
-
}
|
|
221
|
-
const request = fact;
|
|
222
|
-
let outcome;
|
|
223
|
-
let service = pendingService(request);
|
|
97
|
+
function encodedFailure(request, error) {
|
|
224
98
|
try {
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
if (served.service !== undefined)
|
|
228
|
-
service = served.service;
|
|
99
|
+
const failure = request.encodeFailure(error);
|
|
100
|
+
return failure === null ? undefined : failure;
|
|
229
101
|
}
|
|
230
|
-
catch
|
|
231
|
-
|
|
232
|
-
fact = await voidRequest(input.paths, request.id, "body failed before serving the request");
|
|
233
|
-
await projectReceipt(input.directory, input.transportId, fact);
|
|
234
|
-
return;
|
|
102
|
+
catch {
|
|
103
|
+
return undefined;
|
|
235
104
|
}
|
|
236
|
-
fact =
|
|
237
|
-
service === undefined
|
|
238
|
-
? await voidRequest(input.paths, request.id, "body completed without a durable Contract fact reference")
|
|
239
|
-
: await serveUpstreamRequest(input.paths, request.id, service);
|
|
240
|
-
await projectReceipt(input.directory, input.transportId, fact, outcome);
|
|
241
105
|
}
|
|
242
106
|
export async function serveRequest(input) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
107
|
+
const command = input.commands[input.claim.action];
|
|
108
|
+
if (command === undefined) {
|
|
109
|
+
await atomicJson(receiptPath(input.directory, input.transportId), {
|
|
110
|
+
id: input.claim.id,
|
|
111
|
+
action: input.claim.action,
|
|
112
|
+
state: "refused",
|
|
113
|
+
diagnostic: `request action ${input.claim.action} is not registered`,
|
|
114
|
+
});
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
return await serveCommand(input, command);
|
|
246
118
|
}
|
|
247
119
|
async function serveTransportClaim(input) {
|
|
248
120
|
try {
|
|
249
|
-
await serveRequest(input);
|
|
121
|
+
return await serveRequest(input);
|
|
250
122
|
}
|
|
251
123
|
catch (error) {
|
|
252
124
|
if (!isRequestInputConflict(error))
|
|
@@ -257,10 +129,11 @@ async function serveTransportClaim(input) {
|
|
|
257
129
|
state: "refused",
|
|
258
130
|
diagnostic: error.message,
|
|
259
131
|
});
|
|
132
|
+
return true;
|
|
260
133
|
}
|
|
261
134
|
}
|
|
262
135
|
export class BodyRequestPump extends LifecycleBodyRequestPump {
|
|
263
136
|
static async open(input) {
|
|
264
|
-
return (await LifecycleBodyRequestPump.openWithService(input, async (claim) => await serveTransportClaim(claim)));
|
|
137
|
+
return (await LifecycleBodyRequestPump.openWithService(input, async (claim) => await serveTransportClaim({ ...claim, commands: input.commands })));
|
|
265
138
|
}
|
|
266
139
|
}
|