@astrosheep/keiyaku 4.5.0 → 4.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +4 -2
  2. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/package.json +9 -3
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +16 -5
  5. package/build/integrations/pi/keiyaku.ts +159 -0
  6. package/build/src/akuma/abort.js +9 -9
  7. package/build/src/akuma/akuma-handle.d.ts +4 -2
  8. package/build/src/akuma/akuma-handle.js +14 -2
  9. package/build/src/akuma/akuma-product.d.ts +8 -2
  10. package/build/src/akuma/akuma-product.js +9 -4
  11. package/build/src/akuma/body.d.ts +4 -0
  12. package/build/src/akuma/body.js +21 -14
  13. package/build/src/akuma/heart/index.js +7 -3
  14. package/build/src/akuma/heart/rows.d.ts +1 -1
  15. package/build/src/akuma/heart/rows.js +3 -3
  16. package/build/src/akuma/heart/storage.d.ts +1 -0
  17. package/build/src/akuma/heart/storage.js +28 -6
  18. package/build/src/akuma/identity.d.ts +1 -0
  19. package/build/src/akuma/identity.js +7 -0
  20. package/build/src/akuma/index.d.ts +1 -1
  21. package/build/src/akuma/projection.d.ts +18 -2
  22. package/build/src/akuma/projection.js +11 -1
  23. package/build/src/akuma/providers/claude/index.js +68 -37
  24. package/build/src/akuma/publication.js +3 -0
  25. package/build/src/akuma/request-lifecycle.d.ts +45 -0
  26. package/build/src/akuma/request-lifecycle.js +171 -0
  27. package/build/src/akuma/request-serve.d.ts +9 -32
  28. package/build/src/akuma/request-serve.js +47 -173
  29. package/build/src/akuma/request-wire.js +1 -1
  30. package/build/src/akuma/requests.js +3 -2
  31. package/build/src/cli/commands/akuma-invoke.d.ts +9 -0
  32. package/build/src/cli/commands/akuma-invoke.js +9 -6
  33. package/build/src/cli/commands/akuma.d.ts +1 -0
  34. package/build/src/cli/commands/akuma.js +16 -6
  35. package/build/src/cli/commands/contract.d.ts +3 -2
  36. package/build/src/cli/commands/contract.js +5 -2
  37. package/build/src/cli/commands/status-set.d.ts +4 -0
  38. package/build/src/cli/commands/status-set.js +61 -0
  39. package/build/src/cli/invoke.js +5 -0
  40. package/build/src/cli/parse.js +1 -1
  41. package/build/src/cli/render/akuma-activity.js +11 -0
  42. package/build/src/cli/render/akuma.js +7 -0
  43. package/build/src/cli/render/status-set.d.ts +5 -0
  44. package/build/src/cli/render/status-set.js +14 -0
  45. package/build/src/cli/render/text.js +3 -0
  46. package/build/src/cli/result.d.ts +15 -1
  47. package/build/src/cli/runtime.js +2 -0
  48. package/build/src/cli/square-edge.d.ts +2 -1
  49. package/build/src/cli/square-edge.js +60 -33
  50. package/build/src/contract-worktree.js +18 -5
  51. package/build/src/library/akuma-creation.d.ts +1 -1
  52. package/build/src/library/akuma-creation.js +6 -2
  53. package/build/src/library/fleet.d.ts +12 -1
  54. package/build/src/library/fleet.js +21 -5
  55. package/build/src/library/repo.js +3 -1
  56. package/build/src/runtime/proc/windows-launch.exe +0 -0
  57. package/build/src/world.d.ts +2 -0
  58. package/build/src/world.js +4 -0
  59. package/package.json +8 -3
@@ -4,6 +4,13 @@ import { dirname, join } from "node:path";
4
4
  import { identityCoordinate, identitySegments } from "../identity/coordinates.js";
5
5
  import { normalizeIdentityStem } from "../identity/normalize.js";
6
6
  const HEX8 = /^[0-9a-f]{8}$/u;
