@astrosheep/keiyaku 4.0.3 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +15 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +34 -13
- package/build/src/akuma/akuma.d.ts +34 -12
- package/build/src/akuma/akuma.js +118 -63
- package/build/src/akuma/allowed.d.ts +7 -0
- package/build/src/akuma/allowed.js +33 -0
- package/build/src/akuma/archetype.d.ts +7 -4
- package/build/src/akuma/archetype.js +15 -16
- package/build/src/akuma/body.d.ts +6 -1
- package/build/src/akuma/body.js +36 -27
- package/build/src/akuma/heart/facts.d.ts +82 -14
- package/build/src/akuma/heart/index.d.ts +5 -18
- package/build/src/akuma/heart/index.js +14 -84
- package/build/src/akuma/heart/request-authority.d.ts +12 -0
- package/build/src/akuma/heart/request-authority.js +119 -0
- package/build/src/akuma/heart/request-rows.d.ts +16 -0
- package/build/src/akuma/heart/request-rows.js +88 -0
- package/build/src/akuma/heart/rows.d.ts +1 -26
- package/build/src/akuma/heart/rows.js +0 -50
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +22 -10
- package/build/src/akuma/heart/soul.js +2 -36
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +15 -0
- package/build/src/akuma/heart/timeline.d.ts +1 -5
- package/build/src/akuma/heart/timeline.js +8 -17
- package/build/src/akuma/index.d.ts +5 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/projection.d.ts +17 -3
- package/build/src/akuma/projection.js +40 -3
- package/build/src/akuma/provider-recipe.js +1 -11
- package/build/src/akuma/provider.d.ts +2 -7
- package/build/src/akuma/provider.js +2 -1
- package/build/src/akuma/providers/acp/core.d.ts +3 -1
- package/build/src/akuma/providers/acp/core.js +10 -6
- package/build/src/akuma/providers/acp/events.d.ts +11 -3
- package/build/src/akuma/providers/acp/events.js +78 -4
- package/build/src/akuma/providers/acp/index.js +0 -1
- package/build/src/akuma/providers/claude/events.js +62 -3
- package/build/src/akuma/providers/claude/index.d.ts +0 -4
- package/build/src/akuma/providers/claude/index.js +7 -3
- package/build/src/akuma/providers/codex-app-server/events.js +1 -13
- package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
- package/build/src/akuma/providers/codex-app-server/index.js +0 -2
- package/build/src/akuma/providers/grok-build/index.d.ts +2 -1
- package/build/src/akuma/providers/grok-build/index.js +72 -3
- package/build/src/akuma/providers/opencode-sdk/events.js +71 -6
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
- package/build/src/akuma/providers/opencode-sdk/index.js +8 -4
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
- package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
- package/build/src/akuma/providers/pi/events.js +17 -3
- package/build/src/akuma/providers/pi/index.js +11 -4
- package/build/src/akuma/providers/unified-patch.d.ts +4 -0
- package/build/src/akuma/providers/unified-patch.js +14 -0
- package/build/src/akuma/publication.d.ts +1 -1
- package/build/src/akuma/publication.js +1 -1
- package/build/src/akuma/request-serve.d.ts +87 -0
- package/build/src/akuma/request-serve.js +484 -0
- package/build/src/akuma/request-wire.d.ts +124 -0
- package/build/src/akuma/request-wire.js +380 -0
- package/build/src/akuma/requests.d.ts +41 -41
- package/build/src/akuma/requests.js +75 -374
- package/build/src/akuma-body.d.ts +8 -0
- package/build/src/akuma-body.js +84 -0
- package/build/src/body/arc.js +4 -29
- package/build/src/body/decode.js +5 -39
- package/build/src/body/envelope.d.ts +7 -0
- package/build/src/body/envelope.js +37 -0
- package/build/src/cli/accepted.d.ts +4 -1
- package/build/src/cli/accepted.js +39 -9
- package/build/src/cli/commands/akuma-invoke.d.ts +8 -7
- package/build/src/cli/commands/akuma-invoke.js +18 -10
- package/build/src/cli/commands/akuma.d.ts +11 -2
- package/build/src/cli/commands/akuma.js +67 -28
- package/build/src/cli/commands/amend.d.ts +1 -1
- package/build/src/cli/commands/amend.js +1 -1
- package/build/src/cli/commands/contract.d.ts +8 -8
- package/build/src/cli/commands/contract.js +3 -3
- package/build/src/cli/commands/install.js +2 -2
- package/build/src/cli/commands/task-invoke.js +98 -9
- package/build/src/cli/commands/task-query.d.ts +1 -1
- package/build/src/cli/commands/task-query.js +11 -5
- package/build/src/cli/coordinates.d.ts +2 -0
- package/build/src/cli/coordinates.js +12 -5
- package/build/src/cli/invoke.d.ts +1 -0
- package/build/src/cli/invoke.js +116 -75
- package/build/src/cli/main.d.ts +2 -0
- package/build/src/cli/main.js +29 -4
- package/build/src/cli/parse.d.ts +3 -2
- package/build/src/cli/parse.js +25 -8
- package/build/src/cli/render/akuma.d.ts +2 -2
- package/build/src/cli/render/akuma.js +138 -24
- package/build/src/cli/render/audit.js +18 -8
- package/build/src/cli/render/contract.d.ts +2 -0
- package/build/src/cli/render/contract.js +243 -36
- package/build/src/cli/render/kanshi.js +64 -29
- package/build/src/cli/render/receipt.d.ts +2 -1
- package/build/src/cli/render/receipt.js +37 -2
- package/build/src/cli/render/terminal.d.ts +0 -2
- package/build/src/cli/render/terminal.js +0 -29
- package/build/src/cli/render/text.js +3 -1
- package/build/src/cli/result.d.ts +52 -9
- package/build/src/cli/selectors.d.ts +1 -0
- package/build/src/cli/selectors.js +9 -6
- package/build/src/contract-worktree.d.ts +1 -2
- package/build/src/contract-worktree.js +7 -9
- package/build/src/core/facts/codec.js +9 -0
- package/build/src/core/facts/fold.js +13 -1
- package/build/src/core/facts/types.d.ts +8 -1
- package/build/src/core/subject.js +4 -3
- package/build/src/core/verbs/placement.d.ts +9 -1
- package/build/src/core/verbs/placement.js +24 -6
- package/build/src/core/verbs/reintegrate.d.ts +13 -0
- package/build/src/core/verbs/reintegrate.js +24 -0
- package/build/src/dispatch/index.d.ts +1 -1
- package/build/src/dispatch/index.js +50 -39
- package/build/src/git/admission.d.ts +2 -1
- package/build/src/git/hooks.d.ts +0 -4
- package/build/src/git/hooks.js +0 -36
- package/build/src/git/integration.d.ts +7 -8
- package/build/src/git/integration.js +62 -9
- package/build/src/git/observe.d.ts +2 -1
- package/build/src/git/observe.js +6 -5
- package/build/src/git/process.d.ts +26 -0
- package/build/src/git/process.js +94 -0
- package/build/src/git/read-observation.d.ts +2 -1
- package/build/src/git/read-observation.js +3 -2
- package/build/src/git/reconcile.d.ts +8 -2
- package/build/src/git/reconcile.js +63 -14
- package/build/src/git/repository.d.ts +2 -29
- package/build/src/git/repository.js +4 -118
- package/build/src/git/scratch.d.ts +1 -1
- package/build/src/git/scratch.js +1 -1
- package/build/src/git/target-placement.d.ts +1 -1
- package/build/src/git/target-placement.js +9 -7
- package/build/src/git/tender.d.ts +20 -5
- package/build/src/git/tender.js +45 -13
- package/build/src/git/terminal-seal.d.ts +16 -2
- package/build/src/git/terminal-seal.js +15 -5
- package/build/src/git/workspace.d.ts +2 -1
- package/build/src/git/workspace.js +13 -5
- package/build/src/index.d.ts +1 -2
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +9 -1
- package/build/src/kanshi/read.js +91 -37
- package/build/src/kanshi/report.d.ts +1 -0
- package/build/src/library/address.d.ts +5 -14
- package/build/src/library/address.js +27 -23
- package/build/src/library/akuma-creation.d.ts +4 -2
- package/build/src/library/akuma-creation.js +43 -26
- package/build/src/library/audit.d.ts +2 -1
- package/build/src/library/audit.js +1 -1
- package/build/src/library/bind.d.ts +2 -1
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -2
- package/build/src/library/catalog.js +11 -6
- package/build/src/library/configuration.d.ts +5 -1
- package/build/src/library/configuration.js +71 -18
- package/build/src/library/contract.d.ts +70 -3
- package/build/src/library/contract.js +213 -27
- package/build/src/library/delivery.d.ts +1 -1
- package/build/src/library/fleet.d.ts +70 -12
- package/build/src/library/fleet.js +236 -56
- package/build/src/library/input.d.ts +0 -1
- package/build/src/library/input.js +1 -5
- package/build/src/library/keiyaku.d.ts +4 -4
- package/build/src/library/keiyaku.js +1 -2
- package/build/src/library/mutation.d.ts +2 -1
- package/build/src/library/reconcile.d.ts +2 -1
- package/build/src/library/reconcile.js +3 -1
- package/build/src/library/region.d.ts +1 -1
- package/build/src/library/repo.d.ts +3 -1
- package/build/src/library/repo.js +8 -4
- package/build/src/protocol/abandon.d.ts +9 -0
- package/build/src/protocol/abandon.js +15 -0
- package/build/src/protocol/amend.d.ts +16 -0
- package/build/src/protocol/amend.js +77 -0
- package/build/src/protocol/arc.d.ts +6 -0
- package/build/src/protocol/arc.js +12 -0
- package/build/src/protocol/attempt.d.ts +2 -1
- package/build/src/protocol/audit.d.ts +53 -0
- package/build/src/protocol/audit.js +140 -0
- package/build/src/protocol/bind.d.ts +2 -3
- package/build/src/protocol/bind.js +2 -16
- package/build/src/protocol/completion.d.ts +32 -0
- package/build/src/protocol/completion.js +130 -0
- package/build/src/protocol/deliver.d.ts +37 -0
- package/build/src/protocol/deliver.js +160 -0
- package/build/src/protocol/intent.d.ts +1 -1
- package/build/src/protocol/intent.js +1 -1
- package/build/src/protocol/operations.d.ts +65 -198
- package/build/src/protocol/operations.js +21 -634
- package/build/src/protocol/placement.d.ts +4 -13
- package/build/src/protocol/placement.js +3 -15
- package/build/src/protocol/read/status.d.ts +4 -2
- package/build/src/protocol/read/status.js +27 -15
- package/build/src/protocol/reconcile.d.ts +35 -0
- package/build/src/protocol/reconcile.js +41 -0
- package/build/src/protocol/reintegrate.d.ts +31 -0
- package/build/src/protocol/reintegrate.js +74 -0
- package/build/src/protocol/review.d.ts +33 -0
- package/build/src/protocol/review.js +148 -0
- package/build/src/protocol/run.d.ts +1 -1
- package/build/src/runtime/proc/run.d.ts +1 -0
- package/build/src/runtime/proc/run.js +9 -2
- package/build/src/settlement/fence.d.ts +1 -1
- package/build/src/settlement/holder.d.ts +1 -1
- package/build/src/settlement/settle.d.ts +2 -1
- package/build/src/settlement/settle.js +4 -1
- package/build/src/task/board.d.ts +18 -4
- package/build/src/task/board.js +73 -29
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +11 -4
- package/build/src/task/index.d.ts +4 -4
- package/build/src/task/index.js +8 -131
- package/build/src/task/input.d.ts +18 -0
- package/build/src/task/input.js +189 -0
- package/build/src/task/mutation.d.ts +39 -0
- package/build/src/task/mutation.js +85 -0
- package/build/src/task/operations.d.ts +4 -19
- package/build/src/task/operations.js +64 -18
- package/build/src/task/query.d.ts +9 -2
- package/build/src/task/query.js +32 -64
- package/build/src/task/store.js +0 -2
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/verification/execution.js +2 -1
- package/build/src/workspace-place.d.ts +1 -4
- package/build/src/workspace-place.js +0 -15
- package/package.json +5 -3
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { rename, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
import { decodeAllowedActions } from "./allowed.js";
|
|
5
|
+
import { archetypeName, parseAkuId } from "./identity.js";
|
|
6
|
+
import { decodeProviderOptions, decodeReadonlyRestraint, } from "./provider-recipe.js";
|
|
7
|
+
import { resolveProviderExecution } from "./providers/index.js";
|
|
8
|
+
import { decodeTaskMutationRequest, isTaskMutationAction, } from "../task/mutation.js";
|
|
9
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
|
|
10
|
+
function object(value) {
|
|
11
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
12
|
+
? value
|
|
13
|
+
: null;
|
|
14
|
+
}
|
|
15
|
+
function exactKeys(value, expected) {
|
|
16
|
+
const actual = Object.keys(value).sort();
|
|
17
|
+
const sorted = [...expected].sort();
|
|
18
|
+
return actual.length === sorted.length && actual.every((key, index) => key === sorted[index]);
|
|
19
|
+
}
|
|
20
|
+
export function absolute(value) {
|
|
21
|
+
return typeof value === "string" && isAbsolute(value) && resolve(value) === value;
|
|
22
|
+
}
|
|
23
|
+
export function canonicalAkuId(value) {
|
|
24
|
+
if (typeof value !== "string")
|
|
25
|
+
return null;
|
|
26
|
+
try {
|
|
27
|
+
const id = parseAkuId(value).id;
|
|
28
|
+
return id === value ? id : null;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function canonicalTargets(value) {
|
|
35
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
36
|
+
return null;
|
|
37
|
+
const ids = [];
|
|
38
|
+
for (const item of value) {
|
|
39
|
+
const id = canonicalAkuId(item);
|
|
40
|
+
if (id === null
|
|
41
|
+
|| (ids.length > 0
|
|
42
|
+
&& Buffer.compare(Buffer.from(ids.at(-1)), Buffer.from(id)) >= 0))
|
|
43
|
+
return null;
|
|
44
|
+
ids.push(id);
|
|
45
|
+
}
|
|
46
|
+
return ids;
|
|
47
|
+
}
|
|
48
|
+
export function decodeRecipe(value) {
|
|
49
|
+
const recipe = object(value);
|
|
50
|
+
if (recipe === null)
|
|
51
|
+
return null;
|
|
52
|
+
const expected = [
|
|
53
|
+
"allowed",
|
|
54
|
+
"options",
|
|
55
|
+
"provider",
|
|
56
|
+
...(recipe.description === undefined ? [] : ["description"]),
|
|
57
|
+
...(recipe.readonly === undefined ? [] : ["readonly"]),
|
|
58
|
+
];
|
|
59
|
+
if (!exactKeys(recipe, expected)
|
|
60
|
+
|| (recipe.description !== undefined
|
|
61
|
+
&& (typeof recipe.description !== "string"
|
|
62
|
+
|| recipe.description.trim().length === 0)))
|
|
63
|
+
return null;
|
|
64
|
+
try {
|
|
65
|
+
const options = decodeProviderOptions(recipe.options);
|
|
66
|
+
const readonly = recipe.readonly === undefined ? undefined : decodeReadonlyRestraint(recipe.readonly);
|
|
67
|
+
if ((options.readonly === true) !== (readonly !== undefined))
|
|
68
|
+
return null;
|
|
69
|
+
return Object.freeze({
|
|
70
|
+
...(recipe.description === undefined ? {} : { description: recipe.description }),
|
|
71
|
+
allowed: decodeAllowedActions(recipe.allowed),
|
|
72
|
+
provider: resolveProviderExecution(recipe.provider).execution,
|
|
73
|
+
options,
|
|
74
|
+
...(readonly === undefined ? {} : { readonly }),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function contractId(value) {
|
|
82
|
+
return typeof value === "string" && /^kei\/[^/\s]+$/u.test(value) ? value : null;
|
|
83
|
+
}
|
|
84
|
+
function decodeCall(id, payload) {
|
|
85
|
+
const expected = [
|
|
86
|
+
"archetype",
|
|
87
|
+
"body",
|
|
88
|
+
"recipe",
|
|
89
|
+
"world",
|
|
90
|
+
...(payload.cwd === undefined ? [] : ["cwd"]),
|
|
91
|
+
];
|
|
92
|
+
if (!exactKeys(payload, expected)
|
|
93
|
+
|| typeof payload.body !== "string"
|
|
94
|
+
|| !absolute(payload.world)
|
|
95
|
+
|| (payload.cwd !== undefined && !absolute(payload.cwd)))
|
|
96
|
+
return null;
|
|
97
|
+
try {
|
|
98
|
+
archetypeName(payload.archetype);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
id,
|
|
105
|
+
action: "akuma.call",
|
|
106
|
+
world: payload.world,
|
|
107
|
+
archetype: payload.archetype,
|
|
108
|
+
body: payload.body,
|
|
109
|
+
recipe: payload.recipe,
|
|
110
|
+
...(payload.cwd === undefined ? {} : { cwd: payload.cwd }),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function decodeWait(id, payload) {
|
|
114
|
+
const targets = canonicalTargets(payload.targets);
|
|
115
|
+
const expected = [
|
|
116
|
+
"completion",
|
|
117
|
+
"targets",
|
|
118
|
+
...(payload.timeoutMs === undefined ? [] : ["timeoutMs"]),
|
|
119
|
+
];
|
|
120
|
+
if (!exactKeys(payload, expected)
|
|
121
|
+
|| targets === null
|
|
122
|
+
|| (payload.completion !== "any" && payload.completion !== "all")
|
|
123
|
+
|| (payload.timeoutMs !== undefined
|
|
124
|
+
&& (!Number.isSafeInteger(payload.timeoutMs)
|
|
125
|
+
|| payload.timeoutMs < 0)))
|
|
126
|
+
return null;
|
|
127
|
+
return {
|
|
128
|
+
id,
|
|
129
|
+
action: "akuma.wait",
|
|
130
|
+
targets,
|
|
131
|
+
completion: payload.completion,
|
|
132
|
+
...(payload.timeoutMs === undefined
|
|
133
|
+
? {}
|
|
134
|
+
: { timeoutMs: payload.timeoutMs }),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function decodeTell(id, payload) {
|
|
138
|
+
const target = canonicalAkuId(payload.target);
|
|
139
|
+
return exactKeys(payload, ["body", "target"])
|
|
140
|
+
&& target !== null
|
|
141
|
+
&& typeof payload.body === "string"
|
|
142
|
+
? { id, action: "akuma.tell", target, body: payload.body }
|
|
143
|
+
: null;
|
|
144
|
+
}
|
|
145
|
+
function decodeKill(id, payload) {
|
|
146
|
+
const targets = canonicalTargets(payload.targets);
|
|
147
|
+
return exactKeys(payload, ["targets"])
|
|
148
|
+
&& targets !== null
|
|
149
|
+
? { id, action: "akuma.kill", targets }
|
|
150
|
+
: null;
|
|
151
|
+
}
|
|
152
|
+
function decodeDeliver(id, payload) {
|
|
153
|
+
const valid = exactKeys(payload, [
|
|
154
|
+
"contractId",
|
|
155
|
+
"includeDirty",
|
|
156
|
+
"repoRoot",
|
|
157
|
+
...(payload.message === undefined ? [] : ["message"]),
|
|
158
|
+
]);
|
|
159
|
+
const selected = contractId(payload.contractId);
|
|
160
|
+
return valid
|
|
161
|
+
&& selected !== null
|
|
162
|
+
&& absolute(payload.repoRoot)
|
|
163
|
+
&& typeof payload.includeDirty === "boolean"
|
|
164
|
+
&& (payload.message === undefined
|
|
165
|
+
|| (typeof payload.message === "string"
|
|
166
|
+
&& payload.message.trim().length > 0))
|
|
167
|
+
? {
|
|
168
|
+
id,
|
|
169
|
+
action: "contract.deliver",
|
|
170
|
+
repoRoot: payload.repoRoot,
|
|
171
|
+
contractId: selected,
|
|
172
|
+
includeDirty: payload.includeDirty,
|
|
173
|
+
...(payload.message === undefined
|
|
174
|
+
? {}
|
|
175
|
+
: { message: payload.message }),
|
|
176
|
+
}
|
|
177
|
+
: null;
|
|
178
|
+
}
|
|
179
|
+
function decodeReview(id, payload) {
|
|
180
|
+
const valid = exactKeys(payload, [
|
|
181
|
+
"contractId",
|
|
182
|
+
"repoRoot",
|
|
183
|
+
"verdict",
|
|
184
|
+
...(payload.summary === undefined ? [] : ["summary"]),
|
|
185
|
+
]);
|
|
186
|
+
const selected = contractId(payload.contractId);
|
|
187
|
+
return valid
|
|
188
|
+
&& selected !== null
|
|
189
|
+
&& absolute(payload.repoRoot)
|
|
190
|
+
&& (payload.verdict === "satisfied" || payload.verdict === "unsatisfied")
|
|
191
|
+
&& (payload.summary === undefined
|
|
192
|
+
|| (typeof payload.summary === "string"
|
|
193
|
+
&& payload.summary.trim().length > 0))
|
|
194
|
+
? {
|
|
195
|
+
id,
|
|
196
|
+
action: "contract.review",
|
|
197
|
+
repoRoot: payload.repoRoot,
|
|
198
|
+
contractId: selected,
|
|
199
|
+
verdict: payload.verdict,
|
|
200
|
+
...(payload.summary === undefined
|
|
201
|
+
? {}
|
|
202
|
+
: { summary: payload.summary }),
|
|
203
|
+
}
|
|
204
|
+
: null;
|
|
205
|
+
}
|
|
206
|
+
function decodeTask(id, action, payload) {
|
|
207
|
+
if (!isTaskMutationAction(action)
|
|
208
|
+
|| !exactKeys(payload, ["request", "world"])
|
|
209
|
+
|| !absolute(payload.world))
|
|
210
|
+
return null;
|
|
211
|
+
try {
|
|
212
|
+
return {
|
|
213
|
+
id,
|
|
214
|
+
action,
|
|
215
|
+
world: payload.world,
|
|
216
|
+
request: decodeTaskMutationRequest(action, payload.request),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const CLAIM_DECODERS = {
|
|
224
|
+
"akuma.call": decodeCall,
|
|
225
|
+
"akuma.wait": decodeWait,
|
|
226
|
+
"akuma.tell": decodeTell,
|
|
227
|
+
"akuma.kill": decodeKill,
|
|
228
|
+
"contract.deliver": decodeDeliver,
|
|
229
|
+
"contract.review": decodeReview,
|
|
230
|
+
};
|
|
231
|
+
export function decodeClaim(bytes, fileId) {
|
|
232
|
+
let decoded;
|
|
233
|
+
try {
|
|
234
|
+
decoded = JSON.parse(bytes);
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
const value = object(decoded);
|
|
240
|
+
if (value === null
|
|
241
|
+
|| !exactKeys(value, ["action", "id", "payload"])
|
|
242
|
+
|| value.id !== fileId
|
|
243
|
+
|| typeof value.id !== "string"
|
|
244
|
+
|| !UUID.test(value.id))
|
|
245
|
+
return null;
|
|
246
|
+
const payload = object(value.payload);
|
|
247
|
+
if (payload === null || typeof value.action !== "string")
|
|
248
|
+
return null;
|
|
249
|
+
const decoder = CLAIM_DECODERS[value.action];
|
|
250
|
+
return decoder === undefined ? decodeTask(value.id, value.action, payload) : decoder(value.id, payload);
|
|
251
|
+
}
|
|
252
|
+
function outcome(value) {
|
|
253
|
+
const input = object(value);
|
|
254
|
+
if (input?.kind === "returned" && exactKeys(input, ["kind", "result"])) {
|
|
255
|
+
return { kind: input.kind, result: input.result };
|
|
256
|
+
}
|
|
257
|
+
const failure = object(input?.failure);
|
|
258
|
+
if (input?.kind !== "failed"
|
|
259
|
+
|| !exactKeys(input, ["failure", "kind"])
|
|
260
|
+
|| failure === null)
|
|
261
|
+
return null;
|
|
262
|
+
if (failure.kind === "akuma-not-born" && exactKeys(failure, ["id", "kind"])) {
|
|
263
|
+
const id = canonicalAkuId(failure.id);
|
|
264
|
+
return id === null
|
|
265
|
+
? null
|
|
266
|
+
: { kind: input.kind, failure: { kind: failure.kind, id } };
|
|
267
|
+
}
|
|
268
|
+
return failure.kind === "failed" && exactKeys(failure, ["diagnostic", "kind"]) && typeof failure.diagnostic === "string"
|
|
269
|
+
? { kind: input.kind, failure: { kind: failure.kind, diagnostic: failure.diagnostic } } : null;
|
|
270
|
+
}
|
|
271
|
+
function envelope(value, id, action) {
|
|
272
|
+
if (value.state === "refused"
|
|
273
|
+
&& exactKeys(value, ["action", "diagnostic", "id", "state"])
|
|
274
|
+
&& typeof value.diagnostic === "string") {
|
|
275
|
+
return { id, action, state: value.state, diagnostic: value.diagnostic };
|
|
276
|
+
}
|
|
277
|
+
if (value.state === "voided"
|
|
278
|
+
&& exactKeys(value, ["action", "evidence", "id", "state"])
|
|
279
|
+
&& typeof value.evidence === "string") {
|
|
280
|
+
return { id, action, state: value.state, evidence: value.evidence };
|
|
281
|
+
}
|
|
282
|
+
if (action !== "akuma.call"
|
|
283
|
+
&& value.state === "served"
|
|
284
|
+
&& exactKeys(value, ["action", "id", "outcome", "state"])) {
|
|
285
|
+
const decoded = outcome(value.outcome);
|
|
286
|
+
return decoded === null
|
|
287
|
+
? null
|
|
288
|
+
: { id, action, state: value.state, outcome: decoded };
|
|
289
|
+
}
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
function reference(value, action) {
|
|
293
|
+
const input = object(value);
|
|
294
|
+
const field = action === "contract.deliver" ? "deliveryFactId" : "reviewFactId";
|
|
295
|
+
if (input === null
|
|
296
|
+
|| !exactKeys(input, ["contractId", field, "kind", "repoRoot"])
|
|
297
|
+
|| input.kind !== "accepted-reference"
|
|
298
|
+
|| !absolute(input.repoRoot)
|
|
299
|
+
|| contractId(input.contractId) === null
|
|
300
|
+
|| typeof input[field] !== "string"
|
|
301
|
+
|| input[field].trim().length === 0)
|
|
302
|
+
return null;
|
|
303
|
+
return action === "contract.deliver"
|
|
304
|
+
? { kind: input.kind, repoRoot: input.repoRoot, contractId: input.contractId, deliveryFactId: input.deliveryFactId }
|
|
305
|
+
: { kind: input.kind, repoRoot: input.repoRoot, contractId: input.contractId, reviewFactId: input.reviewFactId };
|
|
306
|
+
}
|
|
307
|
+
function decodeCallReceipt(value, id) {
|
|
308
|
+
if (value.state !== "served" || !exactKeys(value, ["action", "child", "id", "state"]))
|
|
309
|
+
return null;
|
|
310
|
+
const child = canonicalAkuId(value.child);
|
|
311
|
+
return child === null ? null : { id, action: "akuma.call", state: value.state, child };
|
|
312
|
+
}
|
|
313
|
+
function decodeContractReceipt(value, id, action) {
|
|
314
|
+
if (value.state !== "served" || !exactKeys(value, ["action", "id", "reference", "state"]))
|
|
315
|
+
return null;
|
|
316
|
+
const selected = reference(value.reference, action);
|
|
317
|
+
if (selected === null)
|
|
318
|
+
return null;
|
|
319
|
+
return action === "contract.deliver"
|
|
320
|
+
? { id, action, state: value.state, reference: selected }
|
|
321
|
+
: { id, action, state: value.state, reference: selected };
|
|
322
|
+
}
|
|
323
|
+
function decodeTaskReceipt(value, id, action) {
|
|
324
|
+
if (value.state !== "served" || !exactKeys(value, ["action", "id", "reference", "state"]))
|
|
325
|
+
return null;
|
|
326
|
+
const selected = object(value.reference);
|
|
327
|
+
if (selected === null
|
|
328
|
+
|| !exactKeys(selected, ["action", "kind"])
|
|
329
|
+
|| selected.kind !== "served-reference"
|
|
330
|
+
|| selected.action !== action)
|
|
331
|
+
return null;
|
|
332
|
+
return { id, action, state: value.state, reference: { kind: selected.kind, action } };
|
|
333
|
+
}
|
|
334
|
+
export function decodeReceipt(bytes, id, action) {
|
|
335
|
+
let decoded;
|
|
336
|
+
try {
|
|
337
|
+
decoded = JSON.parse(bytes);
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
const value = object(decoded);
|
|
343
|
+
if (value === null || value.id !== id || value.action !== action)
|
|
344
|
+
return null;
|
|
345
|
+
const shared = envelope(value, id, action);
|
|
346
|
+
if (shared !== null)
|
|
347
|
+
return shared;
|
|
348
|
+
if (action === "akuma.call")
|
|
349
|
+
return decodeCallReceipt(value, id);
|
|
350
|
+
if (action === "contract.deliver" || action === "contract.review")
|
|
351
|
+
return decodeContractReceipt(value, id, action);
|
|
352
|
+
if (isTaskMutationAction(action))
|
|
353
|
+
return decodeTaskReceipt(value, id, action);
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
export function requestPayload(claim) {
|
|
357
|
+
if (isTaskMutationAction(claim.action)) {
|
|
358
|
+
const task = claim;
|
|
359
|
+
const { action: _action, ...request } = task.request;
|
|
360
|
+
return { world: task.world, request };
|
|
361
|
+
}
|
|
362
|
+
const { id: _id, action: _action, ...payload } = claim;
|
|
363
|
+
return payload;
|
|
364
|
+
}
|
|
365
|
+
export function requestPath(directory, id) {
|
|
366
|
+
return join(directory, `${id}.request.json`);
|
|
367
|
+
}
|
|
368
|
+
export function receiptPath(directory, id) {
|
|
369
|
+
return join(directory, `${id}.receipt.json`);
|
|
370
|
+
}
|
|
371
|
+
export async function atomicJson(path, value) {
|
|
372
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
373
|
+
try {
|
|
374
|
+
await writeFile(temporary, `${JSON.stringify(value)}\n`, { flag: "wx" });
|
|
375
|
+
await rename(temporary, path);
|
|
376
|
+
}
|
|
377
|
+
finally {
|
|
378
|
+
await rm(temporary, { force: true });
|
|
379
|
+
}
|
|
380
|
+
}
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type
|
|
3
|
-
type
|
|
4
|
-
id: string;
|
|
5
|
-
world: string;
|
|
6
|
-
archetype: string;
|
|
7
|
-
body: string;
|
|
8
|
-
cwd?: string;
|
|
9
|
-
recipe: RequestRecipe;
|
|
10
|
-
}>;
|
|
11
|
-
export type RequestChildLaunch = Readonly<{
|
|
12
|
-
paths: AkumaPaths;
|
|
13
|
-
seed: Omit<Soul, "createdAt">;
|
|
14
|
-
initialBody: string;
|
|
15
|
-
}>;
|
|
1
|
+
import { type CallRequestClaim, type DeliverRequestClaim, type ForwardedDeliveryReference, type ForwardedReviewReference, type KillRequestClaim, type ReviewRequestClaim, type TellRequestClaim, type UpstreamRequestOutcome, type WaitRequestClaim } from "./request-wire.js";
|
|
2
|
+
import { type TaskMutationRequest } from "../task/mutation.js";
|
|
3
|
+
export type { UpstreamRequestOutcome } from "./request-wire.js";
|
|
16
4
|
export declare class AkumaBodyRequestError extends Error {
|
|
17
5
|
readonly outcome: "refused" | "voided";
|
|
18
6
|
readonly diagnostic: string;
|
|
@@ -20,30 +8,42 @@ export declare class AkumaBodyRequestError extends Error {
|
|
|
20
8
|
constructor(outcome: "refused" | "voided", diagnostic: string);
|
|
21
9
|
}
|
|
22
10
|
export declare function injectedBodyRequests(): string | null;
|
|
23
|
-
export declare function requestBodyCall(input:
|
|
11
|
+
export declare function requestBodyCall(input: Omit<CallRequestClaim, "action"> & Readonly<{
|
|
24
12
|
directory: string;
|
|
25
|
-
}>): Promise<AkuId>;
|
|
26
|
-
export declare
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
export {
|
|
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
|
+
}>;
|
|
36
|
+
type BodyDeliverInput = ContractRequestInput<DeliverRequestClaim>;
|
|
37
|
+
export declare function requestBodyDeliver(input: BodyDeliverInput & Readonly<{
|
|
38
|
+
id?: never;
|
|
39
|
+
}>): Promise<UpstreamRequestOutcome>;
|
|
40
|
+
export declare function requestBodyDeliver(input: BodyDeliverInput & Readonly<{
|
|
41
|
+
id: string;
|
|
42
|
+
}>): Promise<UpstreamRequestOutcome | ForwardedDeliveryReference>;
|
|
43
|
+
type BodyReviewInput = ContractRequestInput<ReviewRequestClaim>;
|
|
44
|
+
export declare function requestBodyReview(input: BodyReviewInput & Readonly<{
|
|
45
|
+
id?: never;
|
|
46
|
+
}>): Promise<UpstreamRequestOutcome>;
|
|
47
|
+
export declare function requestBodyReview(input: BodyReviewInput & Readonly<{
|
|
48
|
+
id: string;
|
|
49
|
+
}>): Promise<UpstreamRequestOutcome | ForwardedReviewReference>;
|