@llblab/pi-actors 0.42.3 → 0.43.1

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 (279) hide show
  1. package/AGENTS.md +127 -175
  2. package/BACKLOG.md +189 -1
  3. package/CHANGELOG.md +183 -292
  4. package/README.md +115 -276
  5. package/dist/fixtures/protocol/control-endpoint.json +6 -0
  6. package/dist/fixtures/protocol/control-record.json +9 -0
  7. package/dist/fixtures/protocol/recipe-summary.json +4 -12
  8. package/dist/fixtures/protocol/trace-event.json +9 -0
  9. package/dist/index.js +1 -1
  10. package/dist/lib/async-runs.d.ts +15 -38
  11. package/dist/lib/async-runs.js +173 -111
  12. package/dist/lib/automatic-review-runtime.d.ts +1 -1
  13. package/dist/lib/automatic-review-runtime.js +5 -5
  14. package/dist/lib/command-templates.d.ts +2 -0
  15. package/dist/lib/command-templates.js +38 -4
  16. package/dist/lib/control-projection.d.ts +20 -0
  17. package/dist/lib/control-projection.js +66 -0
  18. package/dist/lib/control.d.ts +15 -0
  19. package/dist/lib/control.js +97 -0
  20. package/dist/lib/draft-sleep.js +3 -3
  21. package/dist/lib/execution-sessions.d.ts +17 -0
  22. package/dist/lib/execution-sessions.js +85 -0
  23. package/dist/lib/file-state.d.ts +2 -0
  24. package/dist/lib/file-state.js +114 -46
  25. package/dist/lib/inspector-actions.d.ts +2 -2
  26. package/dist/lib/inspector-actions.js +2 -2
  27. package/dist/lib/inspector-command.js +3 -3
  28. package/dist/lib/inspector-overlay.d.ts +54 -70
  29. package/dist/lib/inspector-overlay.js +576 -910
  30. package/dist/lib/inspector.d.ts +3 -71
  31. package/dist/lib/inspector.js +19 -665
  32. package/dist/lib/limits.d.ts +7 -3
  33. package/dist/lib/limits.js +7 -3
  34. package/dist/lib/observability.d.ts +16 -16
  35. package/dist/lib/observability.js +43 -82
  36. package/dist/lib/prompts.d.ts +1 -1
  37. package/dist/lib/prompts.js +3 -3
  38. package/dist/lib/recipe-control.d.ts +7 -0
  39. package/dist/lib/recipe-control.js +43 -0
  40. package/dist/lib/recipes-discovery.js +2 -0
  41. package/dist/lib/recipes-references.d.ts +1 -14
  42. package/dist/lib/recipes-references.js +6 -21
  43. package/dist/lib/review-control.d.ts +1 -1
  44. package/dist/lib/review-control.js +4 -5
  45. package/dist/lib/review-projection.js +1 -5
  46. package/dist/lib/run-ui-runtime.js +2 -2
  47. package/dist/lib/runs-control-delivery.d.ts +28 -0
  48. package/dist/lib/runs-control-delivery.js +150 -0
  49. package/dist/lib/runs-controls.d.ts +37 -0
  50. package/dist/lib/runs-controls.js +146 -0
  51. package/dist/lib/runs-retention.d.ts +7 -0
  52. package/dist/lib/runs-retention.js +27 -3
  53. package/dist/lib/runs-start.js +4 -2
  54. package/dist/lib/runs-status.js +11 -6
  55. package/dist/lib/runs-trace.d.ts +24 -0
  56. package/dist/lib/runs-trace.js +102 -0
  57. package/dist/lib/runtime-identity.d.ts +7 -0
  58. package/dist/lib/runtime-identity.js +35 -0
  59. package/dist/lib/runtime-notifier.d.ts +1 -1
  60. package/dist/lib/runtime-notifier.js +1 -1
  61. package/dist/lib/runtime-triage.d.ts +29 -0
  62. package/dist/lib/runtime-triage.js +76 -0
  63. package/dist/lib/tool-review-scheduler.js +7 -7
  64. package/dist/lib/tools-inspect.d.ts +3 -3
  65. package/dist/lib/tools-inspect.js +241 -707
  66. package/dist/lib/tools-local.js +2 -10
  67. package/dist/lib/tools-message.d.ts +6 -7
  68. package/dist/lib/tools-message.js +95 -396
  69. package/dist/lib/tools-response.d.ts +1 -5
  70. package/dist/lib/tools-response.js +5 -48
  71. package/dist/lib/tools-spawn.js +16 -28
  72. package/dist/lib/tools.d.ts +1 -1
  73. package/dist/lib/tools.js +2 -3
  74. package/dist/lib/trace-projection.d.ts +22 -0
  75. package/dist/lib/trace-projection.js +185 -0
  76. package/dist/recipes/draft-review.json +0 -10
  77. package/dist/recipes/lens-swarm.json +0 -14
  78. package/dist/recipes/music-player.json +10 -19
  79. package/dist/recipes/pipeline-architect-coordinator.json +0 -11
  80. package/dist/recipes/pipeline-artifact-bundle.json +1 -22
  81. package/dist/recipes/pipeline-artifact-report.json +1 -18
  82. package/dist/recipes/pipeline-artifact-write.json +1 -18
  83. package/dist/recipes/pipeline-async-run-ops.json +0 -12
  84. package/dist/recipes/pipeline-checkpoint-continuation.json +0 -14
  85. package/dist/recipes/pipeline-development-tasking.json +0 -12
  86. package/dist/recipes/pipeline-docs-maintenance.json +0 -12
  87. package/dist/recipes/pipeline-media-library.json +0 -12
  88. package/dist/recipes/pipeline-quorum-review.json +0 -12
  89. package/dist/recipes/pipeline-release-readiness.json +0 -12
  90. package/dist/recipes/pipeline-release-summary.json +0 -12
  91. package/dist/recipes/pipeline-repo-health.json +0 -12
  92. package/dist/recipes/pipeline-research-synthesis.json +0 -11
  93. package/dist/recipes/pipeline-review-readiness.json +0 -12
  94. package/dist/recipes/resource-locker.json +27 -0
  95. package/dist/recipes/subagent-artifact.json +0 -9
  96. package/dist/recipes/subagent-checkpoint.json +0 -10
  97. package/dist/recipes/subagent-conflict-report.json +0 -11
  98. package/dist/recipes/subagent-contradiction-map.json +0 -11
  99. package/dist/recipes/subagent-critic.json +0 -11
  100. package/dist/recipes/subagent-evidence-map.json +0 -11
  101. package/dist/recipes/subagent-followup.json +0 -10
  102. package/dist/recipes/subagent-judge.json +0 -11
  103. package/dist/recipes/subagent-merge.json +0 -11
  104. package/dist/recipes/subagent-normalize.json +0 -11
  105. package/dist/recipes/subagent-plan.json +0 -11
  106. package/dist/recipes/subagent-preflight.json +0 -11
  107. package/dist/recipes/subagent-prompt.json +0 -10
  108. package/dist/recipes/subagent-quorum.json +0 -10
  109. package/dist/recipes/subagent-review-coordinator.json +0 -14
  110. package/dist/recipes/subagent-review.json +0 -11
  111. package/dist/recipes/subagent-task-card.json +0 -11
  112. package/dist/recipes/subagent-tools.json +0 -10
  113. package/dist/recipes/subagent-verify.json +0 -11
  114. package/dist/recipes/subagents-prompts.json +0 -10
  115. package/dist/recipes/tool-review.json +0 -10
  116. package/dist/scripts/async-runner.mjs +25 -25
  117. package/dist/scripts/conformance.mjs +4 -2
  118. package/dist/scripts/locker.mjs +196 -69
  119. package/dist/scripts/music-player.mjs +162 -159
  120. package/dist/scripts/recipe-utils.mjs +6 -96
  121. package/dist/scripts/release-gates.mjs +91 -0
  122. package/dist/scripts/validate-recipe.mjs +8 -57
  123. package/dist/skills/actors/SKILL.md +57 -265
  124. package/dist/skills/swarm/SKILL.md +10 -34
  125. package/docs/0.43-baseline.md +39 -0
  126. package/docs/README.md +4 -6
  127. package/docs/actor-inspector.md +26 -64
  128. package/docs/async-runs.md +81 -328
  129. package/docs/command-templates.md +8 -118
  130. package/docs/recipe-library.md +55 -182
  131. package/docs/releasing.md +28 -0
  132. package/docs/template-recipes.md +76 -289
  133. package/docs/tool-registry.md +41 -161
  134. package/fixtures/protocol/control-endpoint.json +6 -0
  135. package/fixtures/protocol/control-record.json +9 -0
  136. package/fixtures/protocol/recipe-summary.json +4 -12
  137. package/fixtures/protocol/trace-event.json +9 -0
  138. package/index.ts +1 -1
  139. package/lib/async-runs.ts +218 -204
  140. package/lib/automatic-review-runtime.ts +7 -7
  141. package/lib/command-templates.ts +44 -4
  142. package/lib/control-projection.ts +105 -0
  143. package/lib/control.ts +117 -0
  144. package/lib/draft-sleep.ts +3 -3
  145. package/lib/execution-sessions.ts +111 -0
  146. package/lib/file-state.ts +84 -64
  147. package/lib/inspector-actions.ts +2 -2
  148. package/lib/inspector-command.ts +3 -3
  149. package/lib/inspector-overlay.ts +617 -1126
  150. package/lib/inspector.ts +46 -979
  151. package/lib/limits.ts +7 -3
  152. package/lib/observability.ts +60 -101
  153. package/lib/prompts.ts +3 -3
  154. package/lib/recipe-control.ts +52 -0
  155. package/lib/recipes-discovery.ts +2 -0
  156. package/lib/recipes-references.ts +9 -45
  157. package/lib/review-control.ts +4 -5
  158. package/lib/review-projection.ts +1 -5
  159. package/lib/run-ui-runtime.ts +2 -2
  160. package/lib/runs-control-delivery.ts +209 -0
  161. package/lib/runs-controls.ts +213 -0
  162. package/lib/runs-retention.ts +38 -3
  163. package/lib/runs-start.ts +4 -2
  164. package/lib/runs-status.ts +11 -6
  165. package/lib/runs-trace.ts +136 -0
  166. package/lib/runtime-identity.ts +39 -0
  167. package/lib/runtime-notifier.ts +1 -1
  168. package/lib/runtime-triage.ts +120 -0
  169. package/lib/tool-review-scheduler.ts +7 -7
  170. package/lib/tools-inspect.ts +283 -900
  171. package/lib/tools-local.ts +2 -12
  172. package/lib/tools-message.ts +112 -520
  173. package/lib/tools-response.ts +5 -64
  174. package/lib/tools-spawn.ts +16 -32
  175. package/lib/tools.ts +5 -6
  176. package/lib/trace-projection.ts +244 -0
  177. package/package.json +2 -1
  178. package/recipes/draft-review.json +0 -10
  179. package/recipes/lens-swarm.json +0 -14
  180. package/recipes/music-player.json +10 -19
  181. package/recipes/pipeline-architect-coordinator.json +0 -11
  182. package/recipes/pipeline-artifact-bundle.json +1 -22
  183. package/recipes/pipeline-artifact-report.json +1 -18
  184. package/recipes/pipeline-artifact-write.json +1 -18
  185. package/recipes/pipeline-async-run-ops.json +0 -12
  186. package/recipes/pipeline-checkpoint-continuation.json +0 -14
  187. package/recipes/pipeline-development-tasking.json +0 -12
  188. package/recipes/pipeline-docs-maintenance.json +0 -12
  189. package/recipes/pipeline-media-library.json +0 -12
  190. package/recipes/pipeline-quorum-review.json +0 -12
  191. package/recipes/pipeline-release-readiness.json +0 -12
  192. package/recipes/pipeline-release-summary.json +0 -12
  193. package/recipes/pipeline-repo-health.json +0 -12
  194. package/recipes/pipeline-research-synthesis.json +0 -11
  195. package/recipes/pipeline-review-readiness.json +0 -12
  196. package/recipes/resource-locker.json +27 -0
  197. package/recipes/subagent-artifact.json +0 -9
  198. package/recipes/subagent-checkpoint.json +0 -10
  199. package/recipes/subagent-conflict-report.json +0 -11
  200. package/recipes/subagent-contradiction-map.json +0 -11
  201. package/recipes/subagent-critic.json +0 -11
  202. package/recipes/subagent-evidence-map.json +0 -11
  203. package/recipes/subagent-followup.json +0 -10
  204. package/recipes/subagent-judge.json +0 -11
  205. package/recipes/subagent-merge.json +0 -11
  206. package/recipes/subagent-normalize.json +0 -11
  207. package/recipes/subagent-plan.json +0 -11
  208. package/recipes/subagent-preflight.json +0 -11
  209. package/recipes/subagent-prompt.json +0 -10
  210. package/recipes/subagent-quorum.json +0 -10
  211. package/recipes/subagent-review-coordinator.json +0 -14
  212. package/recipes/subagent-review.json +0 -11
  213. package/recipes/subagent-task-card.json +0 -11
  214. package/recipes/subagent-tools.json +0 -10
  215. package/recipes/subagent-verify.json +0 -11
  216. package/recipes/subagents-prompts.json +0 -10
  217. package/recipes/tool-review.json +0 -10
  218. package/scripts/async-runner.mjs +25 -25
  219. package/scripts/conformance.mjs +4 -2
  220. package/scripts/locker.mjs +196 -69
  221. package/scripts/music-player.mjs +162 -159
  222. package/scripts/recipe-utils.mjs +6 -96
  223. package/scripts/release-gates.mjs +91 -0
  224. package/scripts/validate-recipe.mjs +8 -57
  225. package/skills/actors/SKILL.md +57 -265
  226. package/skills/swarm/SKILL.md +10 -34
  227. package/dist/fixtures/protocol/actor-message-branch.json +0 -13
  228. package/dist/fixtures/protocol/mailbox-contract.json +0 -15
  229. package/dist/fixtures/protocol/room-message.json +0 -11
  230. package/dist/fixtures/protocol/room-roster.json +0 -11
  231. package/dist/fixtures/protocol/run-inbox-message.json +0 -9
  232. package/dist/fixtures/protocol/run-outbox-event.json +0 -9
  233. package/dist/lib/mailbox-loop.d.ts +0 -41
  234. package/dist/lib/mailbox-loop.js +0 -60
  235. package/dist/lib/messages.d.ts +0 -25
  236. package/dist/lib/messages.js +0 -122
  237. package/dist/lib/rooms.d.ts +0 -104
  238. package/dist/lib/rooms.js +0 -647
  239. package/dist/lib/runs-mailbox.d.ts +0 -25
  240. package/dist/lib/runs-mailbox.js +0 -146
  241. package/dist/lib/runs-messages.d.ts +0 -15
  242. package/dist/lib/runs-messages.js +0 -179
  243. package/dist/lib/runs-outbox.d.ts +0 -41
  244. package/dist/lib/runs-outbox.js +0 -87
  245. package/dist/lib/tools-mailbox.d.ts +0 -8
  246. package/dist/lib/tools-mailbox.js +0 -48
  247. package/dist/recipes/actor-worker.json +0 -39
  248. package/dist/recipes/coordinator-locker.json +0 -45
  249. package/dist/recipes/locker.json +0 -45
  250. package/dist/recipes/pipeline-room-swarm.json +0 -50
  251. package/dist/recipes/subagent-message.json +0 -32
  252. package/dist/recipes/utility-actor-message.json +0 -23
  253. package/dist/scripts/actor-worker.mjs +0 -214
  254. package/dist/scripts/coordinator.mjs +0 -799
  255. package/docs/actor-messages.md +0 -225
  256. package/docs/actors-deep-reference.md +0 -66
  257. package/docs/component-recipes.md +0 -148
  258. package/docs/task-first-recipes.md +0 -263
  259. package/fixtures/protocol/actor-message-branch.json +0 -13
  260. package/fixtures/protocol/mailbox-contract.json +0 -15
  261. package/fixtures/protocol/room-message.json +0 -11
  262. package/fixtures/protocol/room-roster.json +0 -11
  263. package/fixtures/protocol/run-inbox-message.json +0 -9
  264. package/fixtures/protocol/run-outbox-event.json +0 -9
  265. package/lib/mailbox-loop.ts +0 -144
  266. package/lib/messages.ts +0 -151
  267. package/lib/rooms.ts +0 -939
  268. package/lib/runs-mailbox.ts +0 -208
  269. package/lib/runs-messages.ts +0 -252
  270. package/lib/runs-outbox.ts +0 -144
  271. package/lib/tools-mailbox.ts +0 -56
  272. package/recipes/actor-worker.json +0 -39
  273. package/recipes/coordinator-locker.json +0 -45
  274. package/recipes/locker.json +0 -45
  275. package/recipes/pipeline-room-swarm.json +0 -50
  276. package/recipes/subagent-message.json +0 -32
  277. package/recipes/utility-actor-message.json +0 -23
  278. package/scripts/actor-worker.mjs +0 -214
  279. package/scripts/coordinator.mjs +0 -799
