@astrosheep/keiyaku 4.5.17 → 4.5.19
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/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +5 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +4 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +3 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +3 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +13 -1
- package/build/src/akuma/akuma-handle.d.ts +18 -7
- package/build/src/akuma/akuma-handle.js +97 -120
- package/build/src/akuma/akuma-instance.d.ts +19 -4
- package/build/src/akuma/akuma-instance.js +102 -38
- package/build/src/akuma/akuma-observe.d.ts +2 -0
- package/build/src/akuma/akuma-observe.js +56 -29
- package/build/src/akuma/akuma-product.d.ts +12 -8
- package/build/src/akuma/akuma-product.js +66 -54
- package/build/src/akuma/akuma.d.ts +10 -23
- package/build/src/akuma/akuma.js +12 -72
- package/build/src/akuma/body.js +132 -108
- package/build/src/akuma/call-request.d.ts +2 -2
- package/build/src/akuma/call-request.js +2 -2
- package/build/src/akuma/control.d.ts +8 -0
- package/build/src/akuma/control.js +23 -0
- package/build/src/akuma/dispatch-association.d.ts +13 -0
- package/build/src/akuma/dispatch-association.js +20 -0
- package/build/src/akuma/fleet-execution.js +44 -25
- package/build/src/akuma/fleet-observation.js +1 -1
- package/build/src/akuma/fleet-request.js +9 -2
- package/build/src/akuma/heart/facts.d.ts +3 -0
- package/build/src/akuma/heart/facts.js +6 -0
- package/build/src/akuma/heart/index.d.ts +12 -17
- package/build/src/akuma/heart/index.js +93 -86
- package/build/src/akuma/heart/request-authority.js +19 -19
- package/build/src/akuma/heart/rows.d.ts +1 -0
- package/build/src/akuma/heart/rows.js +7 -0
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +23 -8
- package/build/src/akuma/heart/storage.d.ts +2 -4
- package/build/src/akuma/heart/storage.js +63 -63
- package/build/src/akuma/heart/tells.d.ts +11 -21
- package/build/src/akuma/heart/tells.js +89 -84
- package/build/src/akuma/heart/timeline.d.ts +7 -1
- package/build/src/akuma/heart/timeline.js +62 -53
- package/build/src/akuma/index.d.ts +5 -3
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/nuke.js +8 -45
- package/build/src/akuma/providers/claude/events.d.ts +1 -1
- package/build/src/akuma/providers/claude/events.js +2 -1
- package/build/src/akuma/providers/codex-app-server/events.d.ts +2 -2
- package/build/src/akuma/providers/codex-app-server/events.js +6 -2
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +1 -1
- package/build/src/akuma/providers/opencode-sdk/events.js +5 -1
- package/build/src/akuma/providers/pi/events.d.ts +4 -0
- package/build/src/akuma/providers/pi/events.js +8 -3
- package/build/src/akuma/publication.js +2 -11
- package/build/src/akuma/request-rendezvous.d.ts +1 -1
- package/build/src/akuma/request-rendezvous.js +9 -8
- package/build/src/akuma/schema.d.ts +4 -6
- package/build/src/akuma/schema.js +35 -31
- package/build/src/akuma-body.js +3 -2
- package/build/src/cli/accepted.d.ts +1 -2
- package/build/src/cli/accepted.js +18 -16
- package/build/src/cli/commands/akuma-invoke.d.ts +0 -2
- package/build/src/cli/commands/akuma-invoke.js +8 -25
- package/build/src/cli/commands/akuma.d.ts +2 -1
- package/build/src/cli/commands/akuma.js +6 -6
- package/build/src/cli/commands/contract-help.d.ts +2 -1
- package/build/src/cli/commands/contract-help.js +27 -13
- package/build/src/cli/commands/contract-invoke.js +15 -0
- package/build/src/cli/commands/contract.d.ts +1 -0
- package/build/src/cli/commands/contract.js +4 -3
- package/build/src/cli/commands/install.js +8 -7
- package/build/src/cli/commands/task.d.ts +2 -0
- package/build/src/cli/commands/task.js +9 -5
- package/build/src/cli/invoke.d.ts +0 -1
- package/build/src/cli/invoke.js +19 -5
- package/build/src/cli/parse.d.ts +3 -0
- package/build/src/cli/parse.js +26 -13
- package/build/src/cli/render/akuma-activity.js +4 -4
- package/build/src/cli/render/akuma.js +7 -9
- package/build/src/cli/render/audit.js +28 -24
- package/build/src/cli/render/board.js +7 -3
- package/build/src/cli/render/catalog.js +16 -23
- package/build/src/cli/render/contract-history.js +20 -21
- package/build/src/cli/render/contract-observation.d.ts +2 -0
- package/build/src/cli/render/contract-observation.js +30 -6
- package/build/src/cli/render/contract.js +39 -33
- package/build/src/cli/render/kanshi-akuma.js +5 -6
- package/build/src/cli/render/kanshi.js +56 -99
- package/build/src/cli/render/nuke.js +3 -3
- package/build/src/cli/render/receipt.d.ts +15 -5
- package/build/src/cli/render/receipt.js +54 -20
- package/build/src/cli/render/refusal.d.ts +1 -1
- package/build/src/cli/render/refusal.js +55 -45
- package/build/src/cli/render/region.js +8 -8
- package/build/src/cli/render/settings.js +13 -11
- package/build/src/cli/render/status-set.js +13 -8
- package/build/src/cli/render/task.d.ts +1 -0
- package/build/src/cli/render/task.js +15 -14
- package/build/src/cli/render/terminal.d.ts +3 -1
- package/build/src/cli/render/terminal.js +33 -21
- package/build/src/cli/render/value.d.ts +3 -0
- package/build/src/cli/render/value.js +24 -0
- package/build/src/cli/result.d.ts +11 -18
- package/build/src/cli/runtime.d.ts +0 -1
- package/build/src/cli/runtime.js +46 -31
- package/build/src/cli/usage.d.ts +15 -2
- package/build/src/cli/usage.js +59 -6
- package/build/src/contract-guidance.d.ts +1 -0
- package/build/src/contract-guidance.js +26 -2
- package/build/src/contract-worktree.js +2 -1
- package/build/src/core/facts/gate.d.ts +8 -1
- package/build/src/core/facts/gate.js +48 -6
- package/build/src/core/subject.d.ts +4 -3
- package/build/src/core/subject.js +6 -2
- package/build/src/dispatch/association.d.ts +1 -13
- package/build/src/dispatch/association.js +1 -20
- package/build/src/git/hooks.d.ts +1 -1
- package/build/src/git/hooks.js +10 -3
- package/build/src/git/integration.js +4 -4
- package/build/src/git/process.d.ts +2 -0
- package/build/src/git/process.js +106 -0
- package/build/src/git/read-observation.js +79 -56
- package/build/src/git/result-codec.js +4 -1
- package/build/src/git/scratch.js +1 -1
- package/build/src/git/target-placement.d.ts +15 -4
- package/build/src/git/target-placement.js +136 -84
- package/build/src/git/terminal-reconcile.js +16 -9
- package/build/src/git/workspace.d.ts +18 -3
- package/build/src/git/workspace.js +21 -4
- package/build/src/kanshi/read.js +3 -3
- package/build/src/library/address.js +2 -2
- package/build/src/library/akuma-creation.d.ts +6 -3
- package/build/src/library/akuma-creation.js +45 -23
- package/build/src/library/audit.js +11 -6
- package/build/src/library/catalog.js +2 -3
- package/build/src/library/composition.d.ts +1 -0
- package/build/src/library/continuation.d.ts +23 -31
- package/build/src/library/continuation.js +97 -99
- package/build/src/library/contract-bind.d.ts +2 -0
- package/build/src/library/contract-bind.js +31 -18
- package/build/src/library/contract-execution.d.ts +39 -0
- package/build/src/library/contract-execution.js +145 -0
- package/build/src/library/contract-forwarding.d.ts +9 -29
- package/build/src/library/contract-forwarding.js +14 -78
- package/build/src/library/contract-handle.js +38 -5
- package/build/src/library/contract-operations.d.ts +29 -0
- package/build/src/library/contract-operations.js +35 -2
- package/build/src/library/contract-types.d.ts +4 -0
- package/build/src/library/delivery.d.ts +2 -3
- package/build/src/library/delivery.js +3 -5
- package/build/src/library/execution-result.d.ts +243 -0
- package/build/src/library/execution-result.js +101 -0
- package/build/src/library/fleet.d.ts +3 -0
- package/build/src/library/fleet.js +6 -5
- package/build/src/library/keiyaku.d.ts +5 -4
- package/build/src/library/keiyaku.js +1 -0
- package/build/src/library/mutation.d.ts +121 -89
- package/build/src/library/mutation.js +109 -85
- package/build/src/library/reconcile.d.ts +7 -0
- package/build/src/library/reconcile.js +13 -0
- package/build/src/library/refusal.d.ts +6 -0
- package/build/src/library/refusal.js +40 -0
- package/build/src/plugin/runtime.d.ts +2 -2
- package/build/src/plugin/runtime.js +45 -23
- package/build/src/protocol/attempt.d.ts +3 -1
- package/build/src/protocol/attempt.js +13 -5
- package/build/src/protocol/audit.d.ts +8 -1
- package/build/src/protocol/audit.js +17 -8
- package/build/src/protocol/completion.d.ts +20 -16
- package/build/src/protocol/completion.js +162 -136
- package/build/src/protocol/deliver.d.ts +17 -15
- package/build/src/protocol/deliver.js +107 -52
- package/build/src/protocol/intent.d.ts +5 -2
- package/build/src/protocol/intent.js +9 -2
- package/build/src/protocol/operations.d.ts +4 -4
- package/build/src/protocol/operations.js +3 -1
- package/build/src/protocol/outcome.d.ts +9 -0
- package/build/src/protocol/placement.d.ts +3 -1
- package/build/src/protocol/placement.js +60 -29
- package/build/src/protocol/progress.d.ts +82 -0
- package/build/src/protocol/progress.js +142 -0
- package/build/src/protocol/read/status.d.ts +27 -3
- package/build/src/protocol/read/status.js +40 -9
- package/build/src/protocol/reintegrate.d.ts +2 -0
- package/build/src/protocol/reintegrate.js +1 -0
- package/build/src/protocol/result-codec.d.ts +2 -1
- package/build/src/protocol/result-codec.js +79 -49
- package/build/src/protocol/review.d.ts +11 -7
- package/build/src/protocol/review.js +17 -27
- package/build/src/protocol/run.d.ts +2 -0
- package/build/src/protocol/run.js +1 -0
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settings.js +15 -4
- package/build/src/verification/execution.d.ts +2 -2
- package/build/src/verification/execution.js +2 -2
- package/build/src/workspace-place.d.ts +4 -0
- package/build/src/workspace-place.js +15 -7
- package/build/src/world.d.ts +2 -2
- package/build/src/world.js +20 -51
- package/package.json +8 -6
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Keiyaku is a CLI that records plans, writes handoff terms for deliveries,
|
|
5
|
+
and calls delegates. Use this skill when you need to figure out which
|
|
6
|
+
Keiyaku skill or command to reach for.
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
# Keiyaku
|
|
@@ -33,7 +36,7 @@ keiyaku -C <repo> review [<contract>|@<contract>] --satisfied
|
|
|
33
36
|
```
|
|
34
37
|
|
|
35
38
|
```bash
|
|
36
|
-
keiyaku -C <cwd> call <akuma-name> [--contract <kei/...>] [--alias @name] [--
|
|
39
|
+
keiyaku -C <cwd> call <akuma-name> [--contract <kei/...>] [--alias @name] [--allowed <product.action>]... [--schema <file>] [--wait <duration> | -d | --detach] [--json] (<prompt> | -)
|
|
37
40
|
keiyaku -C <repo> wait <akuma-selector>... [--any | --all]
|
|
38
41
|
keiyaku -C <repo> tell <aku/...|@alias> (<prompt> | -)
|
|
39
42
|
```
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku-akuma
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Calling an Akuma: delegating scouting, mechanical chores, or fanned-out
|
|
5
|
+
parallel work instead of doing it inline.
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Keiyaku Akuma
|
|
@@ -13,7 +15,7 @@ is accepted; the identity underneath never changes.
|
|
|
13
15
|
## Start One
|
|
14
16
|
|
|
15
17
|
```bash
|
|
16
|
-
keiyaku -C <cwd> call <akuma-name> [--alias @name] [--
|
|
18
|
+
keiyaku -C <cwd> call <akuma-name> [--alias @name] [--allowed <product.action>]... [--schema <file>] [--wait <duration> | -d | --detach] [--json] (<prompt> | -)
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
Give the worker's initial prompt as one argument (quote it when it contains
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku-babysit
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Entering babysit mode: supervising parallel work across multiple Akuma and
|
|
5
|
+
Contracts as they advance, instead of doing the work yourself.
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Keiyaku Babysit
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku-bind
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Binding a Keiyaku: writing down what a bounded piece of work must deliver and
|
|
5
|
+
how it will be judged, so it can be handed off.
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Keiyaku Bind
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku-task
|
|
3
3
|
description: >-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Organizing, tracking progress and status, or binding work of three or more
|
|
5
|
+
steps as a Keiyaku Task: what to do, in what order, what depends on what,
|
|
6
|
+
what is done and what is blocked.
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
# Keiyaku Task
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keiyaku-workflow
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
The Keiyaku workflow: how work moves through Keiyaku from planning through
|
|
5
|
+
binding, commissioning, delivery, review, and landing, and what you decide
|
|
6
|
+
at each stage.
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
# Holding a fulfillment loop
|
|
@@ -111,6 +114,15 @@ immutable commit without moving the branch or the real index — a
|
|
|
111
114
|
prior git commit is optional shaping, never a prerequisite. Deliver
|
|
112
115
|
never satisfies a review gate.
|
|
113
116
|
|
|
117
|
+
Conflict materialization projects an uncommitted merge; it does not resolve
|
|
118
|
+
its contents or record a delivery. After editing the final worktree bytes,
|
|
119
|
+
`deliver --include-dirty` can capture them even while the real index still
|
|
120
|
+
reports `UU`. No `git add` or commit is required, and capture preserves the
|
|
121
|
+
real index. The candidate includes the complete non-ignored worktree, not
|
|
122
|
+
just the Contract's Region or the conflict paths. Candidate capture and target
|
|
123
|
+
placement are separate: this authorization does not permit overwriting
|
|
124
|
+
blocking changes in the target checkout.
|
|
125
|
+
|
|
114
126
|
Audit observes: prospective candidate, integration, Verification,
|
|
115
127
|
diff, target. It records no candidate and satisfies no gate.
|
|
116
128
|
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { type TellResult } from "./body.js";
|
|
2
|
-
import { type KillEvidence } from "./heart/index.js";
|
|
3
|
-
import { type AkuId } from "./identity.js";
|
|
1
|
+
import { type TellResult, type TellWakeRuntime } from "./body.js";
|
|
2
|
+
import { HeldAkumaLeash, type KillEvidence } from "./heart/index.js";
|
|
3
|
+
import { type AkuId, type AkumaPaths } from "./identity.js";
|
|
4
4
|
import { type ActivityHistory, type ExactHistory } from "./projection.js";
|
|
5
5
|
import type { AkumaCallExecution, AkumaStatus, ForkReceipt, InterruptReceipt } from "./akuma.js";
|
|
6
6
|
import type { WorldRoot } from "../world.js";
|
|
7
7
|
declare const CALL_EXECUTION: unique symbol;
|
|
8
|
+
export declare function settleAkumaKill(paths: AkumaPaths, signal?: AbortSignal, retainLeash?: boolean): Promise<Readonly<{
|
|
9
|
+
evidence: KillEvidence;
|
|
10
|
+
leash?: HeldAkumaLeash;
|
|
11
|
+
}>>;
|
|
12
|
+
export declare function killAkumaWithRecovery(paths: AkumaPaths, recover?: (paths: AkumaPaths) => Promise<void>, signal?: AbortSignal): Promise<KillEvidence>;
|
|
8
13
|
export declare class AkumaHandle {
|
|
9
14
|
readonly id: AkuId;
|
|
10
15
|
private readonly worldPath;
|
|
@@ -23,13 +28,19 @@ export declare class AkumaHandle {
|
|
|
23
28
|
wait(predicate?: (status: AkumaStatus) => boolean, options?: Readonly<{
|
|
24
29
|
timeoutMs?: number;
|
|
25
30
|
}>): Promise<AkumaStatus>;
|
|
26
|
-
tell(body: string): Promise<TellResult>;
|
|
27
|
-
interrupt(body: string
|
|
28
|
-
|
|
31
|
+
tell(body: string, tellId?: string, recordedAt?: string, runtime?: TellWakeRuntime, schemaJson?: string): Promise<TellResult>;
|
|
32
|
+
interrupt(body: string, options?: Readonly<{
|
|
33
|
+
tellId?: string;
|
|
34
|
+
schemaJson?: string;
|
|
35
|
+
signal?: AbortSignal;
|
|
36
|
+
runtime?: TellWakeRuntime;
|
|
37
|
+
}>): Promise<InterruptReceipt>;
|
|
29
38
|
fork(input: Readonly<{
|
|
30
39
|
at: string;
|
|
31
40
|
}>): Promise<ForkReceipt>;
|
|
32
|
-
kill(
|
|
41
|
+
kill(options?: Readonly<{
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
}>): Promise<KillEvidence>;
|
|
33
44
|
lastAnswer(): Promise<LastAnswer>;
|
|
34
45
|
}
|
|
35
46
|
/** Package-internal provenance retained only by the handle returned from call. */
|
|
@@ -1,73 +1,81 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { handoffPendingTells, wakeRecordedTell } from "./body.js";
|
|
3
3
|
import { HeldAkumaLeash, activitySlice, readForkPoint, readHeart, readKill, readLastAnsweredTurn, readSoul, recordTell, requestPause, requestStop, } from "./heart/index.js";
|
|
4
|
+
import { acquireLeash } from "./control.js";
|
|
4
5
|
import { parsePublicHistoryId, pathsForAkuId } from "./identity.js";
|
|
5
6
|
import { projectTurns, selectHistory, selectExactHistory, } from "./projection.js";
|
|
6
7
|
import { resolveProviderExecution } from "./providers/index.js";
|
|
7
8
|
import { publishAkuma } from "./publication.js";
|
|
8
9
|
import { spawnAkumaBody } from "./body.js";
|
|
9
10
|
import { AkumaNotBornError } from "./akuma-errors.js";
|
|
10
|
-
import { bornStatus } from "./akuma-observe.js";
|
|
11
|
+
import { bornStatus, defaultWaitComplete, readWaitComplete } from "./akuma-observe.js";
|
|
11
12
|
const CALL_EXECUTION = Symbol("akuma-call-execution");
|
|
12
13
|
const POLL_MS = 100;
|
|
13
14
|
const wait = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
14
15
|
function diagnostic(error) {
|
|
15
16
|
return error instanceof Error ? error.message : String(error);
|
|
16
17
|
}
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
async function takeLeashUntilSignal(paths, bodySequence, signal, unbounded = false) {
|
|
19
|
+
const leash = await acquireLeash(paths, {
|
|
20
|
+
bodySequence,
|
|
21
|
+
...(signal === undefined && unbounded ? { deadline: Number.POSITIVE_INFINITY } : {}),
|
|
22
|
+
...(signal === undefined ? {} : { signal }),
|
|
23
|
+
});
|
|
24
|
+
if (leash !== null)
|
|
25
|
+
return leash;
|
|
26
|
+
const latestBody = (await readHeart(paths)).latestBody;
|
|
27
|
+
if (latestBody?.sequence === bodySequence && latestBody.hung !== undefined)
|
|
28
|
+
return { kind: "unavailable", evidence: "hung" };
|
|
29
|
+
if (latestBody?.sequence === bodySequence && latestBody.end !== undefined)
|
|
30
|
+
return { kind: "unavailable", evidence: "untidy" };
|
|
31
|
+
return { kind: "unavailable", evidence: "unavailable" };
|
|
20
32
|
}
|
|
21
|
-
async function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
await wait(Math.min(POLL_MS, Math.max(0, deadline - performance.now())));
|
|
33
|
+
export async function settleAkumaKill(paths, signal, retainLeash = false) {
|
|
34
|
+
const request = await requestStop(paths, new Date().toISOString(), signal);
|
|
35
|
+
if (request.kind !== "requested") {
|
|
36
|
+
if (!retainLeash)
|
|
37
|
+
return { evidence: request.kind };
|
|
38
|
+
const leash = await acquireLeash(paths, signal === undefined ? {} : { signal });
|
|
39
|
+
return leash === null ? { evidence: "unavailable" } : { evidence: request.kind, leash };
|
|
29
40
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
41
|
+
const target = request.body;
|
|
42
|
+
const waited = await takeLeashUntilSignal(paths, target.sequence, signal);
|
|
43
|
+
if ("kind" in waited) {
|
|
44
|
+
if ((await readKill(paths, target.sequence)) !== null)
|
|
45
|
+
return { evidence: "killed" };
|
|
46
|
+
return { evidence: waited.evidence };
|
|
47
|
+
}
|
|
48
|
+
const leash = waited;
|
|
49
|
+
let retain = false;
|
|
38
50
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if ((await readKill(paths, target.sequence)) !== null) {
|
|
45
|
-
leash?.release();
|
|
46
|
-
return "killed";
|
|
51
|
+
if ((await readKill(paths, target.sequence)) !== null)
|
|
52
|
+
return { evidence: "killed" };
|
|
53
|
+
const settledBody = (await readHeart(paths)).latestBody;
|
|
54
|
+
if (settledBody?.sequence !== target.sequence) {
|
|
55
|
+
return { evidence: (await readKill(paths, target.sequence)) === null ? "unavailable" : "killed" };
|
|
47
56
|
}
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const body = (await readHeart(paths)).latestBody;
|
|
52
|
-
return body?.sequence === target.sequence && body.hung !== undefined ? "hung" : "unavailable";
|
|
53
|
-
}
|
|
54
|
-
try {
|
|
55
|
-
const settledBody = (await readHeart(paths)).latestBody;
|
|
56
|
-
if (settledBody?.sequence !== target.sequence)
|
|
57
|
-
return (await readKill(paths, target.sequence)) === null ? "unavailable" : "killed";
|
|
58
|
-
if (settledBody.end !== "put-down") {
|
|
59
|
-
await leash.clearStop(paths);
|
|
60
|
-
return "untidy";
|
|
61
|
-
}
|
|
62
|
-
const settled = await leash.settleStop(paths, target.sequence);
|
|
63
|
-
return settled === null ? "unavailable" : "killed";
|
|
57
|
+
if (settledBody.end !== "put-down") {
|
|
58
|
+
await leash.clearStop(paths);
|
|
59
|
+
return { evidence: "untidy" };
|
|
64
60
|
}
|
|
65
|
-
|
|
61
|
+
const settled = await leash.settleStop(paths, target.sequence);
|
|
62
|
+
if (settled === null)
|
|
63
|
+
return { evidence: "unavailable" };
|
|
64
|
+
retain = retainLeash;
|
|
65
|
+
return retainLeash ? { evidence: "killed", leash } : { evidence: "killed" };
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
if (!retain)
|
|
66
69
|
leash.release();
|
|
67
|
-
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function killAkumaWithRecovery(paths, recover, signal) {
|
|
73
|
+
try {
|
|
74
|
+
return (await settleAkumaKill(paths, signal)).evidence;
|
|
68
75
|
}
|
|
69
76
|
finally {
|
|
70
|
-
|
|
77
|
+
if (recover !== undefined)
|
|
78
|
+
void recover(paths).catch(() => undefined);
|
|
71
79
|
}
|
|
72
80
|
}
|
|
73
81
|
export class AkumaHandle {
|
|
@@ -129,108 +137,77 @@ export class AkumaHandle {
|
|
|
129
137
|
}
|
|
130
138
|
const deadline = options.timeoutMs === undefined ? undefined : performance.now() + options.timeoutMs;
|
|
131
139
|
for (;;) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
140
|
+
if (predicate !== defaultWaitComplete ||
|
|
141
|
+
(deadline !== undefined && performance.now() >= deadline) ||
|
|
142
|
+
(await readWaitComplete(this.worldPath, this.id))) {
|
|
143
|
+
const status = await this.status();
|
|
144
|
+
if (predicate(status) || (deadline !== undefined && performance.now() >= deadline))
|
|
145
|
+
return status;
|
|
146
|
+
}
|
|
135
147
|
await wait(deadline === undefined ? POLL_MS : Math.min(POLL_MS, Math.max(0, deadline - performance.now())));
|
|
136
148
|
}
|
|
137
149
|
}
|
|
138
|
-
async tell(body) {
|
|
139
|
-
const
|
|
140
|
-
|
|
150
|
+
async tell(body, tellId = randomUUID(), recordedAt = new Date().toISOString(), runtime, schemaJson) {
|
|
151
|
+
const admitted = await recordTell(this.paths, {
|
|
152
|
+
kind: "tell",
|
|
153
|
+
id: tellId,
|
|
154
|
+
body,
|
|
155
|
+
recordedAt,
|
|
156
|
+
...(schemaJson === undefined ? {} : { schemaJson }),
|
|
157
|
+
});
|
|
158
|
+
if (admitted.kind === "not-born")
|
|
159
|
+
throw new AkumaNotBornError(this.id);
|
|
160
|
+
return await wakeRecordedTell(this.paths, admitted.tell.id, runtime);
|
|
141
161
|
}
|
|
142
|
-
async interrupt(body) {
|
|
143
|
-
const request = await requestPause(this.paths, new Date().toISOString());
|
|
162
|
+
async interrupt(body, options = {}) {
|
|
163
|
+
const request = await requestPause(this.paths, new Date().toISOString(), options.signal);
|
|
144
164
|
if (request.kind === "not-born") {
|
|
145
165
|
throw new AkumaNotBornError(this.id);
|
|
146
166
|
}
|
|
147
167
|
let putDown = "was-idle";
|
|
148
168
|
let leash = await HeldAkumaLeash.try(this.paths);
|
|
149
169
|
if (leash === null) {
|
|
150
|
-
|
|
170
|
+
const waited = await takeLeashUntilSignal(this.paths, request.body.sequence, options.signal, true);
|
|
171
|
+
if ("kind" in waited)
|
|
172
|
+
return waited;
|
|
173
|
+
leash = waited;
|
|
151
174
|
putDown = "self-aborted";
|
|
152
175
|
}
|
|
153
|
-
if (leash === null) {
|
|
154
|
-
const body = (await readHeart(this.paths)).latestBody;
|
|
155
|
-
return {
|
|
156
|
-
kind: "unavailable",
|
|
157
|
-
evidence: body?.sequence === request.body.sequence && body.hung !== undefined ? "hung" : "unavailable",
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
const settledBody = (await readHeart(this.paths)).latestBody;
|
|
161
|
-
if (settledBody?.sequence === request.body.sequence && settledBody.hung !== undefined) {
|
|
162
|
-
try {
|
|
163
|
-
await leash.clearPause(this.paths);
|
|
164
|
-
}
|
|
165
|
-
finally {
|
|
166
|
-
leash.release();
|
|
167
|
-
}
|
|
168
|
-
return { kind: "unavailable", evidence: "hung" };
|
|
169
|
-
}
|
|
170
|
-
if (settledBody?.sequence !== request.body.sequence || settledBody.end === undefined) {
|
|
171
|
-
try {
|
|
172
|
-
await leash.clearPause(this.paths);
|
|
173
|
-
}
|
|
174
|
-
finally {
|
|
175
|
-
leash.release();
|
|
176
|
-
}
|
|
177
|
-
return { kind: "unavailable", evidence: "untidy" };
|
|
178
|
-
}
|
|
179
|
-
if (request.body.end !== undefined || settledBody.end !== "put-down")
|
|
180
|
-
putDown = "was-idle";
|
|
181
176
|
let recorded;
|
|
182
177
|
try {
|
|
183
|
-
|
|
184
|
-
const admitted = await leash.recordInterruptTell(this.paths, {
|
|
185
|
-
kind: "tell",
|
|
186
|
-
id,
|
|
187
|
-
body,
|
|
188
|
-
recordedAt: new Date().toISOString(),
|
|
189
|
-
});
|
|
190
|
-
if (admitted.kind === "not-born")
|
|
191
|
-
throw new AkumaNotBornError(this.id);
|
|
192
|
-
recorded = { kind: "recorded", tellId: admitted.tell.id };
|
|
193
|
-
}
|
|
194
|
-
finally {
|
|
195
|
-
leash.release();
|
|
196
|
-
}
|
|
197
|
-
return { kind: "interrupted", putDown, tell: await wakeRecordedTell(this.paths, recorded.tellId) };
|
|
198
|
-
}
|
|
199
|
-
async interruptSchema(body, schemaJson) {
|
|
200
|
-
const request = await requestPause(this.paths, new Date().toISOString());
|
|
201
|
-
if (request.kind === "not-born")
|
|
202
|
-
throw new AkumaNotBornError(this.id);
|
|
203
|
-
let tellId;
|
|
204
|
-
let leash = await HeldAkumaLeash.try(this.paths);
|
|
205
|
-
if (leash === null)
|
|
206
|
-
leash = await takeLeashUntil(this.paths, performance.now() + CONTROL_RESPONSE_MS);
|
|
207
|
-
if (leash === null)
|
|
208
|
-
throw new Error("schema interrupt could not acquire Body leash");
|
|
209
|
-
try {
|
|
178
|
+
options.signal?.throwIfAborted();
|
|
210
179
|
const settledBody = (await readHeart(this.paths)).latestBody;
|
|
211
180
|
if (settledBody?.sequence === request.body.sequence && settledBody.hung !== undefined) {
|
|
212
181
|
await leash.clearPause(this.paths);
|
|
213
|
-
|
|
182
|
+
return { kind: "unavailable", evidence: "hung" };
|
|
214
183
|
}
|
|
215
184
|
if (settledBody?.sequence !== request.body.sequence || settledBody.end === undefined) {
|
|
216
185
|
await leash.clearPause(this.paths);
|
|
217
|
-
|
|
186
|
+
return { kind: "unavailable", evidence: "untidy" };
|
|
218
187
|
}
|
|
188
|
+
if (request.body.end !== undefined || settledBody.end !== "put-down")
|
|
189
|
+
putDown = "was-idle";
|
|
190
|
+
options.signal?.throwIfAborted();
|
|
191
|
+
const id = randomUUID();
|
|
219
192
|
const admitted = await leash.recordInterruptTell(this.paths, {
|
|
220
193
|
kind: "tell",
|
|
221
|
-
id:
|
|
194
|
+
id: options.tellId ?? id,
|
|
222
195
|
body,
|
|
223
196
|
recordedAt: new Date().toISOString(),
|
|
224
|
-
schemaJson,
|
|
197
|
+
...(options.schemaJson === undefined ? {} : { schemaJson: options.schemaJson }),
|
|
225
198
|
});
|
|
226
199
|
if (admitted.kind === "not-born")
|
|
227
200
|
throw new AkumaNotBornError(this.id);
|
|
228
|
-
|
|
201
|
+
recorded = { kind: "recorded", tellId: admitted.tell.id };
|
|
229
202
|
}
|
|
230
203
|
finally {
|
|
231
204
|
leash.release();
|
|
232
205
|
}
|
|
233
|
-
return
|
|
206
|
+
return {
|
|
207
|
+
kind: "interrupted",
|
|
208
|
+
putDown,
|
|
209
|
+
tell: await wakeRecordedTell(this.paths, recorded.tellId, options.runtime),
|
|
210
|
+
};
|
|
234
211
|
}
|
|
235
212
|
async fork(input) {
|
|
236
213
|
const source = await readSoul(this.paths);
|
|
@@ -296,8 +273,8 @@ export class AkumaHandle {
|
|
|
296
273
|
};
|
|
297
274
|
}
|
|
298
275
|
}
|
|
299
|
-
async kill() {
|
|
300
|
-
return await killAkumaWithRecovery(this.paths);
|
|
276
|
+
async kill(options = {}) {
|
|
277
|
+
return await killAkumaWithRecovery(this.paths, handoffPendingTells, options.signal);
|
|
301
278
|
}
|
|
302
279
|
async lastAnswer() {
|
|
303
280
|
const turn = await readLastAnsweredTurn(this.paths);
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import type { AllowedAction } from "./allowed.js";
|
|
2
|
+
import type { AkumaStatus } from "./akuma.js";
|
|
3
|
+
import type { InterruptReceipt, KillEvidence } from "./akuma.js";
|
|
2
4
|
import { type AkuId } from "./identity.js";
|
|
3
5
|
import { type ActivityHistory } from "./projection.js";
|
|
4
6
|
import type { Settings } from "../settings.js";
|
|
5
7
|
import type { WorldRoot } from "../world.js";
|
|
6
|
-
import type
|
|
8
|
+
import { type Schema } from "./schema.js";
|
|
9
|
+
export type AkumaIdleOptions = Readonly<{
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}>;
|
|
12
|
+
export type AkumaHistoryOptions = Readonly<{
|
|
13
|
+
before?: number;
|
|
14
|
+
since?: number;
|
|
15
|
+
limit?: number;
|
|
16
|
+
}>;
|
|
17
|
+
export type AkumaSignalOptions = Readonly<{
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}>;
|
|
7
20
|
export type AkumaBirthInput = Readonly<{
|
|
8
21
|
root: WorldRoot;
|
|
9
22
|
cwd?: string;
|
|
@@ -25,7 +38,9 @@ export declare class Akuma {
|
|
|
25
38
|
static select(root: WorldRoot, selector: string): Akuma;
|
|
26
39
|
tell(text: string): Promise<string>;
|
|
27
40
|
tell<T>(text: string, options: AkumaTellOptions<T>): Promise<T>;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
status(): Promise<AkumaStatus>;
|
|
42
|
+
interrupt(text: string, options?: AkumaSignalOptions): Promise<InterruptReceipt>;
|
|
43
|
+
idle(options?: AkumaIdleOptions): Promise<void>;
|
|
44
|
+
history(options?: AkumaHistoryOptions): Promise<ActivityHistory>;
|
|
45
|
+
kill(options?: AkumaSignalOptions): Promise<KillEvidence>;
|
|
31
46
|
}
|