@astrosheep/keiyaku 4.5.13 → 4.5.15

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.
@@ -5,7 +5,7 @@ import { BodySupervisor } from "./body-supervisor.js";
5
5
  import { driveTurn, turnRecipe } from "./turn-drive.js";
6
6
  import { HeldAkumaLeash, breakBody, decidePendingTellDisposition, drainPendingTells, endTurn, failOpenBoundTurns, finishBodyIfIdle, heartExists, isHeartAbsent, probeLeash, projectTell, provePendingTellDispositionCustody, readHeart, readOpenPendingTellDisposition, readTell, readTurn, readNonterminalRequests, recordUndeliveredPendingTells, resolvePendingTellDisposition, } from "./heart/index.js";
7
7
  import { worldRootForAkumaPaths } from "./identity.js";
8
- import { pluginRuntime } from "../plugin/runtime.js";
8
+ import { drainPluginRuntime, pluginRuntime } from "../plugin/runtime.js";
9
9
  import { World } from "../world.js";
10
10
  import { resolveProviderExecution } from "./providers/index.js";
11
11
  import { clearBodyRequestTransport, settleBodyRequests } from "./request-serve.js";
@@ -456,7 +456,9 @@ export async function spawnAkumaBody(launch) {
456
456
  return await spawnDetachedProcess(await bodyProcessInput(launch));
457
457
  }
458
458
  export async function runAkumaBody(launch, world, externalCommands) {
459
- return await driveAkumaBody(launch, undefined, { world, externalCommands });
459
+ const result = await driveAkumaBody(launch, undefined, { world, externalCommands });
460
+ await drainPluginRuntime(world);
461
+ return result;
460
462
  }
461
463
  const DIRECT_TELL_WAKE = {
462
464
  spawn: async (paths) => await spawnAkumaBody({ paths, refuseIfHeld: true }),
@@ -9,6 +9,8 @@ type PluginRuntimeInput = Readonly<{
9
9
  }>;
10
10
  export type PluginRuntime = Readonly<{
11
11
  emit(signal: PluginSignal, reportDiagnostic?: PluginDiagnostic): Promise<void>;
12
+ drain(): Promise<void>;
12
13
  }>;
13
14
  export declare function pluginRuntime(input: PluginRuntimeInput): Promise<PluginRuntime>;
15
+ export declare function drainPluginRuntime(world: WorldRoot): Promise<void>;
14
16
  export {};
@@ -4,6 +4,7 @@ import { isAbsolute, join, posix, relative, sep } from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
5
  import { settings } from "../settings.js";
6
6
  const DIAGNOSTIC_LIMIT = 500;
7
+ const PLUGIN_DRAIN_TIMEOUT_MS = 5_000;
7
8
  const PLUGIN_NAMESPACE = "plugins";
8
9
  const SQUARE_PLUGIN_PACKAGE = "@astrosheep/keiyaku-plugin-square";
9
10
  const BUILTIN_PLUGINS = Object.freeze([
@@ -283,6 +284,11 @@ export async function pluginRuntime(input) {
283
284
  }
284
285
  return await runtime;
285
286
  }
287
+ export async function drainPluginRuntime(world) {
288
+ const runtime = PROCESS_RUNTIMES.get(world);
289
+ if (runtime !== undefined)
290
+ await (await runtime).drain();
291
+ }
286
292
  async function createPluginRuntime(input) {
287
293
  const report = input.reportDiagnostic;
288
294
  const selected = selectedPlugins(input.settings ?? (await settings({ root: input.world })), report);
@@ -290,9 +296,13 @@ async function createPluginRuntime(input) {
290
296
  const registered = new Map();
291
297
  const settled = new Set();
292
298
  const pending = new Map();
299
+ const settledPromises = [];
300
+ const inFlight = new Set();
293
301
  const deliver = (entry, signal, reportDiagnostic) => {
294
302
  try {
295
- void Promise.resolve(entry.handler(signal)).catch((error) => diagnostic(reportDiagnostic, entry.pluginId, "signal", error));
303
+ const delivery = Promise.resolve(entry.handler(signal)).catch((error) => diagnostic(reportDiagnostic, entry.pluginId, "signal", error));
304
+ inFlight.add(delivery);
305
+ void delivery.finally(() => inFlight.delete(delivery));
296
306
  }
297
307
  catch (error) {
298
308
  diagnostic(reportDiagnostic, entry.pluginId, "signal", error);
@@ -307,9 +317,13 @@ async function createPluginRuntime(input) {
307
317
  let previousStarted = Promise.resolve();
308
318
  for (const [index, entry] of selected.entries()) {
309
319
  let releaseStarted;
320
+ let releaseSettled;
310
321
  const started = new Promise((resolve) => {
311
322
  releaseStarted = resolve;
312
323
  });
324
+ settledPromises.push(new Promise((resolve) => {
325
+ releaseSettled = resolve;
326
+ }));
313
327
  void previousStarted.then(async () => {
314
328
  try {
315
329
  const handlers = await activate(entry, input.world, activated, report, releaseStarted);
@@ -330,6 +344,7 @@ async function createPluginRuntime(input) {
330
344
  }
331
345
  finally {
332
346
  releaseStarted();
347
+ releaseSettled();
333
348
  }
334
349
  });
335
350
  previousStarted = started;
@@ -353,5 +368,16 @@ async function createPluginRuntime(input) {
353
368
  deliver(entry, signal, reportDiagnostic);
354
369
  return Promise.resolve();
355
370
  },
371
+ async drain() {
372
+ const settle = async () => {
373
+ await Promise.all(settledPromises);
374
+ while (inFlight.size > 0)
375
+ await Promise.all([...inFlight]);
376
+ };
377
+ await Promise.race([
378
+ settle(),
379
+ new Promise((resolve) => setTimeout(resolve, PLUGIN_DRAIN_TIMEOUT_MS)),
380
+ ]);
381
+ },
356
382
  });
357
383
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/keiyaku",
3
- "version": "4.5.13",
3
+ "version": "4.5.15",
4
4
  "workspaces": [
5
5
  "plugins/*"
6
6
  ],
@@ -77,7 +77,7 @@
77
77
  "dependencies": {
78
78
  "@agentclientprotocol/sdk": "^1.3.0",
79
79
  "@anthropic-ai/claude-agent-sdk": "^0.3.226",
80
- "@astrosheep/keiyaku-plugin-square": "0.1.1",
80
+ "@astrosheep/keiyaku-plugin-square": "0.1.3",
81
81
  "@earendil-works/pi-coding-agent": "0.80.10",
82
82
  "@opencode-ai/sdk": "1.18.3",
83
83
  "cross-spawn": "^7.0.6",