package/README.md CHANGED
@@ -1,48 +1,13 @@
1
1
  # pi-actors
2
2
 
3
- ![Actors](./banner.jpg)
4
-
5
- **Local actor kernel for Pi.**
6
-
7
- `pi-actors` turns trusted local programs, scripts, services, pipelines, recipes, and sub-agents into addressable actors that Pi can spawn, steer, inspect, and reuse. It is the bridge between one-shot shell commands and durable local capability memory.
8
-
9
- A command is a moment. An actor is a local thing with time: address, lifecycle, logs, mailbox, messages, artifacts, state, and an interaction contract.
3
+ Local Run kernel and persistent tool registry for [Pi](https://github.com/badlogic/pi-mono).
10
4
 
11
5
  ```text
12
- trusted local capability
13
- → command template
14
- → recipe
15
- → spawn
16
- → run:<id>
17
- → message / inspect / artifacts
18
- → reusable tool memory
6
+ Recipe --spawn--> Run
7
+ Run = Recipe + Trace + Control
19
8
  ```
20
9
 
21
- ## Why it exists
22
-
23
- Agents are good at reasoning, but they should not reconstruct the same fragile background command every time a task becomes long-lived. `pi-actors` gives Pi a local-first actor layer: work can outlive the current turn, expose bounded state, receive typed instructions, produce artifacts, and graduate into persistent recipe-backed tools under `~/.pi/agent/recipes`.
24
-
25
- Use it when the correct shape is not "run a command and forget" but "start a local capability, keep its handle, and come back with intent."
26
-
27
- ## The promise
28
-
29
- - **Spawn long-lived work without shell gymnastics.** Start services, workers, subagents, fanouts, and pipelines as named actor runs.
30
- - **Steer instead of restarting.** Send typed `message` envelopes to runs, tools, branches, rooms, sessions, or coordinators.
31
- - **Inspect intentionally.** Read status, logs, messages, mailboxes, artifacts, registry health, and room rosters at decision points.
32
- - **Promote what works.** Persist trusted command templates and recipes as durable local tools in `~/.pi/agent/recipes`.
33
- - **Keep orchestration local.** State is file-backed, inspectable, operator-owned, and designed for Pi sessions rather than a cloud broker.
34
-
35
- ## Core verbs
36
-
37
- `pi-actors` compresses local orchestration into three public verbs:
38
-
39
- | Verb | Use it when | Result |
40
- | --- | --- | --- |
41
- | `spawn` | Work may outlive this turn, fan out, produce artifacts, or need later steering | A `run:<id>` actor with lifecycle and state |
42
- | `message` | An existing actor should be continued, stopped, approved, killed, or given scoped input | One typed envelope delivered to one address |
43
- | `inspect` | You need evidence before deciding the next step | Bounded views of status, logs, messages, registry, artifacts, or rooms |
44
-
45
- Everything else is an adapter until proven otherwise.
10
+ An **actor** is any runnable local capability: a script, tool, service, pipeline, or subagent. A **Recipe** is its reusable executable definition. `spawn` creates a **Run**—one concrete actor instance—which captures its Recipe, appends observable **Trace**, and may consume actor-local **Control**.
46
11
 
47
12
  ## Install
48
13
 
@@ -50,317 +15,191 @@ Everything else is an adapter until proven otherwise.
50
15
  pi install npm:@llblab/pi-actors
51
16
  ```
52
17
 
53
- Or from git:
18
+ For local development:
54
19
 
55
20
  ```bash
56
- pi install git:github.com/llblab/pi-actors
21
+ pi install /path/to/pi-actors
57
22
  ```
58
23
 
59
- The npm package is dist-first for JavaScript-only runtimes: Pi metadata points at the named compiled entrypoint `dist/pi-actors/index.js` plus mirrored runtime assets, so extension discovery identifies `pi-actors` rather than an anonymous `dist` directory. Source TypeScript and source skills remain packaged for TypeScript-native or checkout-based runtimes.
24
+ The package contributes the extension, packaged Recipes, and the `actors` and `swarm` skills.
60
25
 
61
- ## First run: actor mode in one minute
26
+ ## Public Tools
62
27
 
63
- Use actors instead of ad hoc shell backgrounding when work is long-running, stateful, resumable, artifact-producing, service-like, parallel, agentic, or worth saving.
28
+ ### `spawn`
64
29
 
65
- Start an actor:
30
+ Create a Run from a packaged/local Recipe or an inline command template:
66
31
 
67
32
  ```text
68
33
  spawn template="sleep 30" as=run:demo
34
+ spawn recipe=pipeline-repo-health values={"repo":"/work/project","model":"provider/model"}
35
+ spawn template="make test" as=run:test
69
36
  ```
70
37
 
71
- Inspect it when you need evidence:
38
+ Use a Run when work may outlive the current turn, needs steering, fans out, produces artifacts, or must remain inspectable. Short foreground commands can remain ordinary tools.
72
39
 
73
- ```text
74
- inspect target=run:demo view=status
75
- inspect target=run:demo view=tail lines=40
76
- ```
40
+ ### `message`
77
41
 
78
- Steer it with a typed message:
42
+ Send one exact Control:
79
43
 
80
- ```text
81
- message to=run:demo type=control.kill body=stop
44
+ ```json
45
+ {
46
+ "target": "run:player",
47
+ "action": "pause",
48
+ "input": { "reason": "operator" },
49
+ "verbose": false
50
+ }
82
51
  ```
83
52
 
84
- For non-trivial actor workflows, load the bundled `actors` skill before improvising. For multi-model review or delegated audit, load the bundled `swarm` skill.
85
-
86
- ## Address surface
87
-
88
- Core addresses stay small:
53
+ Run targets accept only actions declared by the captured Recipe. Runtime targets accept only reserved review actions:
89
54
 
90
55
  ```text
91
- run:<id> one detached actor run
92
- tool:<name> executable registered tool actor
56
+ message target=runtime action=review.retry input={"scope":"draft"}
57
+ message target=runtime action=review.retry input={"scope":"tool"}
58
+ message target=runtime action=review.reset input={"scope":"draft"}
59
+ message target=runtime action=review.reset input={"scope":"tool"}
93
60
  ```
94
61
 
95
- Advanced addresses exist for coordination and diagnostics:
62
+ Lifecycle `kill` remains runtime-owned rather than Recipe-declared.
96
63
 
97
- ```text
98
- branch:<run>/<branch> branch-local worker endpoint
99
- room:<run> run-local group timeline plus roster
100
- coordinator current session coordination path
101
- session: current session actor surface
102
- session:all cross-session diagnostics inventory
103
- ```
64
+ ### `inspect`
104
65
 
105
- Messages use one envelope shape:
66
+ Inspect one exact management target:
106
67
 
107
- ```json
108
- {
109
- "to": "run:review",
110
- "from": "coordinator",
111
- "type": "control.continue",
112
- "summary": "Continue after checkpoint",
113
- "body": "continue",
114
- "reply_to": "msg_123",
115
- "correlation_id": "task_456",
116
- "metadata": {}
117
- }
68
+ ```text
69
+ inspect target=run:test view=recipe
70
+ inspect target=run:test view=trace source=lifecycle lines=40
71
+ inspect target=run:test view=control
72
+ inspect target=runtime view=status
73
+ inspect target=recipes view=status
74
+ inspect target=tool:my_tool view=status
118
75
  ```
119
76
 
120
- Routing comes from `to`, actor ownership, and runtime policy. `type` describes intent. Recipes should expose semantic message types instead of transport knobs.
77
+ A Run exposes exactly `recipe`, `trace`, and `control` views.
121
78
 
122
- ## Feature showcase
79
+ ### `register_tool`
123
80
 
124
- | Surface | What it gives you | Typical move |
125
- | --- | --- | --- |
126
- | Command templates | Portable command graphs with placeholders, defaults, guards, retries, parallel nodes, recovery, and timeouts | Wrap a trusted local executable without writing a bespoke tool |
127
- | Recipes | JSON/Markdown capability specs with metadata, args, defaults, imports, mailbox contracts, artifacts, and async mode | Save a known-good local workflow as reusable muscle memory |
128
- | Async runs | File-backed detached lifecycle, logs, progress, output, cancellation, artifacts, and durable terminal follow-up notifications | Let model work, media jobs, services, or pipelines continue after the turn |
129
- | Message protocol | Typed envelopes across run, tool, branch, room, coordinator, and session targets | Continue, approve, kill, or route work without restarting actors |
130
- | Rooms and rosters | Run-local group timeline with actor join/leave, contacts, previews, and branch-aware delivery | Coordinate multiple subagents under one visible run |
131
- | Registry and recipe doctor | Discovered tools, overrides, drafts, invalid recipes, and advisory risk labels | Audit local capability memory before using or promoting it |
132
- | Draft promotion | Captured ad hoc spawn patterns can become explicit recipes through one operator-selected promotion or bounded automatic unchanged-source review | Turn successful improvisation into durable local tools without granting a reviewer executable-authoring authority |
133
- | Review/swarm recipes | Maintained packaged pipelines with preflight, marked semantic evidence, quorum knobs, model/thinking inheritance, one-turn prompt-file transport, and diagnostics | Delegate reviews without rebuilding fanout commands |
134
- | Actor inspector | One manual `Recipe → Messages or Turns → timeline → one detail level` overlay for owned actor evidence, plus confirmed `K` → `control.kill` for the selected running run | Understand the selected recipe and launch, follow actor traffic and persisted subagent turns, or explicitly terminate one owned actor without exposing another session or signaling directly |
135
- | Packaged recipe QA | Installed-package-safe checks for helper paths, mailbox contracts, platform scope, artifacts, and recipe structure | Keep shipped actor components executable and diagnosable |
81
+ Persist a trusted command template or Recipe-backed capability under `~/.pi/agent/recipes`. Registration remains separate from running Control.
136
82
 
137
- Detached actors survive ordinary agent turns. When their owning Pi session quits, reloads, or is replaced, pi-actors scans run state without the ordinary index depth cap and attempts canonical `control.kill` for each readable still-running exact-owner run. Destructive control is fenced by immutable run generation and serialized against state-directory restart; terminal, ambiguous, changed-generation, and other-session runs remain untouched. Unreadable/corrupt state becomes an explicit failure and every shutdown writes a bounded summary under the run root; actors owned by descendant Pi sessions remain outside the exact-owner contract and require their own shutdown hook or manual OS recovery.
83
+ ## Recipe
138
84
 
139
- ## Golden path: from local workflow to actor memory
85
+ Recipes can declare:
140
86
 
141
- Create a reusable async actor recipe in the user recipe root:
87
+ - args and typed defaults;
88
+ - imports and command-template composition;
89
+ - retry, failure, recovery, repeat, concurrency, and timeout policy;
90
+ - artifact paths;
91
+ - `control: ["action"]` only for inputs a service actually consumes.
142
92
 
143
- ```bash
144
- mkdir -p ~/.pi/agent/recipes
93
+ Example controlled Recipe:
145
94
 
146
- cat > ~/.pi/agent/recipes/docs_review.json <<'JSON'
95
+ ```json
147
96
  {
148
- "description": "Start an async docs review actor",
149
97
  "async": true,
150
- "args": ["scope:path", "model:string", "thinking:string"],
151
- "defaults": { "model": "{current_model}", "thinking": "{current_thinking}" },
152
- "mailbox": {
153
- "accepts": ["control.kill", "control.continue"],
154
- "emits": ["review.completed", "run.failed"]
155
- },
156
- "template": "pi -p --model {model} --thinking {thinking} --no-tools \"Review {scope} for unclear actor-runtime onboarding. Return concise findings.\""
98
+ "control": ["pause", "resume", "stop"],
99
+ "artifacts": { "state": "{state_dir}/player-state.json" },
100
+ "template": "{repo}/scripts/player.mjs --state-dir {state_dir}"
157
101
  }
158
- JSON
159
102
  ```
160
103
 
161
- Because it lives under `~/.pi/agent/recipes/`, the filename becomes the tool id. `{current_model}` and `{current_thinking}` inherit the active Pi session policy; pass explicit values only when a run should intentionally diverge.
104
+ Ordinary one-shot Recipes should omit `control`. Recipe imports compose definitions inside one Run; they do not create peer actors.
162
105
 
163
- Run it:
106
+ String command-template leaves execute directly without shell interpretation. Use template arrays for sequencing or an explicit trusted shell/script when shell semantics matter.
164
107
 
165
- ```text
166
- docs_review scope="README.md" run_id=docs_review
167
- ```
108
+ ## Trace
168
109
 
169
- Inspect it:
110
+ `trace.jsonl` contains bounded structured observations:
170
111
 
171
- ```text
172
- inspect target=tool:pi-actors view=triage
173
- inspect target=run:docs_review view=status
174
- inspect target=run:docs_review view=tail lines=80
175
- inspect target=run:docs_review view=messages
176
- inspect target=run:docs_review view=mailbox
112
+ ```json
113
+ {
114
+ "id": "cfd0…",
115
+ "ts": "2026-01-01T00:00:00.000Z",
116
+ "kind": "progress.update",
117
+ "summary": "Indexed 40 files",
118
+ "data": { "files": 40 },
119
+ "level": "info",
120
+ "attention": "notify"
121
+ }
177
122
  ```
178
123
 
179
- Steer it:
124
+ Trace fields are exact: `id`, `ts`, `kind`, and optional `summary`, `data`, `level`, `attention`. Address, sender, recipient, reply, and routing fields fail validation. The canonical append authority validates and size-checks under a cross-process mutation lock before one append-only JSONL write; first-party scripts never append this file directly.
180
125
 
181
- ```text
182
- message to=run:docs_review type=control.continue body=continue
183
- message to=run:docs_review type=control.kill body=stop
184
- ```
185
-
186
- ## Recipe memory model
126
+ Use `attention: "notify"` for visible status and `attention: "followup"` only when the coordinator needs semantic follow-up context. Store large evidence in artifacts or bounded execution captures.
187
127
 
188
- The persistent tool surface is location-derived:
128
+ ## Control
189
129
 
190
- ```text
191
- ~/.pi/agent/recipes/*.json
192
- ~/.pi/agent/recipes/*.md
193
- ```
130
+ Controls persist to `controls.jsonl` before transport. Token-owned dead-process-reclaiming locks serialize atomic journal replacements. Every record carries the immutable `run_instance_id`; expected-status fencing advances outcomes monotonically through queued/delivered/claimed/handled/failed evidence, while a fast consumer may claim or handle before the sender adds independent delivery-time evidence.
194
131
 
195
- Rules:
132
+ Long-lived services publish `control-endpoint.json` only when ready:
196
133
 
197
- - User recipes in `~/.pi/agent/recipes/` are tools by location.
198
- - Recipe filenames define tool ids.
199
- - User recipes override same-name lower-priority recipes.
200
- - Same-id JSON recipes shadow Markdown recipes in the same priority layer.
201
- - Packaged recipes are standard-library components, not automatically installed operator policy.
202
- - Draft recipes in `~/.pi/agent/recipes/drafts/` are replayable memory, not active tools.
203
- - `register_tool` creates, updates, lists, deletes, or explicitly promotes one draft recipe file through the normal agent interface.
204
- - Batch draft consolidation is automatic and silent. Prefer fenced `register_tool draft=...` for one early promotion; deliberate move/copy into the recipe root remains valid but may defer an already captured batch.
205
-
206
- Register a foreground tool:
207
-
208
- ```text
209
- register_tool name=transcribe_audio \
210
- description="Transcribe a local audio file" \
211
- template="~/bin/transcribe {file:path} {lang=ru} {model:string}"
134
+ ```json
135
+ {
136
+ "path": "/path/to/control.fifo",
137
+ "type": "fifo",
138
+ "ready_at": "2026-01-01T00:00:00.000Z",
139
+ "run_instance_id": "generation-id"
140
+ }
212
141
  ```
213
142
 
214
- Register a recipe-backed tool:
143
+ Supported transports are Unix FIFO and Windows named pipe. Every actor-local Control uses the same portable envelope: action is at most 64 lowercase ASCII characters, serialized JSON input is at most 380 bytes, and the newline-terminated wire record is at most 512 bytes. Put larger data in a declared artifact/path and send only its bounded reference or instruction through Control. Delivery revalidates owner, generation, state, and process identity under the canonical lifecycle lock.
215
144
 
216
- ```text
217
- register_tool name=docs_review \
218
- description="Start an async docs review actor" \
219
- template="docs_review" \
220
- args="scope:path,model:string"
221
- ```
145
+ ## Run State
222
146
 
223
- Promote a captured draft only after explicit operator approval:
147
+ Owned state lives under:
224
148
 
225
149
  ```text
226
- register_tool name=docs_review draft=~/.pi/agent/recipes/drafts/spawned-run.json
150
+ ~/.pi/agent/tmp/pi-actors/runs/<run>/
227
151
  ```
228
152
 
229
- Successful inline spawns accumulate draft memory automatically. When twelve drafts exist, pi-actors waits for the foreground turn and active actors to finish, captures an exact immutable batch, and attaches a value-free structural projection to a silent reviewer with no tools. The projection replaces canonical names, draft basenames, and raw hashes with batch-local opaque occurrence IDs and equality-only content groups, and omits recipe bodies, template text, defaults, authored prose, and filesystem paths; the reviewer selects one quota-free `promote` or `discard` decision per source but cannot return recipe content. The executor derives every promotion from the exact captured source, applies the batch through its journaled transaction, garbage-collects discarded drafts, and leaves newer drafts for the next cycle.
153
+ Core files:
230
154
 
231
- Automatic review and mutation remain separate trust boundaries: reviewers receive only value-free structural/usage evidence and have neither filesystem tools, raw recipe access, mutation tools, nor executable-authoring authority. Active-tool portfolio review excludes recipes detected as sensitive and can only select `keep`, unchanged-source rename (`evolve`), unchanged-source `demote`, or deduplication of canonically identical recipes (`merge`). `replace`, `split`, and any executable contract change require an explicit operator-authored recipe mutation through the existing recipe/register surface. Deterministic executors revalidate the exact batch, source and target hashes, complete captured recipes, quarantine state, and journals before committing or recovering internally. The runtime exposes no separate manual batch command.
155
+ - `run.json` — identity, owner, generation, captured Recipe, policy, process identity;
156
+ - `trace.jsonl` — structured observations;
157
+ - `controls.jsonl` — durable Controls and outcomes;
158
+ - `control-endpoint.json` — generation-fenced service readiness;
159
+ - `execution.json` — command/session provenance and complete-capture references;
160
+ - `result.json`, command logs, progress, and declared artifacts.
232
161
 
233
- Inspect the registry:
162
+ The runtime preserves owner filtering, process-identity verification, lifecycle locking, shutdown kill, terminal reconciliation, bounded captures, owned Pi sessions, path containment, and redaction.
234
163
 
235
- ```text
236
- inspect target=recipes view=status
237
- inspect target=recipes view=reviews
238
- inspect target=recipes view=summary verbose=true
239
- inspect target=tool:pi-actors view=triage
240
- ```
164
+ ## Actor Inspector
241
165
 
242
- Failed automatic cycles retain a bounded failed stage, error, retry count, and exact next action. Retry the same immutable scope through the reserved runtime actor; reset only disposable failed/completed admission state:
166
+ Open the owner-filtered TUI:
243
167
 
244
168
  ```text
245
- message to=tool:pi-actors type=review.retry body={"scope":"draft"}
246
- message to=tool:pi-actors type=review.retry body={"scope":"tool"}
247
- message to=tool:pi-actors type=review.reset body={"scope":"draft"}
169
+ /actor-inspector
248
170
  ```
249
171
 
250
- Draft retry with an existing transaction journal resumes the original reviewer run and uses the journal’s authenticated decisions for lineage/evidence; it never launches a second reviewer over already-committed filesystem state. Tool review recovery that already has approved/transaction evidence cannot be reset; retry preserves that evidence and may require `/reload` for the safe `session_start` activation boundary.
251
-
252
- ## Command templates
253
-
254
- A command template is the launch substrate. It can be a string, a sequence, or a composed graph.
255
-
256
- Templates support:
257
-
258
- - Named placeholders such as `{file}`, `{model}`, `{prompt}`;
259
- - Compact types such as `string`, `path`, `int`, `number`, `bool`, `enum(a,b)`;
260
- - Defaults such as `{lang=ru}` and `{dry_run:bool=true}`;
261
- - Fallback and small ternary forms;
262
- - Sequences with stdin flow;
263
- - Parallel nodes;
264
- - Retries, recovery, failure policy, delays, guards, and timeouts;
265
- - Async run values such as `{run_id}`, `{state_dir}`, `{actor_address}`, `{default_room}`, and `{communication_file}`.
266
-
267
- The template owns execution shape. The recipe owns saved metadata, defaults, imports, mailbox, artifacts, and async launch policy. The run actor owns detached lifecycle, state, messages, cancellation, and inspection.
268
-
269
- ## Packaged recipe library
270
-
271
- Packaged recipes live under `recipes/` and helper scripts live under `scripts/`.
272
-
273
- The library includes:
172
+ It presents actor instances through Recipe, Trace, and Control tabs, with source filtering, detail navigation, refresh, and generation-fenced Run kill.
274
173
 
275
- - Subagent launchers;
276
- - Review, critic, planner, verifier, merger, judge, normalizer, and artifact atoms;
277
- - Quorum and lens-style pipelines;
278
- - Repo-health, release-summary, research-synthesis, development-tasking, docs-maintenance, and room-swarm pipelines;
279
- - Coordinator-locker and actor-message utilities;
280
- - Local music-player actor recipe.
174
+ ## Packaged Recipes
281
175
 
282
- Packaged recipes are building blocks. Use `spawn file=<recipe>` for maintained packaged pipelines before rebuilding equivalent shell commands. Copy or wrap them into `~/.pi/agent/recipes/` only when they should become durable operator-facing tools.
176
+ Useful entry points include:
283
177
 
284
- ## Choosing the right surface
178
+ - `pipeline-repo-health`
179
+ - `pipeline-quorum-review`
180
+ - `pipeline-artifact-bundle`
181
+ - `music-player` — controlled playback service
182
+ - `resource-locker` — optional controlled resource-lock service
285
183
 
286
- | If the work is... | Prefer... |
287
- | --- | --- |
288
- | Short, bounded, and foreground | Ordinary tools or registered foreground tools |
289
- | Long-running, service-like, parallel, agentic, artifact-producing, or controllable | `spawn` / async recipe |
290
- | Already running and needs new input | `message` |
291
- | Unclear, failing, or ready for a decision | `inspect` |
292
- | A multi-actor collaboration under one run | `room:<run>` plus branch addresses |
293
- | A useful output that should survive context compression | Artifacts |
294
- | A repeated local workflow | Recipe/tool memory |
184
+ Validate Recipes with:
295
185
 
296
- Terminal completion queues a minimal follow-up with run id, status, one base path, and relative artifact names only. Bounded semantic output, launch/tool-call correlation, and optional transport context remain in non-LLM follow-up details and run state, so adapters retain the exact launch/result relationship without injecting actor output into coordinator context. Inspect the run before deciding whether a successful pattern deserves recipe persistence; never auto-save without the operator's confirmation.
297
-
298
- ## Platform support
299
-
300
- Core actor state, inspection, foreground tools, and basic async runs are portable Node.js behavior. Run-local messaging and stop/kill use platform adapters under the same `message` API.
301
-
302
- | Surface | Linux/macOS/WSL | Native Windows |
303
- | --- | --- | --- |
304
- | Foreground tools, recipe discovery, inspect | Supported | Supported |
305
- | Async runs and file-backed state | Supported | Supported |
306
- | Mailbox-only actors and worker recipe | Supported | Supported |
307
- | FIFO control endpoints | Supported | Not supported; use mailbox or named pipe |
308
- | Named-pipe control endpoints | Not needed | Supported when recipe exposes one |
309
- | Process cancel/kill | Process group signal with pid fallback | Windows process-tree adapter |
310
-
311
- Packaged recipes should prefer mailbox/wake behavior for portable control. Recipes that require FIFO, Unix shell tools, or platform-specific media backends should make that limitation visible in docs or diagnostics before launch.
312
-
313
- ## Safety boundary
314
-
315
- `pi-actors` is local-first, not sandbox-first.
316
-
317
- Commands execute directly without shell evaluation where possible, but trusted executables still run with the same system permissions as Pi. Only register commands, scripts, recipes, and paths you trust.
318
-
319
- High-risk templates such as shells, interpreter eval modes, network access, external side effects, and broad filesystem mutation may surface warnings, but the runtime is not a security boundary. Automatic reviewers cannot author or change executable contracts: they receive attached immutable evidence with no tools and may only select unchanged-source lifecycle/name operations. Disable all automatic draft/tool review and safe-boundary activation before starting Pi with `PI_ACTORS_AUTOMATIC_REVIEW=off`; `inspect target=tool:pi-actors view=status` reports `automatic_review=false`.
320
-
321
- Prefer:
322
-
323
- - Narrow commands;
324
- - Explicit paths;
325
- - Typed args;
326
- - Bounded timeouts for bounded work;
327
- - Explicit tool allowlists for subagents;
328
- - Deterministic utility recipes for filesystem writes;
329
- - Human approval for destructive or external side effects.
330
-
331
- ## Non-goals
332
-
333
- `pi-actors` is not:
334
-
335
- - A generic workflow DSL;
336
- - A remote agent interoperability protocol;
337
- - A heavyweight broker;
338
- - A sandbox;
339
- - A facade that hides logs, artifacts, ownership, or local side effects;
340
- - A polling-first async runner.
341
-
342
- Its job is narrower: make trusted local capabilities addressable, messageable, inspectable, and reusable by agents.
343
-
344
- ## Documentation
186
+ ```bash
187
+ npm run recipes:qa
188
+ ```
345
189
 
346
- Start here:
190
+ ## Development
347
191
 
348
- - [Project context](./AGENTS.md)
349
- - [Changelog](./CHANGELOG.md)
350
- - [Open backlog](./BACKLOG.md)
351
- - [Documentation index](./docs/README.md)
352
- - [Actors skill](./skills/actors/SKILL.md)
353
- - [Swarm skill](./skills/swarm/SKILL.md)
192
+ ```bash
193
+ npm install
194
+ npm run build
195
+ npm test
196
+ npm run validate
197
+ npm run test:preservation
198
+ ```
354
199
 
355
- Core docs:
200
+ See the [documentation index](./docs/README.md), [Run lifecycle](./docs/async-runs.md), [Recipe library](./docs/recipe-library.md), and [0.43 baseline](./docs/0.43-baseline.md).
356
201
 
357
- - [Command templates](./docs/command-templates.md)
358
- - [Template recipes](./docs/template-recipes.md)
359
- - [Async runs](./docs/async-runs.md)
360
- - [Actor messages](./docs/actor-messages.md)
361
- - [Actor inspector](./docs/actor-inspector.md)
362
- - [Tool registry](./docs/tool-registry.md)
363
- - [Recipe library](./docs/recipe-library.md)
202
+ Project context: [AGENTS.md](./AGENTS.md) · [BACKLOG.md](./BACKLOG.md) · [CHANGELOG.md](./CHANGELOG.md).
364
203
 
365
204
  ## License
366
205
 
@@ -0,0 +1,6 @@
1
+ {
2
+ "path": "named-pipe-example",
3
+ "type": "named-pipe",
4
+ "ready_at": "2026-01-01T00:00:00.000Z",
5
+ "run_instance_id": "generation-1"
6
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "control-1",
3
+ "run_instance_id": "generation-1",
4
+ "action": "pause",
5
+ "input": { "reason": "operator" },
6
+ "status": "handled",
7
+ "queued_at": "2026-01-01T00:00:00.000Z",
8
+ "handled_at": "2026-01-01T00:00:01.000Z"
9
+ }
@@ -1,16 +1,8 @@
1
1
  {
2
- "id": "actor-worker",
3
- "path": "recipes/actor-worker.json",
2
+ "id": "music-player",
3
+ "path": "recipes/music-player.json",
4
4
  "location": "packaged",
5
5
  "active": true,
6
- "args": [
7
- "run",
8
- "branch",
9
- "poll_ms",
10
- "state_dir"
11
- ],
12
- "mailbox": {
13
- "kind": "branch",
14
- "accepts": ["task.assign", "control.stop"]
15
- }
6
+ "args": ["repo", "command", "source", "loop", "volume", "player", "state_dir"],
7
+ "control": ["play", "pause", "resume", "toggle", "next", "previous", "stop", "status"]
16
8
  }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "trace-1",
3
+ "ts": "2026-01-01T00:00:00.000Z",
4
+ "kind": "progress.update",
5
+ "summary": "Work progressed",
6
+ "data": { "completed": 1 },
7
+ "level": "info",
8
+ "attention": "notify"
9
+ }
package/dist/index.js CHANGED
@@ -106,7 +106,7 @@ export default function toolRegistryExtension(pi) {
106
106
  configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
107
107
  getActiveTools: () => pi.getActiveTools(),
108
108
  getRuntimeTool: (name) => Tools.resolveActiveRuntimeTool(name, runtime.getTools(), (activeName) => actorToolDefinitions.get(activeName)),
109
- handleRuntimeMessage: automaticReview.handleMessage,
109
+ handleRuntimeControl: automaticReview.handleControl,
110
110
  registryRuntime: runtime,
111
111
  setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
112
112
  }).map(withCurrentThinkingContext));