@astrosheep/keiyaku 4.0.0 → 4.0.1
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 +2 -9
- 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 +11 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +9 -6
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +94 -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 +162 -45
- package/build/src/akuma/akuma.d.ts +33 -25
- package/build/src/akuma/akuma.js +93 -61
- package/build/src/akuma/archetype.d.ts +8 -0
- package/build/src/akuma/archetype.js +28 -9
- package/build/src/akuma/body.js +196 -84
- 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 +67 -15
- package/build/src/akuma/heart/facts.js +3 -3
- package/build/src/akuma/heart/index.d.ts +41 -29
- package/build/src/akuma/heart/index.js +72 -193
- package/build/src/akuma/heart/rows.d.ts +30 -53
- package/build/src/akuma/heart/rows.js +91 -111
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +55 -8
- package/build/src/akuma/heart/storage.d.ts +33 -0
- package/build/src/akuma/heart/storage.js +164 -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/index.d.ts +4 -2
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/projection.d.ts +97 -0
- package/build/src/akuma/projection.js +145 -0
- package/build/src/akuma/provider.d.ts +57 -11
- package/build/src/akuma/provider.js +57 -37
- package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
- package/build/src/akuma/providers/claude/events.js +185 -0
- package/build/src/akuma/providers/claude/index.d.ts +46 -0
- package/build/src/akuma/providers/claude/index.js +265 -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 +12 -12
- package/build/src/akuma/providers/codex-app-server/index.d.ts +13 -11
- package/build/src/akuma/providers/codex-app-server/index.js +73 -22
- package/build/src/akuma/providers/index.js +22 -8
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +48 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +116 -0
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +32 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +203 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +41 -0
- package/build/src/akuma/providers/opencode-sdk/session.js +62 -0
- package/build/src/akuma/providers/pi/events.d.ts +33 -0
- package/build/src/akuma/providers/pi/events.js +128 -0
- package/build/src/akuma/providers/pi/index.d.ts +11 -0
- package/build/src/akuma/providers/pi/index.js +162 -0
- package/build/src/akuma/requests.d.ts +1 -0
- package/build/src/akuma/requests.js +5 -2
- package/build/src/alias/index.d.ts +4 -3
- package/build/src/alias/index.js +2 -3
- 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 +2 -0
- package/build/src/cli/accepted.js +2 -1
- package/build/src/cli/commands/akuma-invoke.d.ts +42 -18
- package/build/src/cli/commands/akuma-invoke.js +94 -50
- package/build/src/cli/commands/akuma.d.ts +15 -7
- package/build/src/cli/commands/akuma.js +94 -56
- package/build/src/cli/commands/contract.d.ts +142 -0
- package/build/src/cli/commands/contract.js +14 -0
- package/build/src/cli/commands/install.js +2 -0
- package/build/src/cli/commands/task-invoke.d.ts +3 -1
- package/build/src/cli/commands/task-invoke.js +27 -2
- package/build/src/cli/commands/task.js +2 -2
- package/build/src/cli/invoke.d.ts +6 -1
- package/build/src/cli/invoke.js +241 -43
- package/build/src/cli/main.js +20 -1
- package/build/src/cli/parse.d.ts +13 -116
- package/build/src/cli/parse.js +51 -78
- package/build/src/cli/render/akuma-tool.d.ts +2 -0
- package/build/src/cli/render/akuma-tool.js +6 -2
- package/build/src/cli/render/akuma.d.ts +2 -1
- package/build/src/cli/render/akuma.js +157 -217
- 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 +1 -1
- package/build/src/cli/render/contract.js +38 -5
- package/build/src/cli/render/kanshi.js +53 -5
- package/build/src/cli/render/refusal.js +17 -0
- package/build/src/cli/render/terminal.d.ts +13 -0
- package/build/src/cli/render/terminal.js +75 -0
- package/build/src/cli/render/text.js +5 -0
- package/build/src/cli/result.d.ts +15 -3
- package/build/src/contract-worktree.d.ts +43 -0
- package/build/src/contract-worktree.js +213 -0
- package/build/src/coordination/durable-file.d.ts +3 -0
- package/build/src/coordination/durable-file.js +44 -1
- 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/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.js +12 -16
- package/build/src/core/verbs/bind.js +2 -16
- package/build/src/core/verbs/deliver.js +20 -4
- package/build/src/core/verbs/placement.js +3 -8
- package/build/src/dispatch/index.d.ts +3 -1
- package/build/src/dispatch/index.js +14 -5
- 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 +26 -16
- package/build/src/git/hooks.d.ts +15 -0
- package/build/src/git/hooks.js +57 -5
- package/build/src/git/identity.d.ts +5 -1
- package/build/src/git/identity.js +23 -4
- package/build/src/git/integration.d.ts +49 -0
- package/build/src/git/integration.js +214 -0
- package/build/src/git/observe.d.ts +25 -13
- package/build/src/git/observe.js +175 -72
- 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 +15 -5
- package/build/src/git/reconcile.js +238 -85
- package/build/src/git/repository.d.ts +19 -4
- package/build/src/git/repository.js +77 -43
- package/build/src/git/scratch.d.ts +13 -0
- package/build/src/git/scratch.js +66 -0
- package/build/src/git/target-placement.d.ts +56 -0
- package/build/src/git/target-placement.js +255 -0
- package/build/src/git/tender.d.ts +48 -0
- package/build/src/git/tender.js +82 -0
- package/build/src/git/terminal-seal.d.ts +24 -0
- package/build/src/git/terminal-seal.js +87 -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 +21 -0
- package/build/src/git/workspace.js +104 -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 +1 -1
- package/build/src/kanshi/read.d.ts +5 -2
- package/build/src/kanshi/read.js +154 -45
- package/build/src/kanshi/report.d.ts +31 -6
- package/build/src/kanshi/select.js +1 -1
- package/build/src/library/address.d.ts +48 -0
- package/build/src/library/address.js +134 -0
- package/build/src/library/akuma-creation.d.ts +10 -6
- package/build/src/library/akuma-creation.js +12 -11
- 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 +72 -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 +21 -46
- package/build/src/library/contract.js +193 -183
- package/build/src/library/delivery.d.ts +23 -0
- package/build/src/library/delivery.js +21 -0
- package/build/src/library/fleet.d.ts +65 -0
- package/build/src/library/fleet.js +189 -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 +16 -2
- package/build/src/library/keiyaku.js +11 -1
- package/build/src/library/mutation.d.ts +38 -0
- package/build/src/library/mutation.js +39 -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 +2 -1
- package/build/src/library/region.js +3 -3
- package/build/src/library/repo.d.ts +4 -1
- package/build/src/library/repo.js +31 -16
- package/build/src/protocol/attempt.d.ts +16 -3
- package/build/src/protocol/attempt.js +39 -8
- package/build/src/protocol/bind.d.ts +9 -2
- package/build/src/protocol/bind.js +47 -39
- package/build/src/protocol/intent.d.ts +42 -18
- package/build/src/protocol/intent.js +36 -75
- package/build/src/protocol/operations.d.ts +93 -35
- package/build/src/protocol/operations.js +235 -123
- package/build/src/protocol/outcome.d.ts +7 -2
- package/build/src/protocol/outcome.js +9 -3
- package/build/src/protocol/placement.d.ts +30 -0
- package/build/src/protocol/placement.js +114 -0
- package/build/src/protocol/read/audit.d.ts +9 -3
- package/build/src/protocol/read/audit.js +25 -9
- 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 +11 -5
- package/build/src/protocol/read/status.js +28 -15
- 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 +1 -0
- package/build/src/runtime/proc/line-rpc.js +21 -0
- package/build/src/runtime/proc/run.d.ts +18 -2
- package/build/src/runtime/proc/run.js +34 -8
- package/build/src/settings.d.ts +6 -0
- package/build/src/settings.js +29 -14
- package/build/src/settlement/fence.d.ts +9 -0
- package/build/src/settlement/fence.js +23 -0
- package/build/src/settlement/holder.d.ts +25 -4
- package/build/src/settlement/holder.js +102 -28
- package/build/src/settlement/settle.d.ts +8 -0
- package/build/src/settlement/settle.js +102 -28
- package/build/src/task/board.d.ts +20 -2
- package/build/src/task/board.js +11 -1
- package/build/src/task/compose.d.ts +2 -2
- package/build/src/task/compose.js +2 -2
- package/build/src/task/context.js +2 -7
- package/build/src/task/index.d.ts +9 -9
- package/build/src/task/index.js +15 -12
- package/build/src/task/operations.d.ts +31 -12
- package/build/src/task/operations.js +8 -4
- package/build/src/task/store.d.ts +4 -6
- package/build/src/task/store.js +3 -3
- package/build/src/verification/declaration.d.ts +1 -0
- package/build/src/verification/execution.d.ts +49 -0
- package/build/src/verification/execution.js +104 -0
- package/build/src/world.d.ts +13 -0
- package/build/src/world.js +103 -0
- package/package.json +7 -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/verification/producer.d.ts +0 -23
- package/build/src/verification/producer.js +0 -54
package/build/src/akuma/akuma.js
CHANGED
|
@@ -2,9 +2,9 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { readdirSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { spawnAkumaBody } from "./body.js";
|
|
5
|
-
import { HeldAkumaLeash, activitySlice, life, probeLeash,
|
|
5
|
+
import { HeldAkumaLeash, activitySlice, life, 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 { projectActivityHistory, selectActivitySnapshot, } from "./
|
|
7
|
+
import { projectActivityHistory, selectActivitySnapshot, } from "./projection.js";
|
|
8
8
|
import { listArchetypes as readArchetypes, loadArchetype } from "./archetype.js";
|
|
9
9
|
import { publishAkuma } from "./publication.js";
|
|
10
10
|
import { providerNamed } from "./providers/index.js";
|
|
@@ -35,23 +35,21 @@ async function takeLeashUntil(paths, deadline) {
|
|
|
35
35
|
await wait(POLL_MS);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
function recordTellBody(paths, body) {
|
|
38
|
+
function recordTellBody(paths, akuma, body) {
|
|
39
39
|
const id = randomUUID();
|
|
40
|
-
const admitted = recordTell(paths, { id, body, recordedAt: new Date().toISOString() });
|
|
41
|
-
|
|
40
|
+
const admitted = recordTell(paths, { kind: "tell", id, body, recordedAt: new Date().toISOString() });
|
|
41
|
+
if (admitted.kind === "not-born")
|
|
42
|
+
throw new AkumaNotBornError(akuma);
|
|
43
|
+
return { kind: "recorded", tellId: admitted.tell.id };
|
|
42
44
|
}
|
|
43
|
-
async function wakeTell(paths,
|
|
44
|
-
const soul = readSoul(paths);
|
|
45
|
-
if (soul === null)
|
|
46
|
-
throw new Error(`Akuma ${akuma} has no soul`);
|
|
45
|
+
async function wakeTell(paths, tellId) {
|
|
47
46
|
try {
|
|
48
47
|
await spawnAkumaBody({ paths });
|
|
49
|
-
return {
|
|
48
|
+
return { admission: { tellId, fact: "recorded" }, wake: "spawned" };
|
|
50
49
|
}
|
|
51
50
|
catch (error) {
|
|
52
51
|
return {
|
|
53
|
-
|
|
54
|
-
state: "recorded",
|
|
52
|
+
admission: { tellId, fact: "recorded" },
|
|
55
53
|
wake: { kind: "failed", diagnostic: error instanceof Error ? error.message : String(error) },
|
|
56
54
|
};
|
|
57
55
|
}
|
|
@@ -74,35 +72,39 @@ function bornListRow(paths, expected, snapshot = readHeart(paths)) {
|
|
|
74
72
|
id: snapshot.soul.id,
|
|
75
73
|
archetype: snapshot.soul.archetype,
|
|
76
74
|
...(snapshot.soul.description === undefined ? {} : { description: snapshot.soul.description }),
|
|
77
|
-
life: life(probeLeash(paths), collar, snapshot.
|
|
75
|
+
life: life(probeLeash(paths), collar, snapshot.latestBody, snapshot.latestKill),
|
|
78
76
|
collar,
|
|
79
77
|
confinement: snapshot.soul.confinement,
|
|
80
78
|
pending: snapshot.pending.map((tell) => tell.id),
|
|
81
79
|
};
|
|
82
80
|
}
|
|
83
|
-
function bornStatus(paths, expected) {
|
|
81
|
+
function bornStatus(paths, expected, profile = "status") {
|
|
84
82
|
const snapshot = readHeart(paths);
|
|
85
83
|
if (snapshot.soul === null)
|
|
86
84
|
throw new AkumaNotBornError(expected);
|
|
87
85
|
const current = bornListRow(paths, expected, snapshot);
|
|
88
|
-
const
|
|
86
|
+
const resumeUnsupported = current.life === "stranded"
|
|
87
|
+
&& snapshot.latestSession?.provider === snapshot.soul.provider.name
|
|
88
|
+
&& providerNamed(snapshot.soul.provider).resume === undefined;
|
|
89
89
|
return {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
activity: (() => {
|
|
97
|
-
const slice = activitySlice(paths, { limit: 5_000 });
|
|
90
|
+
id: current.id,
|
|
91
|
+
life: current.life,
|
|
92
|
+
collar: current.collar,
|
|
93
|
+
...(resumeUnsupported ? { strandedReason: "resume-unsupported" } : {}),
|
|
94
|
+
timeline: (() => {
|
|
95
|
+
const slice = activitySlice(paths, { limit: Number.MAX_SAFE_INTEGER });
|
|
98
96
|
return selectActivitySnapshot(slice.rows, {
|
|
99
|
-
pending: snapshot.pending,
|
|
100
97
|
lowestRetained: slice.lowestRetained,
|
|
101
98
|
highest: slice.highest,
|
|
99
|
+
profile,
|
|
102
100
|
});
|
|
103
101
|
})(),
|
|
104
102
|
};
|
|
105
103
|
}
|
|
104
|
+
/** Package-internal compact observation for action feedback. */
|
|
105
|
+
export function readActionFeedbackStatus(worldPath, id) {
|
|
106
|
+
return bornStatus(pathsForAkuId(worldPath, id), id, "feedback");
|
|
107
|
+
}
|
|
106
108
|
function diagnostic(error) {
|
|
107
109
|
return error instanceof Error ? error.message : String(error);
|
|
108
110
|
}
|
|
@@ -137,8 +139,9 @@ export class AkumaHandle {
|
|
|
137
139
|
...(input.since === undefined ? {} : { since: input.since }),
|
|
138
140
|
limit: 5_000,
|
|
139
141
|
});
|
|
140
|
-
return projectActivityHistory(slice,
|
|
141
|
-
|
|
142
|
+
return projectActivityHistory(slice, {
|
|
143
|
+
...(input.before === undefined ? {} : { before: input.before }),
|
|
144
|
+
...(input.since === undefined ? {} : { since: input.since }),
|
|
142
145
|
limit,
|
|
143
146
|
});
|
|
144
147
|
}
|
|
@@ -156,14 +159,13 @@ export class AkumaHandle {
|
|
|
156
159
|
}
|
|
157
160
|
}
|
|
158
161
|
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);
|
|
162
|
+
const recorded = recordTellBody(this.paths, this.id, body);
|
|
163
|
+
return await wakeTell(this.paths, recorded.tellId);
|
|
163
164
|
}
|
|
164
165
|
async interrupt(body) {
|
|
165
|
-
if (requestPause(this.paths, new Date().toISOString()) === "
|
|
166
|
-
|
|
166
|
+
if (requestPause(this.paths, new Date().toISOString()).kind === "not-born") {
|
|
167
|
+
throw new AkumaNotBornError(this.id);
|
|
168
|
+
}
|
|
167
169
|
let putDown = "was-idle";
|
|
168
170
|
let leash = HeldAkumaLeash.try(this.paths);
|
|
169
171
|
if (leash === null) {
|
|
@@ -188,16 +190,21 @@ export class AkumaHandle {
|
|
|
188
190
|
}
|
|
189
191
|
let recorded;
|
|
190
192
|
try {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
+
const id = randomUUID();
|
|
194
|
+
const admitted = leash.recordInterruptTell(this.paths, {
|
|
195
|
+
kind: "tell",
|
|
196
|
+
id,
|
|
197
|
+
body,
|
|
198
|
+
recordedAt: new Date().toISOString(),
|
|
199
|
+
});
|
|
200
|
+
if (admitted.kind === "not-born")
|
|
201
|
+
throw new AkumaNotBornError(this.id);
|
|
202
|
+
recorded = { kind: "recorded", tellId: admitted.tell.id };
|
|
193
203
|
}
|
|
194
204
|
finally {
|
|
195
205
|
leash.release();
|
|
196
206
|
}
|
|
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) };
|
|
207
|
+
return { kind: "interrupted", putDown, tell: await wakeTell(this.paths, recorded.tellId) };
|
|
201
208
|
}
|
|
202
209
|
async fork(input) {
|
|
203
210
|
const source = readSoul(this.paths);
|
|
@@ -256,51 +263,67 @@ export class AkumaHandle {
|
|
|
256
263
|
}
|
|
257
264
|
async kill() {
|
|
258
265
|
const at = new Date().toISOString();
|
|
259
|
-
|
|
260
|
-
|
|
266
|
+
const request = requestStop(this.paths, at);
|
|
267
|
+
if (request.kind === "already-killed")
|
|
268
|
+
return "already-killed";
|
|
269
|
+
const target = request.body;
|
|
261
270
|
const graceDeadline = performance.now() + KILL_GRACE_MS;
|
|
262
271
|
while (probeLeash(this.paths) === "held" && performance.now() < graceDeadline)
|
|
263
272
|
await wait(POLL_MS);
|
|
264
|
-
if (
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
273
|
+
if (readKill(this.paths, target.sequence) !== null)
|
|
274
|
+
return "killed";
|
|
275
|
+
const targetProbe = probeProcessTree(target.collar);
|
|
276
|
+
if (targetProbe.kind === "unverifiable")
|
|
277
|
+
return "unavailable";
|
|
278
|
+
if (targetProbe.kind === "alive") {
|
|
279
|
+
const evidence = await putDownProcessTree(target.collar);
|
|
269
280
|
if (evidence === "unavailable" || evidence === "alive-after-sigkill")
|
|
270
281
|
return evidence;
|
|
271
282
|
}
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
283
|
+
const leash = await takeLeashUntil(this.paths, performance.now() + KILL_GRACE_MS);
|
|
284
|
+
if (leash === null)
|
|
285
|
+
return readKill(this.paths, target.sequence) === null ? "unavailable" : "killed";
|
|
286
|
+
try {
|
|
287
|
+
const settled = leash.settleStop(this.paths, target.sequence);
|
|
288
|
+
if (settled === null)
|
|
289
|
+
return "unavailable";
|
|
290
|
+
return "killed";
|
|
291
|
+
}
|
|
292
|
+
finally {
|
|
293
|
+
leash.release();
|
|
294
|
+
}
|
|
278
295
|
}
|
|
279
296
|
lastAnswer() {
|
|
280
297
|
const turn = readLastAnsweredTurn(this.paths);
|
|
281
|
-
return turn?.outcome.kind === "answered"
|
|
298
|
+
return turn?.end?.outcome.kind === "answered"
|
|
299
|
+
? { kind: "answer", answer: turn.end.outcome.answer }
|
|
300
|
+
: { kind: "no-answer" };
|
|
282
301
|
}
|
|
283
302
|
}
|
|
284
303
|
export class Akuma {
|
|
285
304
|
path;
|
|
286
|
-
|
|
287
|
-
constructor(path,
|
|
305
|
+
configuredSettings;
|
|
306
|
+
constructor(path, configuredSettings) {
|
|
288
307
|
this.path = path;
|
|
289
|
-
this.
|
|
308
|
+
this.configuredSettings = configuredSettings;
|
|
290
309
|
}
|
|
291
|
-
static
|
|
292
|
-
|
|
293
|
-
|
|
310
|
+
static of(root, settings) {
|
|
311
|
+
if (typeof root !== "string")
|
|
312
|
+
throw new TypeError("Akuma.of root must be a WorldRoot");
|
|
313
|
+
return new Akuma(root, settings);
|
|
314
|
+
}
|
|
315
|
+
settings() {
|
|
316
|
+
return this.configuredSettings ?? readSettings({ root: this.path });
|
|
294
317
|
}
|
|
295
318
|
of(input) {
|
|
296
319
|
return new AkumaHandle(parseAkuId(input.id).id, this.path);
|
|
297
320
|
}
|
|
298
321
|
listArchetypes() {
|
|
299
|
-
return readArchetypes({ settings: this.settings });
|
|
322
|
+
return readArchetypes({ settings: this.settings() });
|
|
300
323
|
}
|
|
301
324
|
async call(input) {
|
|
302
325
|
const name = archetypeName(input.archetype);
|
|
303
|
-
const archetype = loadArchetype({ name, settings: this.settings });
|
|
326
|
+
const archetype = loadArchetype({ name, settings: this.settings() });
|
|
304
327
|
const provider = archetype.adapter;
|
|
305
328
|
const cwd = resolve(input.cwd ?? this.path);
|
|
306
329
|
const recipe = Object.freeze({
|
|
@@ -342,7 +365,14 @@ export class Akuma {
|
|
|
342
365
|
});
|
|
343
366
|
return new AkumaHandle(published.id, this.path);
|
|
344
367
|
}
|
|
345
|
-
list() {
|
|
368
|
+
list(input = {}) {
|
|
369
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
370
|
+
throw new TypeError("Akuma list input must be an object");
|
|
371
|
+
}
|
|
372
|
+
const unknown = Object.keys(input).find((key) => key !== "archetype");
|
|
373
|
+
if (unknown !== undefined)
|
|
374
|
+
throw new TypeError(`Akuma list input has unknown field: ${unknown}`);
|
|
375
|
+
const selected = input.archetype === undefined ? undefined : archetypeName(input.archetype);
|
|
346
376
|
const runRoot = akumaRunRoot(this.path);
|
|
347
377
|
let names;
|
|
348
378
|
try {
|
|
@@ -359,6 +389,8 @@ export class Akuma {
|
|
|
359
389
|
const rows = names.flatMap((name) => {
|
|
360
390
|
try {
|
|
361
391
|
const physical = akuIdFromDirectoryName(name);
|
|
392
|
+
if (selected !== undefined && physical.archetype !== selected)
|
|
393
|
+
return [];
|
|
362
394
|
const paths = akumaPaths({ runRoot, archetype: physical.archetype, suffix: physical.suffix });
|
|
363
395
|
const snapshot = readHeart(paths);
|
|
364
396
|
if (snapshot.soul !== null)
|
|
@@ -8,6 +8,11 @@ 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
|
}>;
|
|
@@ -24,6 +29,9 @@ export declare class AkumaArchetypeError extends Error {
|
|
|
24
29
|
export declare function listArchetypes(input: Readonly<{
|
|
25
30
|
settings: Settings;
|
|
26
31
|
}>): readonly string[];
|
|
32
|
+
export declare function listArchetypeDefinitions(input: Readonly<{
|
|
33
|
+
settings: Settings;
|
|
34
|
+
}>): readonly ArchetypeCatalogRow[];
|
|
27
35
|
export declare function loadArchetype(input: Readonly<{
|
|
28
36
|
name: string;
|
|
29
37
|
settings: Settings;
|
|
@@ -21,27 +21,24 @@ function archetypeDirectory(settings) {
|
|
|
21
21
|
const userPath = settings.scopes.user.path;
|
|
22
22
|
return userPath === undefined ? null : join(dirname(userPath), "akuma");
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
const directory = archetypeDirectory(
|
|
24
|
+
function archetypePaths(settings) {
|
|
25
|
+
const directory = archetypeDirectory(settings);
|
|
26
26
|
if (directory === null)
|
|
27
27
|
return [];
|
|
28
28
|
try {
|
|
29
29
|
return readdirSync(directory, { withFileTypes: true })
|
|
30
30
|
.flatMap((entry) => {
|
|
31
|
-
if (!entry.isFile())
|
|
32
|
-
return [];
|
|
33
|
-
const filename = entry.name;
|
|
34
|
-
if (!filename.endsWith(".md"))
|
|
31
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
35
32
|
return [];
|
|
36
|
-
const name =
|
|
33
|
+
const name = entry.name.slice(0, -3);
|
|
37
34
|
try {
|
|
38
|
-
return [archetypeName(name)];
|
|
35
|
+
return [{ name: archetypeName(name), path: join(directory, entry.name) }];
|
|
39
36
|
}
|
|
40
37
|
catch {
|
|
41
38
|
return [];
|
|
42
39
|
}
|
|
43
40
|
})
|
|
44
|
-
.sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
|
|
41
|
+
.sort((left, right) => Buffer.compare(Buffer.from(left.name), Buffer.from(right.name)));
|
|
45
42
|
}
|
|
46
43
|
catch (error) {
|
|
47
44
|
if (error.code === "ENOENT")
|
|
@@ -49,6 +46,9 @@ export function listArchetypes(input) {
|
|
|
49
46
|
throw error;
|
|
50
47
|
}
|
|
51
48
|
}
|
|
49
|
+
export function listArchetypes(input) {
|
|
50
|
+
return archetypePaths(input.settings).map(({ name }) => name);
|
|
51
|
+
}
|
|
52
52
|
function archetypeField(values, key, required = false) {
|
|
53
53
|
const value = values[key];
|
|
54
54
|
if (value === undefined && !required)
|
|
@@ -102,6 +102,21 @@ function decodeArchetype(name, path, markdown) {
|
|
|
102
102
|
}),
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
|
+
export function listArchetypeDefinitions(input) {
|
|
106
|
+
return archetypePaths(input.settings).map(({ name, path }) => {
|
|
107
|
+
try {
|
|
108
|
+
const definition = decodeArchetype(name, path, readFileSync(path, "utf8"));
|
|
109
|
+
return Object.freeze({
|
|
110
|
+
name: definition.name,
|
|
111
|
+
...(definition.options.model === undefined ? {} : { model: definition.options.model }),
|
|
112
|
+
...(definition.description === undefined ? {} : { description: definition.description }),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new AkumaArchetypeError(name, [path], `is invalid: ${error instanceof Error ? error.message : String(error)}`);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
105
120
|
function record(value) {
|
|
106
121
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
107
122
|
? value : null;
|
|
@@ -142,6 +157,10 @@ function providerExecution(settings, name) {
|
|
|
142
157
|
return Object.freeze({ name, kind: "claude-agent-sdk" });
|
|
143
158
|
if (name === "codex-app-server")
|
|
144
159
|
return Object.freeze({ name, kind: "codex-app-server" });
|
|
160
|
+
if (name === "opencode-sdk")
|
|
161
|
+
return Object.freeze({ name, kind: "opencode-sdk" });
|
|
162
|
+
if (name === "pi")
|
|
163
|
+
return Object.freeze({ name, kind: "pi" });
|
|
145
164
|
throw new TypeError(`unknown provider ${name}`);
|
|
146
165
|
}
|
|
147
166
|
function admitArchetype(archetype, settings) {
|