@llblab/pi-actors 0.22.5 → 0.23.0

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 (49) hide show
  1. package/AGENTS.md +1 -0
  2. package/BACKLOG.md +0 -220
  3. package/CHANGELOG.md +18 -1
  4. package/README.md +1 -1
  5. package/dist/index.js +15 -0
  6. package/dist/lib/actor-inspector-tui.d.ts +4 -0
  7. package/dist/lib/actor-inspector-tui.js +53 -12
  8. package/dist/lib/actor-rooms.d.ts +8 -0
  9. package/dist/lib/actor-rooms.js +61 -10
  10. package/dist/lib/async-runs.d.ts +34 -2
  11. package/dist/lib/async-runs.js +215 -22
  12. package/dist/lib/command-templates.js +5 -5
  13. package/dist/lib/limits.d.ts +11 -0
  14. package/dist/lib/limits.js +11 -0
  15. package/dist/lib/observability.js +6 -4
  16. package/dist/lib/output.js +4 -5
  17. package/dist/lib/recipe-discovery.js +1 -0
  18. package/dist/lib/recipe-references.d.ts +11 -2
  19. package/dist/lib/recipe-references.js +4 -2
  20. package/dist/lib/recipe-usage.d.ts +2 -1
  21. package/dist/lib/recipe-usage.js +15 -3
  22. package/dist/lib/runtime.js +12 -2
  23. package/dist/lib/tools.js +197 -38
  24. package/docs/async-runs.md +2 -1
  25. package/docs/template-recipes.md +1 -1
  26. package/docs/tool-registry.md +0 -1
  27. package/index.ts +18 -0
  28. package/lib/actor-inspector-tui.ts +131 -29
  29. package/lib/actor-rooms.ts +155 -44
  30. package/lib/async-runs.ts +290 -31
  31. package/lib/command-templates.ts +5 -5
  32. package/lib/limits.ts +12 -0
  33. package/lib/observability.ts +10 -4
  34. package/lib/output.ts +4 -6
  35. package/lib/recipe-discovery.ts +1 -0
  36. package/lib/recipe-references.ts +20 -4
  37. package/lib/recipe-usage.ts +31 -4
  38. package/lib/runtime.ts +31 -7
  39. package/lib/tools.ts +296 -57
  40. package/package.json +2 -1
  41. package/scripts/async-runner.mjs +6 -0
  42. package/scripts/conformance.mjs +47 -0
  43. package/scripts/coordinator.mjs +13 -0
  44. package/scripts/locker.mjs +13 -0
  45. package/scripts/music-player.mjs +21 -2
  46. package/scripts/recipe-utils.mjs +13 -0
  47. package/scripts/validate-recipe.mjs +13 -0
  48. package/skills/actors/SKILL.md +3 -3
  49. package/skills/swarm/SKILL.md +1 -1
@@ -64,22 +64,27 @@ function event(name, data = {}) {
64
64
  `${JSON.stringify({ event: name, ts: new Date().toISOString(), ...data })}\n`,
65
65
  );
66
66
  }
67
+
67
68
  function quoteCommandDetailPart(value) {
68
69
  if (value === "") return "''";
69
70
  if (/^[A-Za-z0-9_/:=.,@%+\-]+$/.test(value)) return value;
70
71
  return `'${String(value).replaceAll("'", "'\\''")}'`;
71
72
  }
73
+
72
74
  function formatCommandDetail(command, args) {
73
75
  return [command, ...args].map(quoteCommandDetailPart).join(" ");
74
76
  }
77
+
75
78
  function summarizeCommandDetail(commandDetail) {
76
79
  return commandDetail.length > 160
77
80
  ? `${commandDetail.slice(0, 157)}...`
78
81
  : commandDetail;
79
82
  }
83
+
80
84
  function getCommandDoneDelivery(result) {
81
85
  return result.code !== 0 || activeSubagents > 0 ? "followup" : "log";
82
86
  }
