@astrosheep/keiyaku 4.5.7 → 4.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/opencode.js +3 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +10 -9
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +22 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +35 -96
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +28 -49
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +21 -15
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +148 -89
- package/build/src/akuma/abort.d.ts +2 -1
- package/build/src/akuma/abort.js +6 -23
- package/build/src/akuma/akuma-handle.js +4 -2
- package/build/src/akuma/akuma-observe.d.ts +2 -0
- package/build/src/akuma/akuma-observe.js +1 -0
- package/build/src/akuma/akuma-product.js +9 -7
- package/build/src/akuma/akuma.d.ts +372 -9
- package/build/src/akuma/akuma.js +31 -1
- package/build/src/akuma/allowed.d.ts +1 -1
- package/build/src/akuma/allowed.js +1 -0
- package/build/src/akuma/body.d.ts +6 -4
- package/build/src/akuma/body.js +5 -3
- package/build/src/akuma/call-request.d.ts +80 -0
- package/build/src/akuma/call-request.js +211 -0
- package/build/src/akuma/heart/facts.d.ts +6 -78
- package/build/src/akuma/heart/index.d.ts +1 -1
- package/build/src/akuma/heart/request-authority.d.ts +5 -4
- package/build/src/akuma/heart/request-authority.js +20 -34
- package/build/src/akuma/heart/request-rows.js +12 -23
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +5 -13
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/projection-read.d.ts +1 -0
- package/build/src/akuma/projection-read.js +8 -1
- package/build/src/akuma/projection.d.ts +856 -137
- package/build/src/akuma/projection.js +190 -0
- package/build/src/akuma/provider.d.ts +30 -3
- package/build/src/akuma/provider.js +104 -0
- package/build/src/akuma/providers/acp/core.d.ts +2 -2
- package/build/src/akuma/providers/acp/core.js +13 -6
- package/build/src/akuma/providers/acp/index.js +5 -4
- package/build/src/akuma/providers/claude/index.d.ts +3 -3
- package/build/src/akuma/providers/claude/index.js +16 -5
- package/build/src/akuma/providers/codex-app-server/events.js +1 -1
- package/build/src/akuma/providers/codex-app-server/index.js +18 -6
- package/build/src/akuma/providers/grok-build/index.js +5 -4
- package/build/src/akuma/providers/opencode-sdk/index.js +66 -25
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/session.js +28 -11
- package/build/src/akuma/providers/pi/index.js +42 -14
- package/build/src/akuma/request-lifecycle.d.ts +3 -9
- package/build/src/akuma/request-lifecycle.js +4 -4
- package/build/src/akuma/request-rendezvous.d.ts +26 -0
- package/build/src/akuma/request-rendezvous.js +100 -0
- package/build/src/akuma/request-serve.d.ts +5 -65
- package/build/src/akuma/request-serve.js +81 -208
- package/build/src/akuma/request-wire.d.ts +109 -115
- package/build/src/akuma/request-wire.js +63 -318
- package/build/src/akuma/requests.d.ts +19 -47
- package/build/src/akuma/requests.js +51 -107
- package/build/src/akuma/turn-drive.d.ts +5 -3
- package/build/src/akuma/turn-drive.js +32 -10
- package/build/src/akuma-body.d.ts +7 -2
- package/build/src/akuma-body.js +68 -46
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +2 -2
- package/build/src/cli/commands/akuma-invoke.d.ts +2 -0
- package/build/src/cli/commands/akuma-invoke.js +17 -9
- package/build/src/cli/commands/akuma.js +7 -7
- package/build/src/cli/commands/contract-invoke.d.ts +3 -2
- package/build/src/cli/commands/contract-invoke.js +26 -19
- package/build/src/cli/commands/contract.d.ts +13 -13
- package/build/src/cli/commands/contract.js +32 -17
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +1 -1
- package/build/src/cli/commands/task-invoke.d.ts +3 -0
- package/build/src/cli/commands/task-invoke.js +23 -140
- package/build/src/cli/commands/task.js +54 -20
- package/build/src/cli/invoke.js +39 -25
- package/build/src/cli/main.js +2 -1
- package/build/src/cli/parse.d.ts +2 -2
- package/build/src/cli/parse.js +37 -22
- package/build/src/cli/render/akuma-activity.d.ts +4 -1
- package/build/src/cli/render/akuma-activity.js +45 -30
- package/build/src/cli/render/akuma-tool.d.ts +5 -1
- package/build/src/cli/render/akuma.js +5 -9
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/catalog.js +80 -21
- package/build/src/cli/render/contract-observation.d.ts +2 -0
- package/build/src/cli/render/contract-observation.js +11 -0
- package/build/src/cli/render/contract.js +25 -65
- package/build/src/cli/render/kanshi-akuma.d.ts +8 -0
- package/build/src/cli/render/kanshi-akuma.js +111 -0
- package/build/src/cli/render/kanshi.js +108 -213
- package/build/src/cli/render/receipt.d.ts +1 -2
- package/build/src/cli/render/receipt.js +76 -26
- package/build/src/cli/render/refusal.js +2 -10
- package/build/src/cli/render/region.js +5 -2
- package/build/src/cli/render/settings.d.ts +1 -1
- package/build/src/cli/render/settings.js +27 -8
- package/build/src/cli/render/task.js +22 -5
- package/build/src/cli/render/terminal.d.ts +28 -0
- package/build/src/cli/render/terminal.js +65 -0
- package/build/src/cli/result.d.ts +3 -3
- package/build/src/cli/runtime.js +3 -1
- package/build/src/cli/selectors.d.ts +2 -1
- package/build/src/cli/selectors.js +4 -3
- package/build/src/cli/square-edge.js +120 -36
- package/build/src/cli/usage.js +2 -1
- package/build/src/contract-guidance.d.ts +5 -0
- package/build/src/contract-guidance.js +121 -0
- package/build/src/contract-worktree.d.ts +0 -1
- package/build/src/contract-worktree.js +32 -83
- package/build/src/coordination/sqlite-transaction-lock.d.ts +1 -0
- package/build/src/coordination/sqlite-transaction-lock.js +5 -0
- package/build/src/core/facts/codec.d.ts +2 -0
- package/build/src/core/facts/codec.js +4 -0
- package/build/src/core/verbs/placement.d.ts +6 -1
- package/build/src/core/verbs/placement.js +5 -3
- package/build/src/dispatch/index.d.ts +0 -2
- package/build/src/dispatch/index.js +54 -55
- package/build/src/git/admission.js +2 -2
- package/build/src/git/hooks.d.ts +9 -15
- package/build/src/git/hooks.js +23 -317
- package/build/src/git/nuke.d.ts +2 -1
- package/build/src/git/nuke.js +36 -18
- package/build/src/git/private-state-seat.d.ts +12 -0
- package/build/src/git/private-state-seat.js +39 -0
- package/build/src/git/process.d.ts +6 -0
- package/build/src/git/process.js +19 -7
- package/build/src/git/read-observation.js +29 -20
- package/build/src/git/reconcile.d.ts +11 -0
- package/build/src/git/reconcile.js +64 -11
- package/build/src/git/repository.d.ts +6 -2
- package/build/src/git/repository.js +8 -0
- package/build/src/git/target-placement.d.ts +1 -0
- package/build/src/git/target-placement.js +5 -0
- package/build/src/git/tender.d.ts +1 -0
- package/build/src/git/terminal-reconcile.d.ts +1 -1
- package/build/src/git/terminal-reconcile.js +22 -20
- package/build/src/git/workspace.d.ts +14 -0
- package/build/src/git/workspace.js +44 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +16 -16
- package/build/src/kanshi/report.d.ts +2 -2
- package/build/src/library/address.d.ts +9 -3
- package/build/src/library/address.js +3 -2
- package/build/src/library/akuma-creation.d.ts +4 -3
- package/build/src/library/akuma-creation.js +19 -13
- package/build/src/library/audit.d.ts +1 -1
- package/build/src/library/audit.js +5 -3
- package/build/src/library/catalog.d.ts +3 -1
- package/build/src/library/catalog.js +20 -6
- package/build/src/library/composition.d.ts +371 -0
- package/build/src/library/composition.js +28 -0
- package/build/src/library/configuration.js +8 -2
- package/build/src/library/continuation.js +66 -30
- package/build/src/library/contract-bind.js +10 -2
- package/build/src/library/contract-forwarding-reconciliation-result.d.ts +96 -0
- package/build/src/library/contract-forwarding-reconciliation-result.js +83 -0
- package/build/src/library/contract-forwarding-result.d.ts +6723 -0
- package/build/src/library/contract-forwarding-result.js +521 -0
- package/build/src/library/contract-forwarding.d.ts +72 -0
- package/build/src/library/contract-forwarding.js +125 -0
- package/build/src/library/contract-handle.d.ts +36 -0
- package/build/src/library/contract-handle.js +313 -0
- package/build/src/library/contract-operations.d.ts +1044 -67
- package/build/src/library/contract-operations.js +190 -118
- package/build/src/library/contract.d.ts +11 -32
- package/build/src/library/contract.js +16 -289
- package/build/src/library/fleet-result.d.ts +1454 -0
- package/build/src/library/fleet-result.js +96 -0
- package/build/src/library/fleet.d.ts +112 -54
- package/build/src/library/fleet.js +211 -71
- package/build/src/library/input.d.ts +2 -0
- package/build/src/library/input.js +4 -0
- package/build/src/library/keiyaku.d.ts +371 -20
- package/build/src/library/keiyaku.js +8 -21
- package/build/src/library/mutation.d.ts +3 -3
- package/build/src/library/mutation.js +5 -9
- package/build/src/library/nuke.d.ts +1 -1
- package/build/src/library/nuke.js +4 -3
- package/build/src/library/reconcile.d.ts +4 -0
- package/build/src/library/reconcile.js +2 -0
- package/build/src/library/refusal.d.ts +0 -9
- package/build/src/library/refusal.js +0 -7
- package/build/src/protocol/amend.js +56 -50
- package/build/src/protocol/attempt.d.ts +2 -0
- package/build/src/protocol/attempt.js +8 -1
- package/build/src/protocol/completion.js +7 -0
- package/build/src/protocol/deliver.js +6 -2
- package/build/src/protocol/operations.d.ts +4 -1
- package/build/src/protocol/operations.js +5 -2
- package/build/src/protocol/placement.d.ts +1 -0
- package/build/src/protocol/placement.js +52 -38
- package/build/src/protocol/read/observation.d.ts +1 -4
- package/build/src/protocol/read/observation.js +2 -15
- package/build/src/protocol/reintegrate.js +62 -58
- package/build/src/protocol/review.js +5 -0
- package/build/src/protocol/run.js +17 -13
- package/build/src/runtime/proc/run.d.ts +8 -0
- package/build/src/runtime/proc/run.js +27 -0
- package/build/src/runtime/proc/termination.js +26 -22
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/holder.d.ts +2 -1
- package/build/src/settlement/holder.js +15 -4
- package/build/src/settlement/settle.js +99 -33
- package/build/src/task/board.d.ts +68 -27
- package/build/src/task/board.js +31 -1
- package/build/src/task/catalog.d.ts +4 -0
- package/build/src/task/catalog.js +23 -0
- package/build/src/task/compose-language.js +33 -7
- package/build/src/task/compose-parser.d.ts +1 -1
- package/build/src/task/compose-parser.js +1 -1
- package/build/src/task/compose.js +2 -0
- package/build/src/task/index.d.ts +12 -4
- package/build/src/task/index.js +97 -16
- package/build/src/task/mutation-result.d.ts +923 -0
- package/build/src/task/mutation-result.js +140 -0
- package/build/src/task/mutation.d.ts +552 -28
- package/build/src/task/mutation.js +304 -97
- package/build/src/task/operations.d.ts +1 -4
- package/build/src/task/operations.js +0 -6
- package/build/src/task/public.d.ts +2 -0
- package/build/src/task/public.js +1 -0
- package/build/src/workspace-place.d.ts +7 -2
- package/build/src/workspace-place.js +34 -24
- package/build/src/world.d.ts +1 -0
- package/build/src/world.js +11 -0
- package/package.json +8 -6
- package/build/src/akuma/request-execution.d.ts +0 -8
- package/build/src/akuma/request-execution.js +0 -98
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { akumaIdSchema, akumaStatusSchema } from "../akuma/akuma.js";
|
|
2
|
+
import { contractId } from "../core/facts/types.js";
|
|
3
|
+
import { taskRowsSchema } from "../task/board.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
const nonblankTextSchema = z.string().refine((value) => value.trim() !== "");
|
|
6
|
+
const contractIdSchema = z.string().transform((value, context) => {
|
|
7
|
+
try {
|
|
8
|
+
return contractId(value);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
context.addIssue({ code: "custom", message: "expected ContractId" });
|
|
12
|
+
return z.NEVER;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const killEvidenceSchema = z.enum([
|
|
16
|
+
"killed",
|
|
17
|
+
"already-killed",
|
|
18
|
+
"already-stopped",
|
|
19
|
+
"hung",
|
|
20
|
+
"untidy",
|
|
21
|
+
"unavailable",
|
|
22
|
+
]);
|
|
23
|
+
const dispatchAssociationSchema = z.union([
|
|
24
|
+
z.object({ kind: z.literal("none") }).strict(),
|
|
25
|
+
z.object({ kind: z.literal("associated"), contractId: contractIdSchema }).strict(),
|
|
26
|
+
z.object({ kind: z.literal("failed"), diagnostic: z.string() }).strict(),
|
|
27
|
+
]);
|
|
28
|
+
const createdTaskObservationSchema = z.union([
|
|
29
|
+
z.object({ kind: z.literal("present"), rows: taskRowsSchema }).strict(),
|
|
30
|
+
z.object({ kind: z.literal("failed"), diagnostic: z.string() }).strict(),
|
|
31
|
+
]);
|
|
32
|
+
const akumaObservationSchema = z
|
|
33
|
+
.object({
|
|
34
|
+
status: akumaStatusSchema,
|
|
35
|
+
contract: dispatchAssociationSchema,
|
|
36
|
+
createdTasks: createdTaskObservationSchema,
|
|
37
|
+
})
|
|
38
|
+
.strict();
|
|
39
|
+
const runLogReferenceSchema = z
|
|
40
|
+
.object({ path: z.string(), from: z.number().int().nonnegative(), to: z.number().int().nonnegative() })
|
|
41
|
+
.strict();
|
|
42
|
+
const failedTellWakeSchema = z
|
|
43
|
+
.object({
|
|
44
|
+
kind: z.literal("failed"),
|
|
45
|
+
diagnostic: z.string(),
|
|
46
|
+
child: z
|
|
47
|
+
.object({ code: z.number().int().nullable(), signal: z.string().nullable(), log: runLogReferenceSchema })
|
|
48
|
+
.strict()
|
|
49
|
+
.optional(),
|
|
50
|
+
})
|
|
51
|
+
.strict()
|
|
52
|
+
.transform(({ child, ...wake }) => (child === undefined ? wake : { ...wake, child }));
|
|
53
|
+
const tellWakeSchema = z.union([
|
|
54
|
+
z.object({ kind: z.literal("told") }).strict(),
|
|
55
|
+
z.object({ kind: z.literal("held") }).strict(),
|
|
56
|
+
z.object({ kind: z.literal("pursuing"), bodySequence: z.number().int().nonnegative() }).strict(),
|
|
57
|
+
failedTellWakeSchema,
|
|
58
|
+
]);
|
|
59
|
+
const tellResultSchema = z
|
|
60
|
+
.object({
|
|
61
|
+
admission: z.object({ fact: z.literal("recorded"), tellId: nonblankTextSchema }).strict(),
|
|
62
|
+
wake: tellWakeSchema,
|
|
63
|
+
})
|
|
64
|
+
.strict();
|
|
65
|
+
const akumaUnobservedSchema = z.object({ id: akumaIdSchema, diagnostic: z.string() }).strict();
|
|
66
|
+
const akumaKillResultItemSchema = z.object({ id: akumaIdSchema, evidence: killEvidenceSchema }).strict();
|
|
67
|
+
const akumaWaitResultSchema = z
|
|
68
|
+
.object({
|
|
69
|
+
completion: z.enum(["any", "all"]),
|
|
70
|
+
observations: z.array(akumaObservationSchema),
|
|
71
|
+
unobserved: z.array(akumaUnobservedSchema),
|
|
72
|
+
})
|
|
73
|
+
.strict();
|
|
74
|
+
const akumaKillResultSchema = z.object({ results: z.array(akumaKillResultItemSchema) }).strict();
|
|
75
|
+
const akumaTellResultSchema = z.object({ akuma: akumaIdSchema, tell: tellResultSchema }).strict();
|
|
76
|
+
export function parseCreatedTaskObservation(value) {
|
|
77
|
+
return createdTaskObservationSchema.parse(value);
|
|
78
|
+
}
|
|
79
|
+
export function parseAkumaObservation(value) {
|
|
80
|
+
return akumaObservationSchema.parse(value);
|
|
81
|
+
}
|
|
82
|
+
export function isWaitResult(value) {
|
|
83
|
+
return akumaWaitResultSchema.safeParse(value).success;
|
|
84
|
+
}
|
|
85
|
+
export function isKillResult(value) {
|
|
86
|
+
return akumaKillResultSchema.safeParse(value).success;
|
|
87
|
+
}
|
|
88
|
+
export function isTellResult(value) {
|
|
89
|
+
return akumaTellResultSchema.safeParse(value).success;
|
|
90
|
+
}
|
|
91
|
+
export const fleetResultSchemas = {
|
|
92
|
+
wait: akumaWaitResultSchema,
|
|
93
|
+
tell: akumaTellResultSchema,
|
|
94
|
+
kill: akumaKillResultSchema,
|
|
95
|
+
killEvidence: killEvidenceSchema,
|
|
96
|
+
};
|
|
@@ -1,64 +1,19 @@
|
|
|
1
|
-
import { type ActivityHistory, type OutcomeRow, type AkumaStatus, type InterruptReceipt, type KillEvidence
|
|
2
|
-
import type
|
|
3
|
-
import type
|
|
1
|
+
import { type ActivityHistory, type OutcomeRow, type AkumaStatus, type InterruptReceipt, type KillEvidence } from "../akuma/index.js";
|
|
2
|
+
import { type ExecutionContext } from "../akuma/requests.js";
|
|
3
|
+
import { type ErasedRequestCommand, type RequestCommand } from "../akuma/request-wire.js";
|
|
4
4
|
import type { WorldRoot } from "../world.js";
|
|
5
5
|
import { type AkumaAddressInput, type AkumaSetAddressInput } from "./address.js";
|
|
6
|
+
import { type AkumaKillResult, type AkumaObservation, type AkumaObservationStage, type AkumaTellResult, type AkumaWaitResult, type DispatchAssociation } from "./fleet-result.js";
|
|
7
|
+
export type { AkumaKillResult, AkumaObservation, AkumaObservationStage, AkumaTellResult, AkumaUnobserved, AkumaWaitResult, CreatedTaskObservation, DispatchAssociation, } from "./fleet-result.js";
|
|
6
8
|
import { type Repo } from "./repo.js";
|
|
7
|
-
|
|
8
|
-
kind: "present";
|
|
9
|
-
rows: readonly TaskRow[];
|
|
10
|
-
}> | Readonly<{
|
|
11
|
-
kind: "failed";
|
|
12
|
-
diagnostic: string;
|
|
13
|
-
}>;
|
|
14
|
-
export type DispatchAssociation = Readonly<{
|
|
15
|
-
kind: "none";
|
|
16
|
-
}> | Readonly<{
|
|
17
|
-
kind: "associated";
|
|
18
|
-
contractId: ContractId;
|
|
19
|
-
}> | Readonly<{
|
|
20
|
-
kind: "failed";
|
|
21
|
-
diagnostic: string;
|
|
22
|
-
}>;
|
|
23
|
-
export type AkumaObservation = Readonly<{
|
|
24
|
-
status: AkumaStatus;
|
|
25
|
-
contract: DispatchAssociation;
|
|
26
|
-
createdTasks: CreatedTaskObservation;
|
|
27
|
-
}>;
|
|
28
|
-
export type AkumaObservationStage = (Readonly<{
|
|
29
|
-
kind: "observed";
|
|
30
|
-
}> & AkumaObservation) | Readonly<{
|
|
31
|
-
kind: "unobserved";
|
|
32
|
-
diagnostic: string;
|
|
33
|
-
}>;
|
|
34
|
-
export type AkumaUnobserved = Readonly<{
|
|
35
|
-
id: AkumaStatus["id"];
|
|
36
|
-
diagnostic: string;
|
|
37
|
-
}>;
|
|
9
|
+
import { z } from "zod";
|
|
38
10
|
export type AkumaWaitInput = AkumaSetAddressInput & Readonly<{
|
|
39
11
|
completion?: "any" | "all";
|
|
40
12
|
timeoutMs?: number;
|
|
41
13
|
}>;
|
|
42
|
-
export type AkumaWaitResult = Readonly<{
|
|
43
|
-
completion: "any" | "all";
|
|
44
|
-
observations: readonly AkumaObservation[];
|
|
45
|
-
unobserved: readonly AkumaUnobserved[];
|
|
46
|
-
}>;
|
|
47
|
-
export type AkumaKillResult = Readonly<{
|
|
48
|
-
results: readonly Readonly<{
|
|
49
|
-
id: AkumaStatus["id"];
|
|
50
|
-
evidence: KillEvidence;
|
|
51
|
-
observation: AkumaObservationStage;
|
|
52
|
-
}>[];
|
|
53
|
-
}>;
|
|
54
14
|
export type AkumaTellInput = AkumaAddressInput & Readonly<{
|
|
55
15
|
body: string;
|
|
56
16
|
}>;
|
|
57
|
-
export type AkumaTellResult = Readonly<{
|
|
58
|
-
akuma: AkumaStatus["id"];
|
|
59
|
-
tell: TellResult;
|
|
60
|
-
observation: AkumaObservationStage;
|
|
61
|
-
}>;
|
|
62
17
|
export type { TellResult, TellWake } from "../akuma/index.js";
|
|
63
18
|
export type AkumaInterruptInput = AkumaAddressInput & Readonly<{
|
|
64
19
|
body: string;
|
|
@@ -126,9 +81,112 @@ type KillExecutionInput = Readonly<{
|
|
|
126
81
|
signal?: AbortSignal;
|
|
127
82
|
}>;
|
|
128
83
|
export declare function executeKillAkuma(input: KillExecutionInput): Promise<AkumaKillResult>;
|
|
84
|
+
declare const waitRequestSchema: z.ZodPipe<z.ZodObject<{
|
|
85
|
+
targets: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<import("../akuma/identity.js").AkuId, string>>>;
|
|
86
|
+
completion: z.ZodEnum<{
|
|
87
|
+
any: "any";
|
|
88
|
+
all: "all";
|
|
89
|
+
}>;
|
|
90
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
91
|
+
}, z.core.$strict>, z.ZodTransform<{
|
|
92
|
+
timeoutMs?: number;
|
|
93
|
+
targets: import("../akuma/identity.js").AkuId[];
|
|
94
|
+
completion: "any" | "all";
|
|
95
|
+
action: "akuma.wait";
|
|
96
|
+
}, {
|
|
97
|
+
targets: import("../akuma/identity.js").AkuId[];
|
|
98
|
+
completion: "any" | "all";
|
|
99
|
+
timeoutMs?: number | undefined;
|
|
100
|
+
}>>;
|
|
101
|
+
declare const tellRequestSchema: z.ZodPipe<z.ZodObject<{
|
|
102
|
+
target: z.ZodPipe<z.ZodString, z.ZodTransform<import("../akuma/identity.js").AkuId, string>>;
|
|
103
|
+
body: z.ZodString;
|
|
104
|
+
}, z.core.$strict>, z.ZodTransform<{
|
|
105
|
+
target: import("../akuma/identity.js").AkuId;
|
|
106
|
+
body: string;
|
|
107
|
+
action: "akuma.tell";
|
|
108
|
+
}, {
|
|
109
|
+
target: import("../akuma/identity.js").AkuId;
|
|
110
|
+
body: string;
|
|
111
|
+
}>>;
|
|
112
|
+
declare const killRequestSchema: z.ZodPipe<z.ZodObject<{
|
|
113
|
+
targets: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<import("../akuma/identity.js").AkuId, string>>>;
|
|
114
|
+
}, z.core.$strict>, z.ZodTransform<{
|
|
115
|
+
targets: import("../akuma/identity.js").AkuId[];
|
|
116
|
+
action: "akuma.kill";
|
|
117
|
+
}, {
|
|
118
|
+
targets: import("../akuma/identity.js").AkuId[];
|
|
119
|
+
}>>;
|
|
120
|
+
declare const waitServiceSchema: z.ZodObject<{
|
|
121
|
+
action: z.ZodLiteral<"akuma.wait">;
|
|
122
|
+
}, z.core.$strict>;
|
|
123
|
+
declare const tellServiceSchema: z.ZodObject<{
|
|
124
|
+
action: z.ZodLiteral<"akuma.tell">;
|
|
125
|
+
target: z.ZodPipe<z.ZodString, z.ZodTransform<import("../akuma/identity.js").AkuId, string>>;
|
|
126
|
+
tellId: z.ZodString;
|
|
127
|
+
}, z.core.$strict>;
|
|
128
|
+
declare const killServiceSchema: z.ZodObject<{
|
|
129
|
+
action: z.ZodLiteral<"akuma.kill">;
|
|
130
|
+
results: z.ZodArray<z.ZodObject<{
|
|
131
|
+
id: z.ZodPipe<z.ZodString, z.ZodTransform<import("../akuma/identity.js").AkuId, string>>;
|
|
132
|
+
evidence: z.ZodEnum<{
|
|
133
|
+
unavailable: "unavailable";
|
|
134
|
+
killed: "killed";
|
|
135
|
+
"already-killed": "already-killed";
|
|
136
|
+
"already-stopped": "already-stopped";
|
|
137
|
+
hung: "hung";
|
|
138
|
+
untidy: "untidy";
|
|
139
|
+
}>;
|
|
140
|
+
}, z.core.$strict>>;
|
|
141
|
+
}, z.core.$strict>;
|
|
142
|
+
type FleetRequest = (Omit<z.infer<typeof waitRequestSchema>, "targets"> & Readonly<{
|
|
143
|
+
targets: readonly AkumaStatus["id"][];
|
|
144
|
+
}>) | z.infer<typeof tellRequestSchema> | (Omit<z.infer<typeof killRequestSchema>, "targets"> & Readonly<{
|
|
145
|
+
targets: readonly AkumaStatus["id"][];
|
|
146
|
+
}>);
|
|
147
|
+
type FleetService = z.infer<typeof waitServiceSchema> | z.infer<typeof tellServiceSchema> | (Omit<z.infer<typeof killServiceSchema>, "results"> & Readonly<{
|
|
148
|
+
results: readonly Readonly<{
|
|
149
|
+
id: AkumaStatus["id"];
|
|
150
|
+
evidence: KillEvidence;
|
|
151
|
+
}>[];
|
|
152
|
+
}>);
|
|
153
|
+
export type FleetRequestPort = Readonly<{
|
|
154
|
+
wait(input: Readonly<{
|
|
155
|
+
targets: readonly AkumaStatus["id"][];
|
|
156
|
+
completion: "any" | "all";
|
|
157
|
+
timeoutMs?: number;
|
|
158
|
+
signal: AbortSignal;
|
|
159
|
+
}>): Promise<AkumaWaitResult>;
|
|
160
|
+
tell(input: Readonly<{
|
|
161
|
+
target: AkumaStatus["id"];
|
|
162
|
+
body: string;
|
|
163
|
+
tellId: string;
|
|
164
|
+
recordedAt: string;
|
|
165
|
+
signal: AbortSignal;
|
|
166
|
+
}>): Promise<AkumaTellResult>;
|
|
167
|
+
kill(input: Readonly<{
|
|
168
|
+
targets: readonly AkumaStatus["id"][];
|
|
169
|
+
signal: AbortSignal;
|
|
170
|
+
}>): Promise<AkumaKillResult | Readonly<{
|
|
171
|
+
result: unknown;
|
|
172
|
+
service: readonly Readonly<{
|
|
173
|
+
id: AkumaStatus["id"];
|
|
174
|
+
evidence: KillEvidence;
|
|
175
|
+
}>[];
|
|
176
|
+
}>>;
|
|
177
|
+
}>;
|
|
178
|
+
type FleetExecutionContext = Readonly<{
|
|
179
|
+
id: string;
|
|
180
|
+
admittedAt: string;
|
|
181
|
+
signal: AbortSignal;
|
|
182
|
+
upstream: FleetRequestPort;
|
|
183
|
+
}>;
|
|
184
|
+
/** Fleet owns its Body Request payload, live result, and durable service codecs. */
|
|
185
|
+
export declare function fleetRequestCommand(action: FleetRequest["action"]): RequestCommand<FleetRequest, unknown, FleetService, FleetService, FleetExecutionContext>;
|
|
186
|
+
export declare function fleetRequestCommands(): Readonly<Record<"akuma.wait" | "akuma.tell" | "akuma.kill", ErasedRequestCommand>>;
|
|
129
187
|
export declare function statusAkuma(input: AkumaAddressInput): Promise<AkumaObservation>;
|
|
130
|
-
export declare function waitAkuma(input: AkumaWaitInput): Promise<AkumaWaitResult>;
|
|
131
|
-
export declare function killAkuma(input: AkumaSetAddressInput): Promise<AkumaKillResult>;
|
|
132
|
-
export declare function tellAkuma(input: AkumaTellInput): Promise<AkumaTellResult>;
|
|
188
|
+
export declare function waitAkuma(input: AkumaWaitInput, execution?: ExecutionContext): Promise<AkumaWaitResult>;
|
|
189
|
+
export declare function killAkuma(input: AkumaSetAddressInput, execution?: ExecutionContext): Promise<AkumaKillResult>;
|
|
190
|
+
export declare function tellAkuma(input: AkumaTellInput, execution?: ExecutionContext): Promise<AkumaTellResult>;
|
|
133
191
|
export declare function interruptAkuma(input: AkumaInterruptInput): Promise<AkumaInterruptResult>;
|
|
134
192
|
export declare function historyAkuma(input: AkumaHistoryInput): Promise<AkumaHistoryResult>;
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable max-lines -- Fleet owns one coherent public operation surface. */
|
|
2
|
+
import { Akuma, AkumaNotBornError, akumaIdSchema, defaultWaitComplete, } from "../akuma/index.js";
|
|
2
3
|
import { readBudgetedStatus, tellAkumaWithId } from "../akuma/akuma.js";
|
|
3
|
-
import {
|
|
4
|
+
import { executionChannel, localExecutionContext, requestBodyCommand, } from "../akuma/requests.js";
|
|
5
|
+
import { eraseRequestCommand } from "../akuma/request-wire.js";
|
|
4
6
|
import { readDispatch } from "../dispatch/index.js";
|
|
5
7
|
import { observeTaskBoard } from "../task/operations.js";
|
|
6
8
|
import { addressAkuma, addressAkumaSet } from "./address.js";
|
|
7
9
|
import { requireInput } from "./input.js";
|
|
10
|
+
import { isKillResult, isTellResult, isWaitResult, fleetResultSchemas, parseAkumaObservation, parseCreatedTaskObservation, } from "./fleet-result.js";
|
|
8
11
|
import { scopeForRepo } from "./repo.js";
|
|
9
12
|
import { parsePublicHistoryId } from "../akuma/identity.js";
|
|
13
|
+
import { z } from "zod";
|
|
10
14
|
function source(path) {
|
|
11
15
|
return Akuma.of(path);
|
|
12
16
|
}
|
|
@@ -37,14 +41,17 @@ async function createdTasksFor(path, statuses) {
|
|
|
37
41
|
const failed = { kind: "failed", diagnostic: createdTaskDiagnostic(error) };
|
|
38
42
|
return statuses.map(() => failed);
|
|
39
43
|
}
|
|
40
|
-
return statuses.map((status) => ({ kind: "present", rows: board.selectCreatedBy(status.id) }));
|
|
44
|
+
return statuses.map((status) => parseCreatedTaskObservation({ kind: "present", rows: board.selectCreatedBy(status.id) }));
|
|
41
45
|
}
|
|
42
46
|
async function observeAkuma(status, path, repo) {
|
|
43
47
|
return (await observeAkumaSet([status], path, repo))[0];
|
|
44
48
|
}
|
|
45
|
-
async function observeAkumaStage(path, id, repo) {
|
|
49
|
+
async function observeAkumaStage(path, id, repo, admittedTellId) {
|
|
46
50
|
try {
|
|
47
|
-
const observed = await readBudgetedStatus(path, id, {
|
|
51
|
+
const observed = await readBudgetedStatus(path, id, {
|
|
52
|
+
aperture: "receipt",
|
|
53
|
+
...(admittedTellId === undefined ? {} : { admittedTellId }),
|
|
54
|
+
});
|
|
48
55
|
return { kind: "observed", ...(await observeAkuma(observed.status, path, repo)) };
|
|
49
56
|
}
|
|
50
57
|
catch (error) {
|
|
@@ -55,7 +62,7 @@ async function observeAkumaStage(path, id, repo) {
|
|
|
55
62
|
}
|
|
56
63
|
async function observeAkumaSet(statuses, path, repo) {
|
|
57
64
|
const created = await createdTasksFor(path, statuses);
|
|
58
|
-
return await Promise.all(statuses.map(async (status, index) => ({
|
|
65
|
+
return await Promise.all(statuses.map(async (status, index) => parseAkumaObservation({
|
|
59
66
|
status,
|
|
60
67
|
contract: await dispatchAssociation(repo, status.id),
|
|
61
68
|
createdTasks: created[index],
|
|
@@ -124,11 +131,11 @@ export async function executeWaitAkuma(input) {
|
|
|
124
131
|
const completed = round.statuses.length > 0 &&
|
|
125
132
|
(input.completion === "any" ? settled.some(Boolean) : round.unobserved.length === 0 && settled.every(Boolean));
|
|
126
133
|
if (completed || (deadline !== undefined && performance.now() >= deadline)) {
|
|
127
|
-
return {
|
|
134
|
+
return fleetResultSchemas.wait.parse({
|
|
128
135
|
completion: input.completion,
|
|
129
136
|
observations: await observeAkumaSet(round.statuses, input.path, input.repo),
|
|
130
137
|
unobserved: round.unobserved,
|
|
131
|
-
};
|
|
138
|
+
});
|
|
132
139
|
}
|
|
133
140
|
await delay(deadline === undefined ? POLL_MS : Math.min(POLL_MS, Math.max(0, deadline - performance.now())), input.signal);
|
|
134
141
|
}
|
|
@@ -146,31 +153,177 @@ export async function executeTellAkuma(input) {
|
|
|
146
153
|
...(input.recordedAt === undefined ? {} : { recordedAt: input.recordedAt }),
|
|
147
154
|
});
|
|
148
155
|
input.signal?.throwIfAborted();
|
|
149
|
-
return {
|
|
156
|
+
return fleetResultSchemas.tell.parse({
|
|
150
157
|
akuma: input.id,
|
|
151
158
|
tell,
|
|
152
|
-
|
|
153
|
-
};
|
|
159
|
+
});
|
|
154
160
|
}
|
|
155
161
|
export async function executeKillAkuma(input) {
|
|
156
162
|
input.signal?.throwIfAborted();
|
|
157
163
|
const handles = input.ids.map((id) => source(input.path).of({ id }));
|
|
158
164
|
const evidence = await Promise.all(handles.map(async (handle) => await handle.kill()));
|
|
159
165
|
input.signal?.throwIfAborted();
|
|
166
|
+
return fleetResultSchemas.kill.parse({
|
|
167
|
+
results: input.ids.map((id, index) => ({ id, evidence: evidence[index] })),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function forwardedFleetCommandResult(response, action) {
|
|
171
|
+
if (response.kind === "returned") {
|
|
172
|
+
if (action === "akuma.wait" && isWaitResult(response.result))
|
|
173
|
+
return response.result;
|
|
174
|
+
if (action === "akuma.tell" && isTellResult(response.result))
|
|
175
|
+
return response.result;
|
|
176
|
+
if (action === "akuma.kill" && isKillResult(response.result))
|
|
177
|
+
return response.result;
|
|
178
|
+
throw new Error(`transport integrity: request Fleet ${action} returned an invalid live result`);
|
|
179
|
+
}
|
|
180
|
+
throw new Error("Akuma body request terminal Fleet reference cannot reproduce an expired live result");
|
|
181
|
+
}
|
|
182
|
+
const nonblankTextSchema = z.string().refine((value) => value.trim() !== "");
|
|
183
|
+
const fleetTargetsSchema = z
|
|
184
|
+
.array(akumaIdSchema)
|
|
185
|
+
.min(1)
|
|
186
|
+
.superRefine((ids, context) => {
|
|
187
|
+
if (ids.some((id, index) => index > 0 && ids[index - 1] >= id))
|
|
188
|
+
context.addIssue({ code: "custom", message: "expected a strictly ordered target set" });
|
|
189
|
+
});
|
|
190
|
+
const waitRequestSchema = z
|
|
191
|
+
.object({
|
|
192
|
+
targets: fleetTargetsSchema,
|
|
193
|
+
completion: z.enum(["any", "all"]),
|
|
194
|
+
timeoutMs: z.number().int().nonnegative().optional(),
|
|
195
|
+
})
|
|
196
|
+
.strict()
|
|
197
|
+
.transform(({ timeoutMs, ...request }) => ({
|
|
198
|
+
action: "akuma.wait",
|
|
199
|
+
...request,
|
|
200
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
201
|
+
}));
|
|
202
|
+
const tellRequestSchema = z
|
|
203
|
+
.object({ target: akumaIdSchema, body: z.string() })
|
|
204
|
+
.strict()
|
|
205
|
+
.transform((request) => ({ action: "akuma.tell", ...request }));
|
|
206
|
+
const killRequestSchema = z
|
|
207
|
+
.object({ targets: fleetTargetsSchema })
|
|
208
|
+
.strict()
|
|
209
|
+
.transform((request) => ({ action: "akuma.kill", ...request }));
|
|
210
|
+
const waitServiceSchema = z.object({ action: z.literal("akuma.wait") }).strict();
|
|
211
|
+
const tellServiceSchema = z
|
|
212
|
+
.object({ action: z.literal("akuma.tell"), target: akumaIdSchema, tellId: nonblankTextSchema })
|
|
213
|
+
.strict();
|
|
214
|
+
const killServiceSchema = z
|
|
215
|
+
.object({
|
|
216
|
+
action: z.literal("akuma.kill"),
|
|
217
|
+
results: z.array(z.object({ id: akumaIdSchema, evidence: fleetResultSchemas.killEvidence }).strict()),
|
|
218
|
+
})
|
|
219
|
+
.strict();
|
|
220
|
+
function decodeFleetExecutionContext(value) {
|
|
221
|
+
const context = fleetPayload(value);
|
|
222
|
+
if (context === null ||
|
|
223
|
+
typeof context.id !== "string" ||
|
|
224
|
+
context.id.trim() === "" ||
|
|
225
|
+
typeof context.admittedAt !== "string" ||
|
|
226
|
+
!isAbortSignal(context.signal) ||
|
|
227
|
+
!isFleetRequestPort(context.upstream))
|
|
228
|
+
throw new Error("invalid Fleet execution context");
|
|
229
|
+
return {
|
|
230
|
+
id: context.id,
|
|
231
|
+
admittedAt: context.admittedAt,
|
|
232
|
+
signal: context.signal,
|
|
233
|
+
upstream: context.upstream,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function isAbortSignal(value) {
|
|
237
|
+
return (value !== null &&
|
|
238
|
+
typeof value === "object" &&
|
|
239
|
+
typeof value.throwIfAborted === "function");
|
|
240
|
+
}
|
|
241
|
+
function isFleetRequestPort(value) {
|
|
242
|
+
const port = fleetPayload(value);
|
|
243
|
+
return (port !== null &&
|
|
244
|
+
typeof port.wait === "function" &&
|
|
245
|
+
typeof port.tell === "function" &&
|
|
246
|
+
typeof port.kill === "function");
|
|
247
|
+
}
|
|
248
|
+
function fleetPayload(value) {
|
|
249
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
250
|
+
? value
|
|
251
|
+
: null;
|
|
252
|
+
}
|
|
253
|
+
function decodeFleetRequest(action, value) {
|
|
254
|
+
const schema = action === "akuma.wait" ? waitRequestSchema : action === "akuma.tell" ? tellRequestSchema : killRequestSchema;
|
|
255
|
+
const parsed = schema.safeParse(value);
|
|
256
|
+
return parsed.success ? parsed.data : null;
|
|
257
|
+
}
|
|
258
|
+
function decodeFleetService(action, value) {
|
|
259
|
+
const schema = action === "akuma.wait" ? waitServiceSchema : action === "akuma.tell" ? tellServiceSchema : killServiceSchema;
|
|
260
|
+
const parsed = schema.safeParse(value);
|
|
261
|
+
if (!parsed.success)
|
|
262
|
+
throw new Error("malformed stored Fleet service evidence");
|
|
263
|
+
return parsed.data;
|
|
264
|
+
}
|
|
265
|
+
/** Fleet owns its Body Request payload, live result, and durable service codecs. */
|
|
266
|
+
export function fleetRequestCommand(action) {
|
|
160
267
|
return {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
268
|
+
action,
|
|
269
|
+
encodeRequest: (request) => {
|
|
270
|
+
const { action: _action, ...payload } = request;
|
|
271
|
+
return payload;
|
|
272
|
+
},
|
|
273
|
+
decodeRequest: (payload) => decodeFleetRequest(action, payload),
|
|
274
|
+
encodeResult: (result) => result,
|
|
275
|
+
decodeResult: (result) => {
|
|
276
|
+
const schema = action === "akuma.wait"
|
|
277
|
+
? fleetResultSchemas.wait
|
|
278
|
+
: action === "akuma.tell"
|
|
279
|
+
? fleetResultSchemas.tell
|
|
280
|
+
: fleetResultSchemas.kill;
|
|
281
|
+
const parsed = schema.safeParse(result);
|
|
282
|
+
if (!parsed.success)
|
|
283
|
+
throw new Error(`Akuma body request returned an invalid live result for ${action}`);
|
|
284
|
+
return parsed.data;
|
|
285
|
+
},
|
|
286
|
+
encodeService: (service) => decodeFleetService(action, service),
|
|
287
|
+
decodeService: (service) => decodeFleetService(action, service),
|
|
288
|
+
projectService: (service) => decodeFleetService(action, service),
|
|
289
|
+
decodeReference: (reference) => decodeFleetService(action, reference),
|
|
290
|
+
isPermitted: (allowed) => action === "akuma.wait" || allowed.includes(action),
|
|
291
|
+
decodeExecutionContext: decodeFleetExecutionContext,
|
|
292
|
+
execute: async (request, context) => {
|
|
293
|
+
if (request.action === "akuma.wait") {
|
|
294
|
+
return {
|
|
295
|
+
result: await context.upstream.wait({ ...request, signal: context.signal }),
|
|
296
|
+
service: { action: request.action },
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
if (request.action === "akuma.tell") {
|
|
300
|
+
return {
|
|
301
|
+
result: await context.upstream.tell({
|
|
302
|
+
target: request.target,
|
|
303
|
+
body: request.body,
|
|
304
|
+
tellId: context.id,
|
|
305
|
+
recordedAt: context.admittedAt,
|
|
306
|
+
signal: context.signal,
|
|
307
|
+
}),
|
|
308
|
+
service: { action: request.action, target: request.target, tellId: context.id },
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
const result = await context.upstream.kill({ targets: request.targets, signal: context.signal });
|
|
312
|
+
if ("result" in result)
|
|
313
|
+
return { result: result.result, service: { action: request.action, results: result.service } };
|
|
314
|
+
return {
|
|
315
|
+
result,
|
|
316
|
+
service: { action: request.action, results: result.results.map(({ id, evidence }) => ({ id, evidence })) },
|
|
317
|
+
};
|
|
318
|
+
},
|
|
166
319
|
};
|
|
167
320
|
}
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
321
|
+
export function fleetRequestCommands() {
|
|
322
|
+
return {
|
|
323
|
+
"akuma.wait": eraseRequestCommand(fleetRequestCommand("akuma.wait")),
|
|
324
|
+
"akuma.tell": eraseRequestCommand(fleetRequestCommand("akuma.tell")),
|
|
325
|
+
"akuma.kill": eraseRequestCommand(fleetRequestCommand("akuma.kill")),
|
|
326
|
+
};
|
|
174
327
|
}
|
|
175
328
|
function needsDispatchAttach(association) {
|
|
176
329
|
return association.kind === "none";
|
|
@@ -180,34 +333,13 @@ async function attachObservationContract(repo, observation) {
|
|
|
180
333
|
return observation;
|
|
181
334
|
return { ...observation, contract: await dispatchAssociation(repo, observation.status.id) };
|
|
182
335
|
}
|
|
183
|
-
async function attachObservationStage(repo, observation) {
|
|
184
|
-
if (repo === undefined || observation.kind !== "observed")
|
|
185
|
-
return observation;
|
|
186
|
-
return { ...observation, ...(await attachObservationContract(repo, observation)) };
|
|
187
|
-
}
|
|
188
336
|
async function attachWaitContracts(repo, result) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
async function attachTellContract(repo, result) {
|
|
197
|
-
return repo === undefined
|
|
198
|
-
? result
|
|
199
|
-
: { ...result, observation: await attachObservationStage(repo, result.observation) };
|
|
200
|
-
}
|
|
201
|
-
async function attachKillContracts(repo, result) {
|
|
202
|
-
return repo === undefined
|
|
203
|
-
? result
|
|
204
|
-
: {
|
|
205
|
-
...result,
|
|
206
|
-
results: await Promise.all(result.results.map(async (entry) => ({
|
|
207
|
-
...entry,
|
|
208
|
-
observation: await attachObservationStage(repo, entry.observation),
|
|
209
|
-
}))),
|
|
210
|
-
};
|
|
337
|
+
if (repo === undefined)
|
|
338
|
+
return result;
|
|
339
|
+
return fleetResultSchemas.wait.parse({
|
|
340
|
+
...result,
|
|
341
|
+
observations: await Promise.all(result.observations.map((observation) => attachObservationContract(repo, observation))),
|
|
342
|
+
});
|
|
211
343
|
}
|
|
212
344
|
function directAddress(values) {
|
|
213
345
|
return {
|
|
@@ -227,7 +359,7 @@ export async function statusAkuma(input) {
|
|
|
227
359
|
const addressed = await addressAkuma(input);
|
|
228
360
|
return await observeAkuma(await source(addressed.path).of({ id: addressed.id }).status(), addressed.path, input.repo);
|
|
229
361
|
}
|
|
230
|
-
export async function waitAkuma(input) {
|
|
362
|
+
export async function waitAkuma(input, execution = localExecutionContext()) {
|
|
231
363
|
const values = requireInput(input, "Keiyaku.wait input");
|
|
232
364
|
for (const key of Object.keys(values)) {
|
|
233
365
|
if (!["path", "akuma", "repo", "completion", "timeoutMs"].includes(key)) {
|
|
@@ -244,15 +376,19 @@ export async function waitAkuma(input) {
|
|
|
244
376
|
}
|
|
245
377
|
const selected = completion ?? "all";
|
|
246
378
|
const timeoutMs = timeout(values.timeoutMs);
|
|
247
|
-
const
|
|
248
|
-
if (
|
|
249
|
-
const
|
|
250
|
-
directory:
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
379
|
+
const channel = executionChannel(execution);
|
|
380
|
+
if (channel.kind === "body-request") {
|
|
381
|
+
const response = await requestBodyCommand({
|
|
382
|
+
directory: channel.directory,
|
|
383
|
+
command: fleetRequestCommand("akuma.wait"),
|
|
384
|
+
value: {
|
|
385
|
+
action: "akuma.wait",
|
|
386
|
+
targets: addressed.ids,
|
|
387
|
+
completion: selected,
|
|
388
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
389
|
+
},
|
|
254
390
|
});
|
|
255
|
-
return await attachWaitContracts(values.repo,
|
|
391
|
+
return await attachWaitContracts(values.repo, forwardedFleetCommandResult(response, "akuma.wait"));
|
|
256
392
|
}
|
|
257
393
|
return await executeWaitAkuma({
|
|
258
394
|
path: addressed.path,
|
|
@@ -262,12 +398,16 @@ export async function waitAkuma(input) {
|
|
|
262
398
|
...(values.repo === undefined ? {} : { repo: values.repo }),
|
|
263
399
|
});
|
|
264
400
|
}
|
|
265
|
-
export async function killAkuma(input) {
|
|
401
|
+
export async function killAkuma(input, execution = localExecutionContext()) {
|
|
266
402
|
const addressed = await addressAkumaSet(input);
|
|
267
|
-
const
|
|
268
|
-
if (
|
|
269
|
-
const
|
|
270
|
-
|
|
403
|
+
const channel = executionChannel(execution);
|
|
404
|
+
if (channel.kind === "body-request") {
|
|
405
|
+
const response = await requestBodyCommand({
|
|
406
|
+
directory: channel.directory,
|
|
407
|
+
command: fleetRequestCommand("akuma.kill"),
|
|
408
|
+
value: { action: "akuma.kill", targets: addressed.ids },
|
|
409
|
+
});
|
|
410
|
+
return forwardedFleetCommandResult(response, "akuma.kill");
|
|
271
411
|
}
|
|
272
412
|
return await executeKillAkuma({
|
|
273
413
|
path: addressed.path,
|
|
@@ -275,7 +415,7 @@ export async function killAkuma(input) {
|
|
|
275
415
|
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
276
416
|
});
|
|
277
417
|
}
|
|
278
|
-
export async function tellAkuma(input) {
|
|
418
|
+
export async function tellAkuma(input, execution = localExecutionContext()) {
|
|
279
419
|
const values = requireInput(input, "Keiyaku.tell input");
|
|
280
420
|
for (const key of Object.keys(values)) {
|
|
281
421
|
if (!["path", "akuma", "body", "repo"].includes(key)) {
|
|
@@ -285,14 +425,14 @@ export async function tellAkuma(input) {
|
|
|
285
425
|
if (typeof values.body !== "string")
|
|
286
426
|
throw new TypeError("body must be a string");
|
|
287
427
|
const addressed = await addressAkuma(directAddress(values));
|
|
288
|
-
const
|
|
289
|
-
if (
|
|
290
|
-
const
|
|
291
|
-
directory:
|
|
292
|
-
|
|
293
|
-
body: values.body,
|
|
428
|
+
const channel = executionChannel(execution);
|
|
429
|
+
if (channel.kind === "body-request") {
|
|
430
|
+
const response = await requestBodyCommand({
|
|
431
|
+
directory: channel.directory,
|
|
432
|
+
command: fleetRequestCommand("akuma.tell"),
|
|
433
|
+
value: { action: "akuma.tell", target: addressed.id, body: values.body },
|
|
294
434
|
});
|
|
295
|
-
return
|
|
435
|
+
return forwardedFleetCommandResult(response, "akuma.tell");
|
|
296
436
|
}
|
|
297
437
|
return await executeTellAkuma({
|
|
298
438
|
path: addressed.path,
|
|
@@ -7,6 +7,8 @@ export declare function actorOption(actor: unknown): Readonly<{
|
|
|
7
7
|
}>;
|
|
8
8
|
export declare function requireMarkdown(value: unknown, label?: string): string;
|
|
9
9
|
export declare function requireInput(value: unknown, label: string): Record<string, unknown>;
|
|
10
|
+
/** Shared public-input failure path for operation owners. */
|
|
11
|
+
export declare function invalidInput(message: string): never;
|
|
10
12
|
export declare function taskOption(value: unknown): TaskId | undefined;
|
|
11
13
|
export declare function optionalNonblank(value: unknown, label: string): string | undefined;
|
|
12
14
|
export declare function optionalBoolean(value: unknown, label: string): boolean | undefined;
|