7
+ export function parsePublicHistoryId(value) {
8
+ const match = /^turn\/([1-9][0-9]*)$/u.exec(value);
9
+ if (match === null)
10
+ return null;
11
+ const sequence = Number(match[1]);
12
+ return Number.isSafeInteger(sequence) ? sequence : null;
13
+ }
7
14
  export function archetypeName(value) {
8
15
  if (value.length === 0 || normalizeIdentityStem({ source: value }) !== value) {
9
16
  throw new TypeError("Akuma name must be one normalized human identity segment");
@@ -9,7 +9,7 @@ export declare function probeBornAkuma(worldPath: WorldRoot, id: AkuId): Promise
9
9
  export { AkumaArchetypeError, listArchetypeDefinitions, listArchetypes } from "./archetype.js";
10
10
  export type { ArchetypeCatalogRow } from "./archetype.js";
11
11
  export { AkumaBodyRequestError } from "./requests.js";
12
- export type { AkumaList, AkumaListInput, AkumaListRow, AkumaStatus, ActivityHistory, ActivityRow, ActivitySnapshot, ActivitySnapshotEntry, ForkReceipt, InterruptReceipt, TellResult, TellWake, UnbornAkumaListRow, } from "./akuma.js";
12
+ export type { AkumaList, AkumaListInput, AkumaListRow, AkumaStatus, ActivityHistory, ExactHistory, ActivityRow, ActivitySnapshot, ActivitySnapshotEntry, ForkReceipt, InterruptReceipt, TellResult, TellWake, UnbornAkumaListRow, } from "./akuma.js";
13
13
  export type { ActiveToolRow, ClosedTurn, ClosedTurnRow, CompletedToolRow, HistoryCursor, HistoryPage, IdleSnapshotRow, OpenSnapshotRow, OpenTurn, OpenTurnRow, OutcomeRow, ReportedFileChange, RetainedWindow, Snapshot, SnapshotRow, TellRow, TurnLedger, TurnOutcome, TurnStartRow, UnsettledToolRow, } from "./akuma.js";
14
14
  export type { AgentEvent, ToolCall, ToolEvent, ToolResult } from "./provider.js";
15
15
  export type { AkuId } from "./identity.js";
@@ -1,6 +1,14 @@
1
1
  import { type ToolCall, type ToolResult } from "./provider.js";
2
- import type { TellDelivery, TellFact, TimelineFact, TurnEndFact } from "./heart/index.js";
3
- export type TurnOutcome = TurnEndFact["outcome"];
2
+ import type { TellDelivery, TellFact, TimelineFact } from "./heart/index.js";
3
+ export type TurnOutcome = Readonly<{
4
+ kind: "answered";
5
+ historyId: string;
6
+ answer: string;
7
+ }> | Readonly<{
8
+ kind: "failed";
9
+ historyId: string;
10
+ diagnostic: string;
11
+ }>;
4
12
  export type TurnStartRow = Readonly<{
5
13
  kind: "turn";
6
14
  sequence: number;
@@ -153,7 +161,15 @@ export type ActivityHistory = Readonly<{
153
161
  lowestRetained: number | null;
154
162
  highest: number | null;
155
163
  }>;
164
+ export type ExactHistory = Readonly<{
165
+ kind: "exact";
166
+ outcome: OutcomeRow;
167
+ }> | Readonly<{
168
+ kind: "unknown-history";
169
+ id: string;
170
+ }>;
156
171
  export type HistoryPage = ActivityHistory;
172
+ export declare function selectExactHistory(rows: readonly ActivityRow[], id: string): ExactHistory;
157
173
  export type HistoryCursor = Readonly<{
158
174
  before?: number;
159
175
  since?: number;
@@ -1,4 +1,14 @@
1
1
  import { decodeAgentEvent } from "./provider.js";
2
+ function publicOutcome(turnSequence, outcome) {
3
+ const historyId = `turn/${turnSequence}`;
4
+ return outcome.kind === "answered"
5
+ ? { kind: "answered", historyId, answer: outcome.answer }
6
+ : { kind: "failed", historyId, diagnostic: outcome.diagnostic };
7
+ }
8
+ export function selectExactHistory(rows, id) {
9
+ const outcome = rows.find((row) => row.kind === "outcome" && row.outcome.historyId === id);
10
+ return outcome === undefined ? { kind: "unknown-history", id } : { kind: "exact", outcome };
11
+ }
2
12
  function duration(startedAt, completedAt) {
3
13
  const start = Date.parse(startedAt);
4
14
  const end = Date.parse(completedAt);
@@ -171,7 +181,7 @@ export function projectTurns(facts, retained = {
171
181
  sequence: fact.sequence,
172
182
  turnSequence: fact.turnSequence,
173
183
  at: fact.completedAt,
174
- outcome: fact.outcome,
184
+ outcome: publicOutcome(fact.turnSequence, fact.outcome),
175
185
  };
176
186
  const turn = state.turnsBySequence.get(fact.turnSequence);
177
187
  if (turn === undefined)
@@ -118,53 +118,64 @@ function finishClaudeInput(input, terminal) {
118
118
  else
119
119
  input.close();
120
120
  }
121
+ function consumeClaudeMessage(context, state, message) {
122
+ const { input, events, observation, progress, admit, rejectAdmission, settle, controls } = context;
123
+ if (state.terminal !== null)
124
+ return;
125
+ if (!state.admitted && "session_id" in message && typeof message.session_id === "string" && admit()) {
126
+ state.admitted = true;
127
+ events.emit({ type: "session", coordinate: { sessionId: message.session_id } });
128
+ }
129
+ emitClaudeMessage(message, events, observation);
130
+ if (message.type === "assistant" &&
131
+ message.parent_tool_use_id === null &&
132
+ typeof message.uuid === "string" &&
133
+ message.uuid.length > 0)
134
+ state.historyId = message.uuid;
135
+ if (message.type !== "result")
136
+ return;
137
+ if (message.subtype === "success") {
138
+ state.terminal = successfulResult(message, state.historyId);
139
+ progress.checkpoint += 1;
140
+ controls.flushReceipts();
141
+ queueMicrotask(controls.closeWhenIdle);
142
+ }
143
+ else {
144
+ state.terminal = { kind: "failed", diagnostic: message.errors.join("; ") || message.subtype };
145
+ input.close();
146
+ }
147
+ progress.ended = true;
148
+ if (!state.admitted)
149
+ rejectAdmission(new Error(state.terminal.kind === "failed" ? state.terminal.diagnostic : "Claude query ended before session admission"));
150
+ finishClaudeInput(input, state.terminal);
151
+ events.end();
152
+ settle(state.terminal);
153
+ controls.settleReceipts();
154
+ }
121
155
  async function consumeClaudeQuery(context) {
122
- const { query, input, events, observation, progress, admit, rejectAdmission, settle, controls } = context;
123
- let admitted = false;
124
- let terminal = null;
125
- let historyId;
156
+ const { query, input, events, progress, rejectAdmission, settle, controls } = context;
157
+ const state = { admitted: false, terminal: null };
126
158
  try {
127
- for await (const message of query) {
128
- if (!admitted && "session_id" in message && typeof message.session_id === "string") {
129
- admitted = true;
130
- events.emit({ type: "session", coordinate: { sessionId: message.session_id } });
131
- admit();
132
- }
133
- emitClaudeMessage(message, events, observation);
134
- if (message.type === "assistant" &&
135
- message.parent_tool_use_id === null &&
136
- typeof message.uuid === "string" &&
137
- message.uuid.length > 0)
138
- historyId = message.uuid;
139
- if (message.type !== "result")
140
- continue;
141
- if (message.subtype === "success") {
142
- terminal = successfulResult(message, historyId);
143
- progress.checkpoint += 1;
144
- controls.flushReceipts();
145
- queueMicrotask(controls.closeWhenIdle);
146
- }
147
- else {
148
- terminal = { kind: "failed", diagnostic: message.errors.join("; ") || message.subtype };
149
- input.close();
150
- }
151
- }
159
+ for await (const message of query)
160
+ consumeClaudeMessage(context, state, message);
152
161
  progress.ended = true;
153
- const result = terminal ?? { kind: "failed", diagnostic: "Claude query ended without a result" };
154
- if (!admitted)
162
+ const result = state.terminal ?? { kind: "failed", diagnostic: "Claude query ended without a result" };
163
+ if (!state.admitted)
155
164
  rejectAdmission(new Error(result.kind === "failed" ? result.diagnostic : "Claude query ended before session admission"));
156
165
  settle(result);
157
166
  }
158
167
  catch (error) {
159
168
  progress.ended = true;
169
+ if (state.terminal !== null)
170
+ return;
160
171
  input.fail(error);
161
172
  const failure = error instanceof Error ? error : new Error(String(error));
162
- if (!admitted)
173
+ if (!state.admitted)
163
174
  rejectAdmission(failure);
164
175
  settle({ kind: "failed", diagnostic: failure.message });
165
176
  }
166
177
  finally {
167
- finishClaudeInput(input, terminal);
178
+ finishClaudeInput(input, state.terminal);
168
179
  events.end();
169
180
  controls.settleReceipts();
170
181
  }
@@ -206,9 +217,21 @@ function observeClaudeQuery(context) {
206
217
  const observation = { tools: new Map() };
207
218
  let admit;
208
219
  let rejectAdmission;
220
+ let admissionOpen = true;
209
221
  const admission = new Promise((resolve, reject) => {
210
- admit = resolve;
211
- rejectAdmission = reject;
222
+ admit = () => {
223
+ if (!admissionOpen)
224
+ return false;
225
+ admissionOpen = false;
226
+ resolve();
227
+ return true;
228
+ };
229
+ rejectAdmission = (error) => {
230
+ if (!admissionOpen)
231
+ return;
232
+ admissionOpen = false;
233
+ reject(error);
234
+ };
212
235
  });
213
236
  let settle;
214
237
  const completion = new Promise((resolve) => {
@@ -247,6 +270,7 @@ function observeClaudeQuery(context) {
247
270
  });
248
271
  return {
249
272
  admission,
273
+ rejectAdmission,
250
274
  completion,
251
275
  get ended() {
252
276
  return progress.ended;
@@ -282,9 +306,13 @@ async function driveClaude(load, execution, drive) {
282
306
  input.fail(error);
283
307
  query.close();
284
308
  };
285
- const abortSetup = () => shutDown(signal.reason);
309
+ let observed;
310
+ const abortSetup = () => {
311
+ shutDown(signal.reason);
312
+ observed?.rejectAdmission(signal.reason);
313
+ };
286
314
  signal.addEventListener("abort", abortSetup, { once: true });
287
- const observed = observeClaudeQuery({
315
+ observed = observeClaudeQuery({
288
316
  query,
289
317
  input,
290
318
  events,
@@ -296,8 +324,11 @@ async function driveClaude(load, execution, drive) {
296
324
  },
297
325
  },
298
326
  });
327
+ if (signal.aborted)
328
+ abortSetup();
299
329
  try {
300
330
  await Promise.all([launchAcknowledged, observed.admission]);
331
+ signal.throwIfAborted();
301
332
  }
302
333
  finally {
303
334
  signal.removeEventListener("abort", abortSetup);
@@ -93,6 +93,9 @@ async function awaitBirth(paths, owned, signal) {
93
93
  const settled = await settleTimedOutBirth(paths);
94
94
  if (settled !== null)
95
95
  return settled;
96
+ if (owned !== undefined)
97
+ await owned.terminate(true);
98
+ throw new Error("Akuma birth timed out before Soul admission");
96
99
  }
97
100
  if (owned === undefined) {
98
101
  await abortableDelay(Math.min(POLL_MS, Math.max(0, deadline - performance.now())), signal);
@@ -0,0 +1,45 @@
1
+ import { type Soul } from "./heart/index.js";
2
+ import { type AkumaPaths } from "./identity.js";
3
+ import { type StructuralRequestClaim } from "./request-wire.js";
4
+ import type { OwnedProcess } from "../runtime/proc/run.js";
5
+ export type RequestChildLaunch = Readonly<{
6
+ paths: AkumaPaths;
7
+ seed: Omit<Soul, "createdAt">;
8
+ initialBody: string;
9
+ }>;
10
+ export type PumpInput = Readonly<{
11
+ paths: AkumaPaths;
12
+ parent: Soul;
13
+ bodySequence: number;
14
+ now(): string;
15
+ spawn(launch: RequestChildLaunch): Promise<OwnedProcess | void>;
16
+ upstream?: unknown;
17
+ signal: AbortSignal;
18
+ }>;
19
+ type ServeClaim = (input: PumpInput & Readonly<{
20
+ directory: string;
21
+ transportId: string;
22
+ claim: StructuralRequestClaim;
23
+ signal: AbortSignal;
24
+ admissionOpen(): boolean;
25
+ }>) => Promise<void>;
26
+ export declare class BodyRequestPump {
27
+ private readonly input;
28
+ private readonly serveClaim;
29
+ readonly directory: string;
30
+ readonly failure: Promise<never>;
31
+ private readonly closeSignal;
32
+ private readonly executionSignal;
33
+ private readonly handled;
34
+ private readonly running;
35
+ private readonly cancelBody;
36
+ private admissionClosed;
37
+ protected constructor(input: PumpInput, serveClaim: ServeClaim);
38
+ static openWithService(input: PumpInput, serveClaim: ServeClaim): Promise<BodyRequestPump>;
39
+ private run;
40
+ close(): Promise<void>;
41
+ stopAdmission(): void;
42
+ }
43
+ export declare function clearBodyRequestTransport(paths: AkumaPaths): Promise<void>;
44
+ export declare function settleBodyRequests(paths: AkumaPaths, parent: Soul, now: () => string, signal?: AbortSignal): Promise<"settled" | "pending">;
45
+ export {};
@@ -0,0 +1,171 @@
1
+ import { access, mkdir, readFile, readdir, rm } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { abortableDelay } from "./abort.js";
4
+ import { HeldAkumaLeash, readNonterminalRequests, readSoul, serveRequest, voidRequest, } from "./heart/index.js";
5
+ import { pathsForAkuId } from "./identity.js";
6
+ import { BIRTH_TIMEOUT_MS } from "./publication.js";
7
+ import { atomicJson, decodeClaim, receiptPath } from "./request-wire.js";
8
+ const POLL_MS = 100;
9
+ export class BodyRequestPump {
10
+ input;
11
+ serveClaim;
12
+ directory;
13
+ failure;
14
+ closeSignal = new AbortController();
15
+ executionSignal = new AbortController();
16
+ handled = new Set();
17
+ running;
18
+ cancelBody;
19
+ admissionClosed = false;
20
+ constructor(input, serveClaim) {
21
+ this.input = input;
22
+ this.serveClaim = serveClaim;
23
+ this.directory = join(input.paths.directory, "requests", String(input.bodySequence));
24
+ this.cancelBody = () => {
25
+ this.stopAdmission();
26
+ if (!this.executionSignal.signal.aborted)
27
+ this.executionSignal.abort(input.signal.reason);
28
+ };
29
+ input.signal.addEventListener("abort", this.cancelBody, { once: true });
30
+ if (input.signal.aborted)
31
+ this.cancelBody();
32
+ this.running = this.run();
33
+ this.failure = this.running.then(() => new Promise(() => { }), (error) => Promise.reject(error));
34
+ }
35
+ static async openWithService(input, serveClaim) {
36
+ await mkdir(join(input.paths.directory, "requests", String(input.bodySequence)), { recursive: true });
37
+ return new BodyRequestPump(input, serveClaim);
38
+ }
39
+ async run() {
40
+ while (!this.closeSignal.signal.aborted) {
41
+ for (const name of await requestFiles(this.directory)) {
42
+ if (this.closeSignal.signal.aborted)
43
+ return;
44
+ const transportId = name.slice(0, -".request.json".length);
45
+ if (this.handled.has(transportId))
46
+ continue;
47
+ const path = join(this.directory, name);
48
+ const claim = decodeClaim(await readFile(path, "utf8"), transportId);
49
+ if (claim === null) {
50
+ await rm(path, { force: true });
51
+ this.handled.add(transportId);
52
+ continue;
53
+ }
54
+ if (!this.admissionClosed) {
55
+ try {
56
+ await this.serveClaim({
57
+ directory: this.directory,
58
+ transportId,
59
+ claim,
60
+ ...this.input,
61
+ signal: this.executionSignal.signal,
62
+ admissionOpen: () => !this.admissionClosed,
63
+ });
64
+ }
65
+ catch (error) {
66
+ await projectTransportFailure(this.directory, transportId, claim, error);
67
+ }
68
+ }
69
+ this.handled.add(transportId);
70
+ }
71
+ try {
72
+ await abortableDelay(POLL_MS, this.closeSignal.signal);
73
+ }
74
+ catch (error) {
75
+ if (this.closeSignal.signal.aborted)
76
+ return;
77
+ throw error;
78
+ }
79
+ }
80
+ }
81
+ async close() {
82
+ this.stopAdmission();
83
+ try {
84
+ await this.running;
85
+ }
86
+ finally {
87
+ this.input.signal.removeEventListener("abort", this.cancelBody);
88
+ await rm(this.directory, { recursive: true, force: true });
89
+ }
90
+ }
91
+ stopAdmission() {
92
+ this.admissionClosed = true;
93
+ if (!this.closeSignal.signal.aborted)
94
+ this.closeSignal.abort(new Error("Body request pump closed"));
95
+ }
96
+ }
97
+ export async function clearBodyRequestTransport(paths) {
98
+ await rm(join(paths.directory, "requests"), { recursive: true, force: true });
99
+ }
100
+ async function requestFiles(directory) {
101
+ try {
102
+ return (await readdir(directory)).filter((name) => name.endsWith(".request.json")).sort();
103
+ }
104
+ catch (error) {
105
+ if (error.code === "ENOENT")
106
+ return [];
107
+ throw error;
108
+ }
109
+ }
110
+ async function projectTransportFailure(directory, transportId, claim, error) {
111
+ await atomicJson(receiptPath(directory, transportId), {
112
+ id: claim.id,
113
+ action: claim.action,
114
+ state: "refused",
115
+ diagnostic: error instanceof Error ? error.message : String(error),
116
+ });
117
+ }
118
+ function matchingRequestOrigin(soul, parent, id) {
119
+ return soul.origin.kind === "request" && soul.origin.parent === parent && soul.origin.requestId === id;
120
+ }
121
+ async function settleReservedSoul(paths, parent, request, soul) {
122
+ await (matchingRequestOrigin(soul, parent.id, request.id)
123
+ ? serveRequest(paths, request.id, request.child)
124
+ : voidRequest(paths, request.id, "reserved child origin does not match the request"));
125
+ }
126
+ async function settleReserved(paths, parent, request, now, signal) {
127
+ const childPaths = pathsForAkuId(request.world, request.child);
128
+ const deadline = performance.now() + BIRTH_TIMEOUT_MS;
129
+ for (;;) {
130
+ signal?.throwIfAborted();
131
+ if (!(await access(childPaths.directory).then(() => true, () => false))) {
132
+ await voidRequest(paths, request.id, "reserved child directory is absent");
133
+ return true;
134
+ }
135
+ const soul = await readSoul(childPaths);
136
+ if (soul !== null) {
137
+ await settleReservedSoul(paths, parent, request, soul);
138
+ return true;
139
+ }
140
+ const leash = await HeldAkumaLeash.try(childPaths);
141
+ if (leash !== null) {
142
+ try {
143
+ const settled = await readSoul(childPaths);
144
+ if (settled !== null)
145
+ await settleReservedSoul(paths, parent, request, settled);
146
+ else {
147
+ await leash.sealIfUnborn(childPaths, { evidence: "request settlement", at: now() });
148
+ await voidRequest(paths, request.id, "reserved child was sealed unborn");
149
+ }
150
+ }
151
+ finally {
152
+ leash.release();
153
+ }
154
+ return true;
155
+ }
156
+ if (performance.now() >= deadline)
157
+ return false;
158
+ await abortableDelay(Math.min(POLL_MS, Math.max(0, deadline - performance.now())), signal);
159
+ }
160
+ }
161
+ export async function settleBodyRequests(paths, parent, now, signal) {
162
+ let pending = false;
163
+ for (const request of await readNonterminalRequests(paths)) {
164
+ signal?.throwIfAborted();
165
+ if (request.state === "admitted")
166
+ await voidRequest(paths, request.id, "body died before serving the request");
167
+ else if (request.state === "reserved" && !(await settleReserved(paths, parent, request, now, signal)))
168
+ pending = true;
169
+ }
170
+ return pending ? "pending" : "settled";
171
+ }
@@ -1,13 +1,10 @@
1
- import { type KillEvidence, type RequestFact, type Soul } from "./heart/index.js";
2
- import { type AkuId, type AkumaPaths } from "./identity.js";
1
+ import { type KillEvidence, type RequestFact } from "./heart/index.js";
2
+ import { type AkuId } from "./identity.js";
3
3
  import { type StructuralRequestClaim } from "./request-wire.js";
4
4
  import { type TaskMutationRequest } from "../task/mutation.js";
5
- import type { OwnedProcess } from "../runtime/proc/run.js";
6
- export type RequestChildLaunch = Readonly<{
7
- paths: AkumaPaths;
8
- seed: Omit<Soul, "createdAt">;
9
- initialBody: string;
10
- }>;
5
+ import { BodyRequestPump as LifecycleBodyRequestPump, type RequestChildLaunch as LifecycleRequestChildLaunch, type PumpInput as LifecyclePumpInput } from "./request-lifecycle.js";
6
+ export { clearBodyRequestTransport, settleBodyRequests } from "./request-lifecycle.js";
7
+ export type RequestChildLaunch = LifecycleRequestChildLaunch;
11
8
  type UpstreamCall = Readonly<{
12
9
  signal: AbortSignal;
13
10
  }>;
@@ -60,17 +57,12 @@ export type UpstreamExecutionPort = Readonly<{
60
57
  request: TaskMutationRequest;
61
58
  }>): Promise<unknown>;
62
59
  }>;
63
- type PumpInput = Readonly<{
64
- paths: AkumaPaths;
65
- parent: Soul;
66
- bodySequence: number;
67
- now(): string;
68
- spawn(launch: RequestChildLaunch): Promise<OwnedProcess | void>;
60
+ type PumpInput = Omit<LifecyclePumpInput, "upstream"> & Readonly<{
69
61
  upstream?: UpstreamExecutionPort;
70
- signal: AbortSignal;
71
62
  }>;
72
63
  export type ServeInput = Omit<PumpInput, "bodySequence"> & Readonly<{
73
64
  directory: string;
65
+ transportId: string;
74
66
  claim: StructuralRequestClaim;
75
67
  admissionOpen(): boolean;
76
68
  }>;
@@ -79,22 +71,7 @@ export type UpstreamFact = Exclude<Extract<RequestFact, {
79
71
  }>, Extract<RequestFact, {
80
72
  action: "akuma.call";
81
73
  }>>;
82
- export declare class BodyRequestPump {
83
- private readonly input;
84
- readonly directory: string;
85
- readonly failure: Promise<never>;
86
- private readonly closeSignal;
87
- private readonly executionSignal;
88
- private readonly handled;
89
- private readonly running;
90
- private readonly cancelBody;
91
- private admissionClosed;
92
- private constructor();
74
+ export declare function serveRequest(input: ServeInput): Promise<void>;
75
+ export declare class BodyRequestPump extends LifecycleBodyRequestPump {
93
76
  static open(input: PumpInput): Promise<BodyRequestPump>;
94
- private run;
95
- close(): Promise<void>;
96
- stopAdmission(): void;
97
77
  }
98
- export declare function clearBodyRequestTransport(paths: AkumaPaths): Promise<void>;
99
- export declare function settleBodyRequests(paths: AkumaPaths, parent: Soul, now: () => string, signal?: AbortSignal): Promise<"settled" | "pending">;
100
- export {};