87
+
83
88
  function outbox(name, summary, data = {}, delivery = "log", level = "info") {
84
89
  appendFileSync(
85
90
  outboxPath,
@@ -102,6 +107,7 @@ function progress(phase, extra = {}) {
102
107
  let activeSubagents = 0;
103
108
  let completedSubagents = 0;
104
109
  const subagentFailures = [];
110
+
105
111
  function progressRunning() {
106
112
  progress("running", {
107
113
  activeSubagents,
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Internal conformance runner.
5
+ *
6
+ * This script runs the protocol-facing regression suites that exercise recipe
7
+ * discovery, registry mutation, spawn lifecycle, message routing, room/branch
8
+ * state, ownership checks, artifacts, and attention semantics without requiring
9
+ * the Pi UI.
10
+ *
11
+ * Keep output compact for CI and release preflight use; detailed failures are
12
+ * printed only when the underlying Node test run fails.
13
+ */
14
+
15
+ import { spawnSync } from "node:child_process";
16
+
17
+ const suites = [
18
+ "tests/protocol-examples.test.ts",
19
+ "tests/recipe-discovery.test.ts",
20
+ "tests/registry.test.ts",
21
+ "tests/runtime-registry.test.ts",
22
+ "tests/async-runs.test.ts",
23
+ "tests/actor-rooms.test.ts",
24
+ "tests/tools.test.ts",
25
+ ];
26
+
27
+ const result = spawnSync(
28
+ process.execPath,
29
+ ["--experimental-strip-types", "--test", ...suites],
30
+ { cwd: new URL("..", import.meta.url), encoding: "utf8", stdio: "pipe" },
31
+ );
32
+
33
+ const output = `${result.stdout ?? ""}${result.stderr ?? ""}`;
34
+ const summary = output
35
+ .split("\n")
36
+ .filter((line) =>
37
+ /^ℹ (tests|pass|fail|cancelled|skipped|todo|duration_ms) /.test(line),
38
+ )
39
+ .join("\n");
40
+
41
+ console.log("pi-actors conformance");
42
+ console.log(`suites ${suites.length}`);
43
+ if (summary) console.log(summary);
44
+ if (result.status !== 0) {
45
+ console.error(output.trimEnd());
46
+ process.exit(result.status ?? 1);
47
+ }
@@ -1,4 +1,17 @@
1
1
  #!/usr/bin/env node
2
+
3
+ /**
4
+ * Multi-actor coordinator helper.
5
+ *
6
+ * This script is the local orchestration process behind packaged swarm and
7
+ * worker-pool recipes. It starts child actors, assigns work through room and
8
+ * branch mailboxes, records progress artifacts, and coordinates optional locker
9
+ * state without owning project-specific policy.
10
+ *
11
+ * Keep reusable coordination mechanics here; keep caller goals, prompts, model
12
+ * choices, and release/project policy in recipes or invocation arguments.
13
+ */
14
+
2
15
  import { spawn } from "node:child_process";
3
16
  import { existsSync } from "node:fs";
4
17
  import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
@@ -1,4 +1,17 @@
1
1
  #!/usr/bin/env node
2
+
3
+ /**
4
+ * Local coordination locker service.
5
+ *
6
+ * This script owns a small file-backed lock/task state directory and exposes a
7
+ * Unix-socket command surface for coordinators. It can serve live lock requests,
8
+ * queue work items, hand out task leases, renew/release resource locks, and emit
9
+ * compact snapshots for inspection.
10
+ *
11
+ * Keep it generic: no project policy, no recipe-specific prompts, and no actor
12
+ * orchestration decisions belong in this layer.
13
+ */
14
+
2
15
  import { spawnSync } from "node:child_process";
3
16
  import { createHash } from "node:crypto";
4
17
  import {
@@ -1,4 +1,17 @@
1
1
  #!/usr/bin/env node
2
+
3
+ /**
4
+ * Packaged local music-player actor helper.
5
+ *
6
+ * This script backs the standard music-player recipe. It scans local music
7
+ * sources, builds playback queues, launches an available backend player, and
8
+ * consumes run-mailbox control messages such as play, pause, next, previous,
9
+ * stop, and status.
10
+ *
11
+ * Keep the helper focused on one maintained player actor implementation; recipe
12
+ * metadata and invocation arguments choose source paths and backend behavior.
13
+ */
14
+
2
15
  import { spawn } from "node:child_process";
3
16
  import { randomUUID } from "node:crypto";
4
17
  import {
@@ -156,7 +169,9 @@ function windowsMediaPlayerExecutable() {
156
169
  const roots = [
157
170
  process.env.ProgramFiles,
158
171
  process.env["ProgramFiles(x86)"],
159
- process.env.SystemDrive ? join(process.env.SystemDrive, "Program Files") : undefined,
172
+ process.env.SystemDrive
173
+ ? join(process.env.SystemDrive, "Program Files")
174
+ : undefined,
160
175
  process.env.SystemDrive
161
176
  ? join(process.env.SystemDrive, "Program Files (x86)")
162
177
  : undefined,
@@ -728,7 +743,11 @@ function startControlLoop(ctx) {
728
743
  try {
729
744
  watcher = watch(ctx.stateDir, { persistent: false }, (_eventType, file) => {
730
745
  const name = file ? String(file) : "";
731
- if (!name || name === basename(ctx.inboxFile) || name === basename(runtimeWakeFile(ctx))) {
746
+ if (
747
+ !name ||
748
+ name === basename(ctx.inboxFile) ||
749
+ name === basename(runtimeWakeFile(ctx))
750
+ ) {
732
751
  dirty = true;
733
752
  }
734
753
  });
@@ -1,4 +1,17 @@
1
1
  #!/usr/bin/env node
2
+
3
+ /**
4
+ * Recipe utility command bundle.
5
+ *
6
+ * This script provides small, deterministic helper subcommands used by packaged
7
+ * recipes: run summaries, operational snapshots, playlist generation, changelog
8
+ * extraction, artifact manifests/writes, actor-message envelopes, package
9
+ * summaries, and skill summaries.
10
+ *
11
+ * Keep outputs compact and machine-readable where possible because recipe-utils
12
+ * often feeds command-template pipelines and actor context directly.
13
+ */
14
+
2
15
  import {
3
16
  appendFileSync,
4
17
  existsSync,
@@ -1,4 +1,17 @@
1
1
  #!/usr/bin/env -S node --experimental-strip-types
2
+
3
+ /**
4
+ * Template recipe validator CLI.
5
+ *
6
+ * This script validates one recipe file or a recipe directory using the same
7
+ * recipe-reference parser and import resolver that the extension runtime uses.
8
+ * It supports source-tree TypeScript during development and compiled dist
9
+ * modules when installed from npm.
10
+ *
11
+ * Keep it read-only: validation should report parse/import/schema problems
12
+ * without registering tools, launching runs, or mutating user recipes.
13
+ */
14
+
2
15
  import { existsSync, readdirSync, statSync } from "node:fs";
3
16
  import { homedir } from "node:os";
4
17
  import { dirname, join, resolve } from "node:path";
@@ -2,7 +2,7 @@
2
2
  name: actors
3
3
  description: Highest-density practical guide for pi-actors. Read this skill whenever prompt and tools are not enough for spawn, message, inspect, actor runs, tools, recipes, command templates, async lifecycle, mailboxes, artifacts, and local orchestration mechanics.
4
4
  metadata:
5
- version: 0.22.5
5
+ version: 0.23.0
6
6
  ---
7
7
 
8
8
  # Actors (pi-actors)
@@ -84,7 +84,7 @@ Envelope fields:
84
84
  - Useful: `summary`, `body`, `from`, `reply_to`, `correlation_id`, `metadata`.
85
85
  - Addresses: `run:<id>`, `branch:<run>/<branch>`, `room:<run>`, `tool:<name>`, `coordinator`, `session:<id>`.
86
86
  - Room posts require `from` from the same run (`run:<run>` or `branch:<run>/<branch>`).
87
- - Standard termination messages: `control.stop`, `control.cancel`, `control.kill`.
87
+ - Standard termination messages: `control.stop`, `control.cancel`, `control.kill`; terminal retention messages: `control.archive`, `control.prune`.
88
88
 
89
89
  Check `inspect view=mailbox` before domain-specific messages.
90
90
 
@@ -125,7 +125,7 @@ Actor inspector commands:
125
125
  - `/actors-inspector-filter all|room|direct|broadcast|unread|branch <name>|current-branch <name>|mention <text>`: narrow table previews without changing room/run state.
126
126
  - `/actors-inspect <number>`: open one visible row as a full-message view.
127
127
 
128
- The table is compact and optimistic by default: bounded body previews, capped noisy room rows, branch-local inbox previews, and an inline roster summary in the form `name/role` that wraps only when needed. Use `unread` for queued branch inbox work and `branch <name>` / `current-branch <name>` for one branch's room/direct/inbox traffic. Active roster members use the target color; members that sent `actor.leave` stay visible as inactive/muted participants from the current run. Actor display names come from `actor.join` bodies (`display`) or branch addresses, keeping debugger output plain and name-driven.
128
+ The table is compact and optimistic by default: bounded body previews, capped noisy room rows, branch-local inbox previews, stable event ids in selected-message details, and an inline roster summary in the form `name/role` that wraps only when needed. Use `unread` for queued branch inbox work and `branch <name>` / `current-branch <name>` for one branch's room/direct/inbox traffic. Rows with `metadata.requires_response=true` show a `!` attention marker. `/actors-inspect <number>` marks that row read for the current session filter. Active roster members use the target color; members that sent `actor.leave` stay visible as inactive/muted participants from the current run. Actor display names come from `actor.join` bodies (`display`) or branch addresses, keeping debugger output plain and name-driven.
129
129
 
130
130
  Let terminal notifications arrive; avoid sleep-poll loops except during diagnosis.
131
131
 
@@ -2,7 +2,7 @@
2
2
  name: swarm
3
3
  description: Subagent orchestration with scoped locks and quorum consensus. Use for multi-model review, parallel scoped work, delegated audit, and coordinated subagent execution.
4
4
  metadata:
5
- version: 0.22.5
5
+ version: 0.23.0
6
6
  ---
7
7
 
8
8
  # Swarm