@astrosheep/keiyaku 4.0.0 → 4.0.2
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 +133 -8
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +13 -5
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -32
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +134 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +262 -46
- package/build/src/akuma/abort.d.ts +2 -0
- package/build/src/akuma/abort.js +50 -0
- package/build/src/akuma/akuma.d.ts +50 -33
- package/build/src/akuma/akuma.js +175 -127
- package/build/src/akuma/archetype.d.ts +14 -5
- package/build/src/akuma/archetype.js +85 -39
- package/build/src/akuma/body.d.ts +3 -5
- package/build/src/akuma/body.js +490 -183
- package/build/src/akuma/coordinate.d.ts +9 -0
- package/build/src/akuma/coordinate.js +22 -0
- package/build/src/akuma/heart/facts.d.ts +88 -45
- package/build/src/akuma/heart/facts.js +19 -8
- package/build/src/akuma/heart/index.d.ts +64 -55
- package/build/src/akuma/heart/index.js +172 -252
- package/build/src/akuma/heart/rows.d.ts +38 -83
- package/build/src/akuma/heart/rows.js +117 -155
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +61 -22
- package/build/src/akuma/heart/soul.d.ts +8 -0
- package/build/src/akuma/heart/soul.js +136 -0
- package/build/src/akuma/heart/storage.d.ts +47 -0
- package/build/src/akuma/heart/storage.js +224 -0
- package/build/src/akuma/heart/tells.d.ts +12 -0
- package/build/src/akuma/heart/tells.js +79 -0
- package/build/src/akuma/heart/timeline.d.ts +15 -0
- package/build/src/akuma/heart/timeline.js +86 -0
- package/build/src/akuma/identity.d.ts +2 -2
- package/build/src/akuma/identity.js +9 -9
- package/build/src/akuma/index.d.ts +10 -3
- package/build/src/akuma/index.js +7 -1
- package/build/src/akuma/projection.d.ts +176 -0
- package/build/src/akuma/projection.js +256 -0
- package/build/src/akuma/provider-recipe.d.ts +24 -0
- package/build/src/akuma/provider-recipe.js +100 -0
- package/build/src/akuma/provider.d.ts +67 -13
- package/build/src/akuma/provider.js +172 -105
- package/build/src/akuma/providers/acp/core.d.ts +19 -0
- package/build/src/akuma/providers/acp/core.js +159 -0
- package/build/src/akuma/providers/acp/events.d.ts +20 -0
- package/build/src/akuma/providers/acp/events.js +73 -0
- package/build/src/akuma/providers/acp/index.d.ts +12 -0
- package/build/src/akuma/providers/acp/index.js +94 -0
- package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
- package/build/src/akuma/providers/claude/events.js +238 -0
- package/build/src/akuma/providers/claude/index.d.ts +47 -0
- package/build/src/akuma/providers/claude/index.js +279 -0
- package/build/src/akuma/providers/claude/input.d.ts +13 -0
- package/build/src/akuma/providers/claude/input.js +109 -0
- package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
- package/build/src/akuma/providers/codex-app-server/events.js +15 -12
- package/build/src/akuma/providers/codex-app-server/index.d.ts +15 -13
- package/build/src/akuma/providers/codex-app-server/index.js +77 -33
- package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
- package/build/src/akuma/providers/grok-build/index.js +70 -0
- package/build/src/akuma/providers/index.d.ts +5 -3
- package/build/src/akuma/providers/index.js +35 -56
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +54 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +235 -0
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +33 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +308 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +26 -0
- package/build/src/akuma/providers/opencode-sdk/session.js +63 -0
- package/build/src/akuma/providers/pi/events.d.ts +33 -0
- package/build/src/akuma/providers/pi/events.js +166 -0
- package/build/src/akuma/providers/pi/index.d.ts +11 -0
- package/build/src/akuma/providers/pi/index.js +191 -0
- package/build/src/akuma/publication.d.ts +3 -3
- package/build/src/akuma/publication.js +28 -40
- package/build/src/akuma/requests.d.ts +9 -6
- package/build/src/akuma/requests.js +95 -65
- package/build/src/alias/index.d.ts +4 -3
- package/build/src/alias/index.js +12 -13
- package/build/src/body/decode.js +7 -1
- package/build/src/body/region.d.ts +2 -0
- package/build/src/body/region.js +77 -7
- package/build/src/body/render.js +2 -1
- package/build/src/body/shape.js +7 -1
- package/build/src/body/verification.js +19 -4
- package/build/src/cli/accepted.d.ts +18 -12
- package/build/src/cli/accepted.js +73 -34
- package/build/src/cli/actor.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +44 -19
- package/build/src/cli/commands/akuma-invoke.js +101 -52
- package/build/src/cli/commands/akuma.d.ts +27 -9
- package/build/src/cli/commands/akuma.js +151 -80
- package/build/src/cli/commands/contract.d.ts +155 -0
- package/build/src/cli/commands/contract.js +20 -0
- package/build/src/cli/commands/install.js +2 -0
- package/build/src/cli/commands/task-invoke.d.ts +19 -4
- package/build/src/cli/commands/task-invoke.js +65 -17
- package/build/src/cli/commands/task-query.d.ts +5 -0
- package/build/src/cli/commands/task-query.js +247 -0
- package/build/src/cli/commands/task.d.ts +3 -1
- package/build/src/cli/commands/task.js +52 -14
- package/build/src/cli/coordinates.d.ts +18 -0
- package/build/src/cli/coordinates.js +120 -0
- package/build/src/cli/draft.d.ts +8 -0
- package/build/src/cli/draft.js +96 -0
- package/build/src/cli/invoke.d.ts +9 -3
- package/build/src/cli/invoke.js +287 -108
- package/build/src/cli/main.js +54 -7
- package/build/src/cli/parse.d.ts +21 -117
- package/build/src/cli/parse.js +79 -84
- package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
- package/build/src/cli/render/akuma-tool-command.js +144 -0
- package/build/src/cli/render/akuma-tool.d.ts +4 -2
- package/build/src/cli/render/akuma-tool.js +35 -5
- package/build/src/cli/render/akuma.d.ts +3 -1
- package/build/src/cli/render/akuma.js +247 -212
- package/build/src/cli/render/audit.d.ts +3 -0
- package/build/src/cli/render/audit.js +104 -0
- package/build/src/cli/render/catalog.d.ts +2 -0
- package/build/src/cli/render/catalog.js +16 -0
- package/build/src/cli/render/contract.d.ts +3 -3
- package/build/src/cli/render/contract.js +200 -54
- package/build/src/cli/render/kanshi.js +272 -129
- package/build/src/cli/render/receipt.d.ts +19 -0
- package/build/src/cli/render/receipt.js +106 -0
- package/build/src/cli/render/refusal.d.ts +16 -2
- package/build/src/cli/render/refusal.js +88 -3
- package/build/src/cli/render/region.d.ts +2 -0
- package/build/src/cli/render/region.js +17 -0
- package/build/src/cli/render/task.d.ts +2 -1
- package/build/src/cli/render/task.js +223 -60
- package/build/src/cli/render/terminal.d.ts +20 -0
- package/build/src/cli/render/terminal.js +121 -0
- package/build/src/cli/render/text.js +11 -3
- package/build/src/cli/result.d.ts +126 -19
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +3 -0
- package/build/src/contract-worktree.d.ts +44 -0
- package/build/src/contract-worktree.js +251 -0
- package/build/src/coordination/durable-file.d.ts +5 -1
- package/build/src/coordination/durable-file.js +57 -10
- package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
- package/build/src/coordination/sqlite-transaction-lock.js +22 -5
- package/build/src/core/facts/codec.js +23 -4
- package/build/src/core/facts/eligibility.d.ts +1 -10
- package/build/src/core/facts/eligibility.js +0 -49
- package/build/src/core/facts/fold.js +1 -6
- package/build/src/core/facts/gate.d.ts +1 -0
- package/build/src/core/facts/gate.js +1 -0
- package/build/src/core/facts/observation.d.ts +3 -0
- package/build/src/core/facts/observation.js +12 -0
- package/build/src/core/facts/types.d.ts +10 -3
- package/build/src/core/subject.js +2 -2
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +3 -18
- package/build/src/core/verbs/bind.js +2 -16
- package/build/src/core/verbs/deliver.d.ts +1 -1
- package/build/src/core/verbs/deliver.js +14 -4
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +7 -9
- package/build/src/dispatch/index.d.ts +5 -3
- package/build/src/dispatch/index.js +30 -21
- package/build/src/duration.d.ts +10 -0
- package/build/src/duration.js +22 -0
- package/build/src/git/admission.d.ts +2 -2
- package/build/src/git/admission.js +33 -23
- package/build/src/git/hooks.d.ts +15 -0
- package/build/src/git/hooks.js +70 -18
- package/build/src/git/identity.d.ts +5 -1
- package/build/src/git/identity.js +23 -4
- package/build/src/git/integration.d.ts +48 -0
- package/build/src/git/integration.js +250 -0
- package/build/src/git/observe.d.ts +29 -15
- package/build/src/git/observe.js +185 -76
- package/build/src/git/read-observation.d.ts +41 -0
- package/build/src/git/read-observation.js +361 -0
- package/build/src/git/reconcile.d.ts +17 -5
- package/build/src/git/reconcile.js +305 -109
- package/build/src/git/repository.d.ts +41 -18
- package/build/src/git/repository.js +220 -114
- package/build/src/git/scratch.d.ts +17 -0
- package/build/src/git/scratch.js +73 -0
- package/build/src/git/target-placement.d.ts +92 -0
- package/build/src/git/target-placement.js +375 -0
- package/build/src/git/tender.d.ts +49 -0
- package/build/src/git/tender.js +63 -0
- package/build/src/git/terminal-seal.d.ts +24 -0
- package/build/src/git/terminal-seal.js +89 -0
- package/build/src/git/tree.d.ts +2 -2
- package/build/src/git/tree.js +4 -0
- package/build/src/git/workspace.d.ts +53 -0
- package/build/src/git/workspace.js +139 -0
- package/build/src/identity/selector.d.ts +6 -0
- package/build/src/identity/selector.js +19 -0
- package/build/src/index.d.ts +4 -2
- package/build/src/index.js +2 -1
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +7 -3
- package/build/src/kanshi/read.js +245 -45
- package/build/src/kanshi/report.d.ts +81 -6
- package/build/src/kanshi/select.d.ts +5 -0
- package/build/src/kanshi/select.js +33 -1
- package/build/src/library/address.d.ts +57 -0
- package/build/src/library/address.js +165 -0
- package/build/src/library/akuma-creation.d.ts +16 -7
- package/build/src/library/akuma-creation.js +96 -22
- package/build/src/library/audit.d.ts +18 -0
- package/build/src/library/audit.js +44 -0
- package/build/src/library/bind.d.ts +21 -0
- package/build/src/library/bind.js +56 -0
- package/build/src/library/catalog.d.ts +58 -0
- package/build/src/library/catalog.js +69 -0
- package/build/src/library/configuration.d.ts +6 -15
- package/build/src/library/configuration.js +14 -17
- package/build/src/library/contract.d.ts +23 -49
- package/build/src/library/contract.js +171 -185
- package/build/src/library/delivery.d.ts +24 -0
- package/build/src/library/delivery.js +21 -0
- package/build/src/library/fleet.d.ts +65 -0
- package/build/src/library/fleet.js +153 -0
- package/build/src/library/input.d.ts +3 -0
- package/build/src/library/input.js +19 -0
- package/build/src/library/keiyaku.d.ts +18 -3
- package/build/src/library/keiyaku.js +12 -1
- package/build/src/library/mutation.d.ts +39 -0
- package/build/src/library/mutation.js +37 -0
- package/build/src/library/reconcile.d.ts +29 -0
- package/build/src/library/reconcile.js +179 -0
- package/build/src/library/refusal.d.ts +21 -0
- package/build/src/library/refusal.js +29 -0
- package/build/src/library/region.d.ts +14 -1
- package/build/src/library/region.js +18 -4
- package/build/src/library/repo.d.ts +4 -13
- package/build/src/library/repo.js +14 -24
- package/build/src/protocol/attempt.d.ts +16 -3
- package/build/src/protocol/attempt.js +41 -10
- package/build/src/protocol/bind.d.ts +9 -2
- package/build/src/protocol/bind.js +48 -40
- package/build/src/protocol/intent.d.ts +57 -20
- package/build/src/protocol/intent.js +55 -79
- package/build/src/protocol/operations.d.ts +152 -43
- package/build/src/protocol/operations.js +482 -166
- package/build/src/protocol/outcome.d.ts +14 -3
- package/build/src/protocol/outcome.js +11 -3
- package/build/src/protocol/placement.d.ts +41 -0
- package/build/src/protocol/placement.js +147 -0
- package/build/src/protocol/read/documents.d.ts +2 -2
- package/build/src/protocol/read/documents.js +4 -4
- package/build/src/protocol/read/status.d.ts +18 -5
- package/build/src/protocol/read/status.js +73 -13
- package/build/src/protocol/run.d.ts +49 -7
- package/build/src/protocol/run.js +53 -25
- package/build/src/runtime/proc/line-rpc.d.ts +4 -8
- package/build/src/runtime/proc/line-rpc.js +22 -28
- package/build/src/runtime/proc/run.d.ts +23 -21
- package/build/src/runtime/proc/run.js +123 -89
- package/build/src/runtime/proc/stdio.d.ts +18 -0
- package/build/src/runtime/proc/stdio.js +58 -0
- package/build/src/settings.d.ts +7 -1
- package/build/src/settings.js +32 -17
- package/build/src/settlement/fence.d.ts +5 -0
- package/build/src/settlement/fence.js +14 -0
- package/build/src/settlement/holder.d.ts +35 -4
- package/build/src/settlement/holder.js +127 -28
- package/build/src/settlement/settle.d.ts +9 -1
- package/build/src/settlement/settle.js +74 -37
- package/build/src/task/board.d.ts +23 -5
- package/build/src/task/board.js +17 -10
- package/build/src/task/compose.d.ts +2 -2
- package/build/src/task/compose.js +18 -10
- package/build/src/task/context.d.ts +3 -3
- package/build/src/task/context.js +15 -20
- package/build/src/task/document.d.ts +2 -1
- package/build/src/task/document.js +15 -5
- package/build/src/task/index.d.ts +27 -15
- package/build/src/task/index.js +57 -35
- package/build/src/task/operations.d.ts +38 -13
- package/build/src/task/operations.js +80 -46
- package/build/src/task/query.d.ts +67 -0
- package/build/src/task/query.js +279 -0
- package/build/src/task/store.d.ts +5 -7
- package/build/src/task/store.js +43 -28
- package/build/src/verification/declaration.d.ts +1 -0
- package/build/src/verification/execution.d.ts +51 -0
- package/build/src/verification/execution.js +108 -0
- package/build/src/workspace-place.d.ts +41 -0
- package/build/src/workspace-place.js +386 -0
- package/build/src/world.d.ts +24 -0
- package/build/src/world.js +136 -0
- package/package.json +8 -4
- package/build/src/akuma/activity.d.ts +0 -66
- package/build/src/akuma/activity.js +0 -139
- package/build/src/akuma/providers/claude.js +0 -305
- package/build/src/context-root.d.ts +0 -4
- package/build/src/context-root.js +0 -15
- package/build/src/git/delivery.d.ts +0 -20
- package/build/src/git/delivery.js +0 -109
- package/build/src/git/verification.d.ts +0 -14
- package/build/src/git/verification.js +0 -56
- package/build/src/protocol/read/audit.d.ts +0 -25
- package/build/src/protocol/read/audit.js +0 -39
- package/build/src/verification/producer.d.ts +0 -23
- package/build/src/verification/producer.js +0 -54
package/build/src/akuma/akuma.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { readdir } from "node:fs/promises";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
-
import { spawnAkumaBody } from "./body.js";
|
|
5
|
-
import { HeldAkumaLeash, activitySlice, life,
|
|
4
|
+
import { CONTROL_RESPONSE_MS, spawnAkumaBody } from "./body.js";
|
|
5
|
+
import { HeldAkumaLeash, activitySlice, life, lifeAt, probeLeash, readHeart, readLastAnsweredTurn, readForkPoint, readKill, readSeal, readSoul, recordTell, requestPause, requestStop, } from "./heart/index.js";
|
|
6
6
|
import { akuIdFromDirectoryName, akumaPaths, akumaRunRoot, parseAkuId, pathsForAkuId, archetypeName, } from "./identity.js";
|
|
7
|
-
import {
|
|
7
|
+
import { ordinarySelectedCount, ordinarySnapshotBudget, projectTurns, selectActivitySnapshot, selectHistory, selectSnapshot, } from "./projection.js";
|
|
8
8
|
import { listArchetypes as readArchetypes, loadArchetype } from "./archetype.js";
|
|
9
9
|
import { publishAkuma } from "./publication.js";
|
|
10
|
-
import {
|
|
10
|
+
import { resolveProviderExecution } from "./providers/index.js";
|
|
11
11
|
import { injectedBodyRequests, requestBodyCall } from "./requests.js";
|
|
12
|
-
import { probeProcessTree, putDownProcessTree } from "../runtime/proc/run.js";
|
|
13
12
|
import { settings as readSettings } from "../settings.js";
|
|
14
13
|
const POLL_MS = 25;
|
|
15
|
-
const KILL_GRACE_MS = 1_000;
|
|
16
14
|
export class AkumaNotBornError extends Error {
|
|
17
15
|
id;
|
|
18
16
|
kind = "akuma-not-born";
|
|
@@ -27,7 +25,7 @@ function wait(milliseconds) {
|
|
|
27
25
|
}
|
|
28
26
|
async function takeLeashUntil(paths, deadline) {
|
|
29
27
|
for (;;) {
|
|
30
|
-
const leash = HeldAkumaLeash.try(paths);
|
|
28
|
+
const leash = await HeldAkumaLeash.try(paths);
|
|
31
29
|
if (leash !== null)
|
|
32
30
|
return leash;
|
|
33
31
|
if (performance.now() >= deadline)
|
|
@@ -35,74 +33,77 @@ async function takeLeashUntil(paths, deadline) {
|
|
|
35
33
|
await wait(POLL_MS);
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
|
-
function recordTellBody(paths, body) {
|
|
36
|
+
async function recordTellBody(paths, akuma, body) {
|
|
39
37
|
const id = randomUUID();
|
|
40
|
-
const admitted = recordTell(paths, { id, body, recordedAt: new Date().toISOString() });
|
|
41
|
-
|
|
38
|
+
const admitted = await recordTell(paths, { kind: "tell", id, body, recordedAt: new Date().toISOString() });
|
|
39
|
+
if (admitted.kind === "not-born")
|
|
40
|
+
throw new AkumaNotBornError(akuma);
|
|
41
|
+
return { kind: "recorded", tellId: admitted.tell.id };
|
|
42
42
|
}
|
|
43
|
-
async function wakeTell(paths,
|
|
44
|
-
const soul = readSoul(paths);
|
|
45
|
-
if (soul === null)
|
|
46
|
-
throw new Error(`Akuma ${akuma} has no soul`);
|
|
43
|
+
async function wakeTell(paths, tellId) {
|
|
47
44
|
try {
|
|
48
45
|
await spawnAkumaBody({ paths });
|
|
49
|
-
return {
|
|
46
|
+
return { admission: { tellId, fact: "recorded" }, wake: "spawned" };
|
|
50
47
|
}
|
|
51
48
|
catch (error) {
|
|
52
49
|
return {
|
|
53
|
-
|
|
54
|
-
state: "recorded",
|
|
50
|
+
admission: { tellId, fact: "recorded" },
|
|
55
51
|
wake: { kind: "failed", diagnostic: error instanceof Error ? error.message : String(error) },
|
|
56
52
|
};
|
|
57
53
|
}
|
|
58
54
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
return { kind: "gone", end: null };
|
|
62
|
-
const probe = probeProcessTree(snapshot.latestBody.collar);
|
|
63
|
-
if (probe.kind === "gone")
|
|
64
|
-
return { kind: "gone", end: snapshot.latestBody.end ?? null };
|
|
65
|
-
return probe;
|
|
66
|
-
}
|
|
67
|
-
function bornListRow(paths, expected, snapshot = readHeart(paths)) {
|
|
55
|
+
async function bornListRow(paths, expected, snapshot) {
|
|
56
|
+
snapshot ??= await readHeart(paths);
|
|
68
57
|
if (snapshot.soul === null)
|
|
69
58
|
throw new AkumaNotBornError(expected);
|
|
70
59
|
if (snapshot.soul.id !== expected)
|
|
71
60
|
throw new Error("Akuma soul does not match its coordinate");
|
|
72
|
-
const
|
|
61
|
+
const currentLife = life({
|
|
62
|
+
leash: await probeLeash(paths),
|
|
63
|
+
body: snapshot.latestBody,
|
|
64
|
+
kill: snapshot.latestKill,
|
|
65
|
+
});
|
|
73
66
|
return {
|
|
74
67
|
id: snapshot.soul.id,
|
|
75
68
|
archetype: snapshot.soul.archetype,
|
|
76
69
|
...(snapshot.soul.description === undefined ? {} : { description: snapshot.soul.description }),
|
|
77
|
-
life:
|
|
78
|
-
|
|
70
|
+
life: currentLife,
|
|
71
|
+
lifeAt: lifeAt(currentLife, snapshot.latestBody, snapshot.latestKill, snapshot.soul.createdAt),
|
|
79
72
|
confinement: snapshot.soul.confinement,
|
|
80
73
|
pending: snapshot.pending.map((tell) => tell.id),
|
|
81
74
|
};
|
|
82
75
|
}
|
|
83
|
-
function bornStatus(paths, expected) {
|
|
84
|
-
const snapshot = readHeart(paths);
|
|
76
|
+
async function bornStatus(paths, expected, budget) {
|
|
77
|
+
const snapshot = await readHeart(paths);
|
|
85
78
|
if (snapshot.soul === null)
|
|
86
79
|
throw new AkumaNotBornError(expected);
|
|
87
|
-
const current = bornListRow(paths, expected, snapshot);
|
|
88
|
-
const
|
|
80
|
+
const current = await bornListRow(paths, expected, snapshot);
|
|
81
|
+
const resumeUnsupported = current.life === "stranded"
|
|
82
|
+
&& snapshot.latestSession?.provider === snapshot.soul.provider.name
|
|
83
|
+
&& resolveProviderExecution(snapshot.soul.provider).adapter.resume === undefined;
|
|
84
|
+
const slice = await activitySlice(paths, { limit: Number.MAX_SAFE_INTEGER });
|
|
89
85
|
return {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
...(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const slice = activitySlice(paths, { limit: 5_000 });
|
|
98
|
-
return selectActivitySnapshot(slice.rows, {
|
|
99
|
-
pending: snapshot.pending,
|
|
100
|
-
lowestRetained: slice.lowestRetained,
|
|
101
|
-
highest: slice.highest,
|
|
102
|
-
});
|
|
103
|
-
})(),
|
|
86
|
+
id: current.id,
|
|
87
|
+
life: current.life,
|
|
88
|
+
...(snapshot.soul.readonly === undefined ? {} : { readonly: snapshot.soul.readonly }),
|
|
89
|
+
...(resumeUnsupported ? { strandedReason: "resume-unsupported" } : {}),
|
|
90
|
+
timeline: budget === undefined
|
|
91
|
+
? selectActivitySnapshot(slice.rows)
|
|
92
|
+
: selectSnapshot(projectTurns(slice.rows), budget),
|
|
104
93
|
};
|
|
105
94
|
}
|
|
95
|
+
/** Package-internal action observation; it uses the same snapshot selector as status. */
|
|
96
|
+
export async function readActionFeedbackStatus(worldPath, id) {
|
|
97
|
+
return await bornStatus(pathsForAkuId(worldPath, id), id);
|
|
98
|
+
}
|
|
99
|
+
/** Package-internal budgeted observation; Fleet allocates, Akuma still selects. */
|
|
100
|
+
export async function readBudgetedStatus(worldPath, id, input) {
|
|
101
|
+
if (!Number.isSafeInteger(input.ordinaryBudget) || input.ordinaryBudget < 0) {
|
|
102
|
+
throw new TypeError("ordinary budget must be a nonnegative safe integer");
|
|
103
|
+
}
|
|
104
|
+
const status = await bornStatus(pathsForAkuId(worldPath, id), id, ordinarySnapshotBudget(input.ordinaryBudget));
|
|
105
|
+
return { status, ordinarySelected: ordinarySelectedCount(status.timeline) };
|
|
106
|
+
}
|
|
106
107
|
function diagnostic(error) {
|
|
107
108
|
return error instanceof Error ? error.message : String(error);
|
|
108
109
|
}
|
|
@@ -116,10 +117,10 @@ export class AkumaHandle {
|
|
|
116
117
|
get paths() {
|
|
117
118
|
return pathsForAkuId(this.worldPath, this.id);
|
|
118
119
|
}
|
|
119
|
-
status() {
|
|
120
|
-
return bornStatus(this.paths, this.id);
|
|
120
|
+
async status() {
|
|
121
|
+
return await bornStatus(this.paths, this.id);
|
|
121
122
|
}
|
|
122
|
-
history(input = {}) {
|
|
123
|
+
async history(input = {}) {
|
|
123
124
|
if (input.before !== undefined && input.since !== undefined) {
|
|
124
125
|
throw new TypeError("Akuma history before and since are mutually exclusive");
|
|
125
126
|
}
|
|
@@ -132,13 +133,17 @@ export class AkumaHandle {
|
|
|
132
133
|
if (!Number.isSafeInteger(limit) || limit <= 0 || limit > 5_000) {
|
|
133
134
|
throw new TypeError("Akuma history limit must be a positive safe integer no greater than 5000");
|
|
134
135
|
}
|
|
135
|
-
const slice = activitySlice(this.paths, {
|
|
136
|
+
const slice = await activitySlice(this.paths, {
|
|
136
137
|
...(input.before === undefined ? {} : { before: input.before }),
|
|
137
138
|
...(input.since === undefined ? {} : { since: input.since }),
|
|
138
139
|
limit: 5_000,
|
|
139
140
|
});
|
|
140
|
-
return
|
|
141
|
-
|
|
141
|
+
return selectHistory(projectTurns(slice.rows, {
|
|
142
|
+
lowestRetained: slice.lowestRetained,
|
|
143
|
+
highest: slice.highest,
|
|
144
|
+
}), {
|
|
145
|
+
...(input.before === undefined ? {} : { before: input.before }),
|
|
146
|
+
...(input.since === undefined ? {} : { since: input.since }),
|
|
142
147
|
limit,
|
|
143
148
|
});
|
|
144
149
|
}
|
|
@@ -149,66 +154,73 @@ export class AkumaHandle {
|
|
|
149
154
|
}
|
|
150
155
|
const deadline = options.timeoutMs === undefined ? undefined : performance.now() + options.timeoutMs;
|
|
151
156
|
for (;;) {
|
|
152
|
-
const status = this.status();
|
|
157
|
+
const status = await this.status();
|
|
153
158
|
if (predicate(status) || (deadline !== undefined && performance.now() >= deadline))
|
|
154
159
|
return status;
|
|
155
160
|
await wait(deadline === undefined ? POLL_MS : Math.min(POLL_MS, Math.max(0, deadline - performance.now())));
|
|
156
161
|
}
|
|
157
162
|
}
|
|
158
163
|
async tell(body) {
|
|
159
|
-
const recorded = recordTellBody(this.paths, body);
|
|
160
|
-
|
|
161
|
-
throw new Error(`Akuma ${this.id} is dead`);
|
|
162
|
-
return await wakeTell(this.paths, this.id, recorded.id);
|
|
164
|
+
const recorded = await recordTellBody(this.paths, this.id, body);
|
|
165
|
+
return await wakeTell(this.paths, recorded.tellId);
|
|
163
166
|
}
|
|
164
167
|
async interrupt(body) {
|
|
165
|
-
|
|
166
|
-
|
|
168
|
+
const request = await requestPause(this.paths, new Date().toISOString());
|
|
169
|
+
if (request.kind === "not-born") {
|
|
170
|
+
throw new AkumaNotBornError(this.id);
|
|
171
|
+
}
|
|
167
172
|
let putDown = "was-idle";
|
|
168
|
-
let leash = HeldAkumaLeash.try(this.paths);
|
|
173
|
+
let leash = await HeldAkumaLeash.try(this.paths);
|
|
169
174
|
if (leash === null) {
|
|
170
|
-
leash = await takeLeashUntil(this.paths, performance.now() +
|
|
175
|
+
leash = await takeLeashUntil(this.paths, performance.now() + CONTROL_RESPONSE_MS);
|
|
171
176
|
putDown = "self-aborted";
|
|
172
177
|
}
|
|
173
178
|
if (leash === null) {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
const body = (await readHeart(this.paths)).latestBody;
|
|
180
|
+
return { kind: "unavailable", evidence: body?.sequence === request.body.sequence && body.hung !== undefined
|
|
181
|
+
? "hung"
|
|
182
|
+
: "unavailable" };
|
|
183
|
+
}
|
|
184
|
+
const settledBody = (await readHeart(this.paths)).latestBody;
|
|
185
|
+
if (settledBody?.sequence !== request.body.sequence || settledBody.end === undefined) {
|
|
186
|
+
try {
|
|
187
|
+
await leash.clearPause(this.paths);
|
|
179
188
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
return { kind: "unstoppable", evidence };
|
|
189
|
+
finally {
|
|
190
|
+
leash.release();
|
|
183
191
|
}
|
|
184
|
-
|
|
185
|
-
if (leash === null)
|
|
186
|
-
return { kind: "unstoppable", evidence: "leash-held-after-put-down" };
|
|
187
|
-
putDown = "collar";
|
|
192
|
+
return { kind: "unavailable", evidence: "untidy" };
|
|
188
193
|
}
|
|
194
|
+
if (request.body.end !== undefined || settledBody.end !== "put-down")
|
|
195
|
+
putDown = "was-idle";
|
|
189
196
|
let recorded;
|
|
190
197
|
try {
|
|
191
|
-
|
|
192
|
-
|
|
198
|
+
const id = randomUUID();
|
|
199
|
+
const admitted = await leash.recordInterruptTell(this.paths, {
|
|
200
|
+
kind: "tell",
|
|
201
|
+
id,
|
|
202
|
+
body,
|
|
203
|
+
recordedAt: new Date().toISOString(),
|
|
204
|
+
});
|
|
205
|
+
if (admitted.kind === "not-born")
|
|
206
|
+
throw new AkumaNotBornError(this.id);
|
|
207
|
+
recorded = { kind: "recorded", tellId: admitted.tell.id };
|
|
193
208
|
}
|
|
194
209
|
finally {
|
|
195
210
|
leash.release();
|
|
196
211
|
}
|
|
197
|
-
|
|
198
|
-
return { kind: "interrupted", putDown, tell: { kind: "refused-dead" } };
|
|
199
|
-
}
|
|
200
|
-
return { kind: "interrupted", putDown, tell: await wakeTell(this.paths, this.id, recorded.id) };
|
|
212
|
+
return { kind: "interrupted", putDown, tell: await wakeTell(this.paths, recorded.tellId) };
|
|
201
213
|
}
|
|
202
214
|
async fork(input) {
|
|
203
|
-
const source = readSoul(this.paths);
|
|
215
|
+
const source = await readSoul(this.paths);
|
|
204
216
|
if (source === null)
|
|
205
217
|
throw new AkumaNotBornError(this.id);
|
|
206
218
|
if (source.id !== this.id)
|
|
207
219
|
throw new Error("Akuma soul does not match its coordinate");
|
|
208
|
-
const adapter =
|
|
220
|
+
const adapter = resolveProviderExecution(source.provider).adapter;
|
|
209
221
|
if (adapter.fork === undefined)
|
|
210
222
|
return { kind: "provider-cannot-fork", provider: source.provider.name };
|
|
211
|
-
const point = readForkPoint(this.paths, input.at);
|
|
223
|
+
const point = await readForkPoint(this.paths, input.at);
|
|
212
224
|
if (point === null)
|
|
213
225
|
return { kind: "unknown-history", at: input.at };
|
|
214
226
|
if (point.provider !== source.provider.name)
|
|
@@ -241,6 +253,7 @@ export class AkumaHandle {
|
|
|
241
253
|
...(source.description === undefined ? {} : { description: source.description }),
|
|
242
254
|
provider: source.provider,
|
|
243
255
|
options: source.options,
|
|
256
|
+
...(source.readonly === undefined ? {} : { readonly: source.readonly }),
|
|
244
257
|
cwd: source.cwd,
|
|
245
258
|
origin: { kind: "fork", parent: this.id, at: input.at },
|
|
246
259
|
confinement: source.confinement,
|
|
@@ -256,57 +269,77 @@ export class AkumaHandle {
|
|
|
256
269
|
}
|
|
257
270
|
async kill() {
|
|
258
271
|
const at = new Date().toISOString();
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
272
|
+
const request = await requestStop(this.paths, at);
|
|
273
|
+
if (request.kind !== "requested")
|
|
274
|
+
return request.kind;
|
|
275
|
+
const target = request.body;
|
|
276
|
+
const graceDeadline = performance.now() + CONTROL_RESPONSE_MS;
|
|
277
|
+
const leash = await takeLeashUntil(this.paths, graceDeadline);
|
|
278
|
+
if (await readKill(this.paths, target.sequence) !== null) {
|
|
279
|
+
leash?.release();
|
|
280
|
+
return "killed";
|
|
281
|
+
}
|
|
282
|
+
if (leash === null) {
|
|
283
|
+
if (await readKill(this.paths, target.sequence) !== null)
|
|
284
|
+
return "killed";
|
|
285
|
+
const body = (await readHeart(this.paths)).latestBody;
|
|
286
|
+
return body?.sequence === target.sequence && body.hung !== undefined ? "hung" : "unavailable";
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
const settledBody = (await readHeart(this.paths)).latestBody;
|
|
290
|
+
if (settledBody?.sequence !== target.sequence)
|
|
291
|
+
return await readKill(this.paths, target.sequence) === null ? "unavailable" : "killed";
|
|
292
|
+
if (settledBody.end !== "put-down") {
|
|
293
|
+
await leash.clearStop(this.paths);
|
|
294
|
+
return "untidy";
|
|
295
|
+
}
|
|
296
|
+
const settled = await leash.settleStop(this.paths, target.sequence);
|
|
297
|
+
if (settled === null)
|
|
267
298
|
return "unavailable";
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
299
|
+
return "killed";
|
|
300
|
+
}
|
|
301
|
+
finally {
|
|
302
|
+
leash.release();
|
|
271
303
|
}
|
|
272
|
-
const releaseDeadline = performance.now() + KILL_GRACE_MS;
|
|
273
|
-
while (probeLeash(this.paths) === "held" && performance.now() < releaseDeadline)
|
|
274
|
-
await wait(POLL_MS);
|
|
275
|
-
if (probeLeash(this.paths) === "held")
|
|
276
|
-
return "unavailable";
|
|
277
|
-
return recordDeath(this.paths, { evidence: "killed", at }) === "already-dead" ? "already-dead" : "killed";
|
|
278
304
|
}
|
|
279
|
-
lastAnswer() {
|
|
280
|
-
const turn = readLastAnsweredTurn(this.paths);
|
|
281
|
-
return turn?.outcome.kind === "answered"
|
|
305
|
+
async lastAnswer() {
|
|
306
|
+
const turn = await readLastAnsweredTurn(this.paths);
|
|
307
|
+
return turn?.end?.outcome.kind === "answered"
|
|
308
|
+
? { kind: "answer", answer: turn.end.outcome.answer }
|
|
309
|
+
: { kind: "no-answer" };
|
|
282
310
|
}
|
|
283
311
|
}
|
|
284
312
|
export class Akuma {
|
|
285
313
|
path;
|
|
286
|
-
|
|
287
|
-
constructor(path,
|
|
314
|
+
configuredSettings;
|
|
315
|
+
constructor(path, configuredSettings) {
|
|
288
316
|
this.path = path;
|
|
289
|
-
this.
|
|
317
|
+
this.configuredSettings = configuredSettings;
|
|
318
|
+
}
|
|
319
|
+
static of(root, settings) {
|
|
320
|
+
if (typeof root !== "string")
|
|
321
|
+
throw new TypeError("Akuma.of root must be a WorldRoot");
|
|
322
|
+
return new Akuma(root, settings);
|
|
290
323
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
return new Akuma(path, input.settings ?? readSettings({ root: path }));
|
|
324
|
+
async settings() {
|
|
325
|
+
return this.configuredSettings ?? await readSettings({ root: this.path });
|
|
294
326
|
}
|
|
295
327
|
of(input) {
|
|
296
328
|
return new AkumaHandle(parseAkuId(input.id).id, this.path);
|
|
297
329
|
}
|
|
298
|
-
listArchetypes() {
|
|
299
|
-
return readArchetypes({ settings: this.settings });
|
|
330
|
+
async listArchetypes() {
|
|
331
|
+
return readArchetypes({ settings: await this.settings() });
|
|
300
332
|
}
|
|
301
333
|
async call(input) {
|
|
302
334
|
const name = archetypeName(input.archetype);
|
|
303
|
-
const archetype = loadArchetype({ name, settings: this.settings });
|
|
335
|
+
const archetype = await loadArchetype({ name, settings: await this.settings() });
|
|
304
336
|
const provider = archetype.adapter;
|
|
305
337
|
const cwd = resolve(input.cwd ?? this.path);
|
|
306
338
|
const recipe = Object.freeze({
|
|
307
339
|
...(archetype.description === undefined ? {} : { description: archetype.description }),
|
|
308
340
|
provider: archetype.provider,
|
|
309
341
|
options: archetype.options,
|
|
342
|
+
...(archetype.readonly === undefined ? {} : { readonly: archetype.readonly }),
|
|
310
343
|
confinement: provider.confinement({ cwd, options: archetype.options }),
|
|
311
344
|
});
|
|
312
345
|
const requests = injectedBodyRequests();
|
|
@@ -333,6 +366,7 @@ export class Akuma {
|
|
|
333
366
|
...(archetype.description === undefined ? {} : { description: archetype.description }),
|
|
334
367
|
provider: archetype.provider,
|
|
335
368
|
options: archetype.options,
|
|
369
|
+
...(archetype.readonly === undefined ? {} : { readonly: archetype.readonly }),
|
|
336
370
|
cwd,
|
|
337
371
|
origin: { kind: "direct" },
|
|
338
372
|
confinement: recipe.confinement,
|
|
@@ -342,11 +376,18 @@ export class Akuma {
|
|
|
342
376
|
});
|
|
343
377
|
return new AkumaHandle(published.id, this.path);
|
|
344
378
|
}
|
|
345
|
-
list() {
|
|
379
|
+
async list(input = {}) {
|
|
380
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
381
|
+
throw new TypeError("Akuma list input must be an object");
|
|
382
|
+
}
|
|
383
|
+
const unknown = Object.keys(input).find((key) => key !== "archetype");
|
|
384
|
+
if (unknown !== undefined)
|
|
385
|
+
throw new TypeError(`Akuma list input has unknown field: ${unknown}`);
|
|
386
|
+
const selected = input.archetype === undefined ? undefined : archetypeName(input.archetype);
|
|
346
387
|
const runRoot = akumaRunRoot(this.path);
|
|
347
388
|
let names;
|
|
348
389
|
try {
|
|
349
|
-
names =
|
|
390
|
+
names = (await readdir(runRoot, { withFileTypes: true }))
|
|
350
391
|
.filter((entry) => entry.isDirectory())
|
|
351
392
|
.map((entry) => entry.name)
|
|
352
393
|
.sort();
|
|
@@ -356,24 +397,31 @@ export class Akuma {
|
|
|
356
397
|
return { rows: [], searched: [runRoot] };
|
|
357
398
|
throw error;
|
|
358
399
|
}
|
|
359
|
-
const rows =
|
|
400
|
+
const rows = [];
|
|
401
|
+
for (const name of names) {
|
|
360
402
|
try {
|
|
361
403
|
const physical = akuIdFromDirectoryName(name);
|
|
404
|
+
if (selected !== undefined && physical.archetype !== selected)
|
|
405
|
+
continue;
|
|
362
406
|
const paths = akumaPaths({ runRoot, archetype: physical.archetype, suffix: physical.suffix });
|
|
363
|
-
const snapshot = readHeart(paths);
|
|
364
|
-
if (snapshot.soul !== null)
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
407
|
+
const snapshot = await readHeart(paths);
|
|
408
|
+
if (snapshot.soul !== null) {
|
|
409
|
+
rows.push(await bornListRow(paths, physical.id, snapshot));
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
if (await probeLeash(paths) === "held") {
|
|
413
|
+
rows.push({ id: physical.id, life: "unborn" });
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
const seal = await readSeal(paths);
|
|
417
|
+
rows.push(seal === null
|
|
418
|
+
? { id: physical.id, life: "unborn" }
|
|
419
|
+
: { id: physical.id, life: "stillborn", seal });
|
|
372
420
|
}
|
|
373
421
|
catch {
|
|
374
|
-
|
|
422
|
+
continue;
|
|
375
423
|
}
|
|
376
|
-
}
|
|
424
|
+
}
|
|
377
425
|
return {
|
|
378
426
|
rows,
|
|
379
427
|
searched: [runRoot],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Settings } from "../settings.js";
|
|
2
|
-
import {
|
|
3
|
-
import type
|
|
2
|
+
import type { ProviderAdapter } from "./provider.js";
|
|
3
|
+
import { type ProviderExecution, type ProviderOptions, type ReadonlyRestraint } from "./provider-recipe.js";
|
|
4
4
|
type DecodedArchetype = Readonly<{
|
|
5
5
|
name: string;
|
|
6
6
|
path: string;
|
|
@@ -8,24 +8,33 @@ type DecodedArchetype = Readonly<{
|
|
|
8
8
|
description?: string;
|
|
9
9
|
options: ProviderOptions;
|
|
10
10
|
}>;
|
|
11
|
+
export type ArchetypeCatalogRow = Readonly<{
|
|
12
|
+
name: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
}>;
|
|
11
16
|
type ArchetypeDefinition = DecodedArchetype & Readonly<{
|
|
12
17
|
adapter: ProviderAdapter;
|
|
13
18
|
}>;
|
|
14
19
|
type AdmittedArchetype = Omit<ArchetypeDefinition, "provider"> & Readonly<{
|
|
15
20
|
provider: ProviderExecution;
|
|
21
|
+
readonly?: ReadonlyRestraint;
|
|
16
22
|
}>;
|
|
17
23
|
export declare class AkumaArchetypeError extends Error {
|
|
18
24
|
readonly archetype: string;
|
|
19
25
|
readonly searched: readonly string[];
|
|
20
26
|
readonly reason: string;
|
|
21
27
|
readonly kind = "akuma-archetype";
|
|
22
|
-
constructor(archetype: string, searched: readonly string[], reason: string);
|
|
28
|
+
constructor(archetype: string, searched: readonly string[], reason: string, guidance?: string);
|
|
23
29
|
}
|
|
24
30
|
export declare function listArchetypes(input: Readonly<{
|
|
25
31
|
settings: Settings;
|
|
26
|
-
}>): readonly string[]
|
|
32
|
+
}>): Promise<readonly string[]>;
|
|
33
|
+
export declare function listArchetypeDefinitions(input: Readonly<{
|
|
34
|
+
settings: Settings;
|
|
35
|
+
}>): Promise<readonly ArchetypeCatalogRow[]>;
|
|
27
36
|
export declare function loadArchetype(input: Readonly<{
|
|
28
37
|
name: string;
|
|
29
38
|
settings: Settings;
|
|
30
|
-
}>): AdmittedArchetype
|
|
39
|
+
}>): Promise<AdmittedArchetype>;
|
|
31
40
|
export {};
|