@llblab/pi-actors 0.45.1 → 0.46.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 (228) hide show
  1. package/AGENTS.md +9 -7
  2. package/BACKLOG.md +582 -0
  3. package/CHANGELOG.md +17 -1
  4. package/README.md +27 -13
  5. package/dist/fixtures/protocol/recipe-summary.json +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/lib/async-runs.d.ts +5 -1
  8. package/dist/lib/async-runs.js +26 -24
  9. package/dist/lib/automatic-review-runtime.d.ts +2 -0
  10. package/dist/lib/automatic-review-runtime.js +12 -5
  11. package/dist/lib/draft-sleep.js +0 -1
  12. package/dist/lib/execution.d.ts +1 -0
  13. package/dist/lib/execution.js +1 -0
  14. package/dist/lib/extension-runtime.d.ts +1 -1
  15. package/dist/lib/extension-runtime.js +26 -4
  16. package/dist/lib/inspector.js +46 -7
  17. package/dist/lib/paths.d.ts +0 -1
  18. package/dist/lib/paths.js +0 -7
  19. package/dist/lib/prompts.d.ts +1 -1
  20. package/dist/lib/prompts.js +4 -4
  21. package/dist/lib/recipes-context.d.ts +12 -3
  22. package/dist/lib/recipes-context.js +30 -6
  23. package/dist/lib/recipes-discovery.d.ts +18 -0
  24. package/dist/lib/recipes-discovery.js +95 -22
  25. package/dist/lib/recipes-references.d.ts +42 -9
  26. package/dist/lib/recipes-references.js +248 -135
  27. package/dist/lib/registry.d.ts +14 -1
  28. package/dist/lib/registry.js +110 -87
  29. package/dist/lib/runtime.d.ts +30 -4
  30. package/dist/lib/runtime.js +74 -12
  31. package/dist/lib/tools-inspect.d.ts +3 -1
  32. package/dist/lib/tools-inspect.js +56 -9
  33. package/dist/lib/tools-local.d.ts +2 -0
  34. package/dist/lib/tools-local.js +5 -2
  35. package/dist/lib/tools-response.js +2 -0
  36. package/dist/lib/tools-spawn.d.ts +2 -0
  37. package/dist/lib/tools-spawn.js +24 -52
  38. package/dist/lib/tools.d.ts +4 -1
  39. package/dist/lib/tools.js +2 -0
  40. package/dist/scripts/build-dist.mjs +13 -4
  41. package/dist/skills/actors/SKILL.md +8 -8
  42. package/dist/skills/actors/recipes/recipe-validate.json +11 -0
  43. package/{recipes/utility-coordinator-lock-snapshot.json → dist/skills/actors/recipes/resource-locker-snapshot.json} +1 -3
  44. package/dist/{recipes → skills/actors/recipes}/resource-locker.json +1 -3
  45. package/dist/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json} +1 -3
  46. package/dist/skills/actors/recipes/run-summary.json +9 -0
  47. package/dist/{scripts/locker.mjs → skills/actors/scripts/resource-locker.mjs} +2 -2
  48. package/dist/skills/actors/scripts/run-utils.mjs +164 -0
  49. package/{scripts → dist/skills/actors/scripts}/validate-recipe.mjs +134 -17
  50. package/dist/skills/artifacts/SKILL.md +16 -0
  51. package/{recipes/pipeline-artifact-bundle.json → dist/skills/artifacts/recipes/bundle.json} +4 -4
  52. package/dist/{recipes/utility-artifact-write.json → skills/artifacts/recipes/file-write.json} +1 -3
  53. package/dist/{recipes/utility-artifact-manifest.json → skills/artifacts/recipes/manifest.json} +1 -3
  54. package/{recipes/pipeline-artifact-report.json → dist/skills/artifacts/recipes/report.json} +2 -2
  55. package/dist/{recipes/pipeline-artifact-write.json → skills/artifacts/recipes/write.json} +3 -3
  56. package/dist/skills/artifacts/scripts/artifact-utils.mjs +63 -0
  57. package/dist/skills/media/SKILL.md +16 -0
  58. package/dist/{recipes/pipeline-media-library.json → skills/media/recipes/library.json} +2 -2
  59. package/{recipes/music-player.json → dist/skills/media/recipes/player.json} +1 -3
  60. package/dist/{recipes/utility-playlist-build.json → skills/media/recipes/playlist-build.json} +1 -3
  61. package/dist/skills/media/scripts/media-utils.mjs +47 -0
  62. package/dist/{scripts → skills/media/scripts}/music-player.mjs +9 -3
  63. package/dist/skills/project-work/SKILL.md +16 -0
  64. package/dist/skills/project-work/recipes/changelog-section.json +11 -0
  65. package/{recipes/pipeline-docs-maintenance.json → dist/skills/project-work/recipes/docs-maintenance.json} +4 -4
  66. package/dist/skills/project-work/recipes/package-summary.json +9 -0
  67. package/{recipes/pipeline-release-readiness.json → dist/skills/project-work/recipes/release-readiness.json} +6 -6
  68. package/dist/{recipes/pipeline-release-summary.json → skills/project-work/recipes/release-summary.json} +5 -5
  69. package/{recipes/pipeline-repo-health.json → dist/skills/project-work/recipes/repo-health.json} +6 -6
  70. package/{recipes/pipeline-async-run-ops.json → dist/skills/project-work/recipes/run-ops.json} +3 -3
  71. package/dist/skills/project-work/recipes/skill-summary.json +11 -0
  72. package/dist/skills/project-work/scripts/project-utils.mjs +89 -0
  73. package/dist/skills/recipe-memory/SKILL.md +16 -0
  74. package/dist/skills/swarm/SKILL.md +4 -4
  75. package/{recipes/pipeline-architect-coordinator.json → dist/skills/swarm/recipes/architect.json} +5 -5
  76. package/{recipes/pipeline-checkpoint-continuation.json → dist/skills/swarm/recipes/checkpoint-continuation.json} +3 -3
  77. package/dist/{recipes/pipeline-development-tasking.json → skills/swarm/recipes/development-tasking.json} +4 -4
  78. package/dist/{recipes/lens-swarm.json → skills/swarm/recipes/lens-review.json} +1 -1
  79. package/dist/{recipes/pipeline-quorum-review.json → skills/swarm/recipes/quorum-review.json} +4 -4
  80. package/{recipes/pipeline-research-synthesis.json → dist/skills/swarm/recipes/research-synthesis.json} +6 -6
  81. package/{recipes/pipeline-review-readiness.json → dist/skills/swarm/recipes/review-readiness.json} +1 -1
  82. package/{recipes/subagents-prompts.json → dist/skills/swarm/recipes/subagent-prompts.json} +1 -1
  83. package/{recipes → dist/skills/swarm/recipes}/subagent-quorum.json +1 -1
  84. package/dist/{recipes → skills/swarm/recipes}/subagent-review-coordinator.json +6 -6
  85. package/docs/actor-inspector.md +4 -3
  86. package/docs/async-runs.md +2 -2
  87. package/docs/recipe-library.md +23 -23
  88. package/docs/releasing.md +2 -2
  89. package/docs/template-recipes.md +32 -14
  90. package/docs/tool-registry.md +10 -4
  91. package/fixtures/protocol/recipe-summary.json +1 -1
  92. package/index.ts +2 -1
  93. package/lib/async-runs.ts +52 -25
  94. package/lib/automatic-review-runtime.ts +16 -3
  95. package/lib/draft-sleep.ts +0 -1
  96. package/lib/execution.ts +2 -0
  97. package/lib/extension-runtime.ts +42 -4
  98. package/lib/inspector.ts +57 -11
  99. package/lib/paths.ts +0 -7
  100. package/lib/prompts.ts +4 -4
  101. package/lib/recipes-context.ts +51 -6
  102. package/lib/recipes-discovery.ts +164 -24
  103. package/lib/recipes-references.ts +359 -146
  104. package/lib/registry.ts +185 -94
  105. package/lib/runtime.ts +109 -17
  106. package/lib/tools-inspect.ts +77 -10
  107. package/lib/tools-local.ts +9 -1
  108. package/lib/tools-response.ts +2 -0
  109. package/lib/tools-spawn.ts +38 -74
  110. package/lib/tools.ts +4 -1
  111. package/package.json +2 -4
  112. package/scripts/build-dist.mjs +13 -4
  113. package/skills/actors/SKILL.md +8 -8
  114. package/skills/actors/recipes/recipe-validate.json +11 -0
  115. package/{dist/recipes/utility-coordinator-lock-snapshot.json → skills/actors/recipes/resource-locker-snapshot.json} +1 -3
  116. package/{recipes → skills/actors/recipes}/resource-locker.json +1 -3
  117. package/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json} +1 -3
  118. package/skills/actors/recipes/run-summary.json +9 -0
  119. package/{scripts/locker.mjs → skills/actors/scripts/resource-locker.mjs} +2 -2
  120. package/skills/actors/scripts/run-utils.mjs +164 -0
  121. package/{dist → skills/actors}/scripts/validate-recipe.mjs +134 -17
  122. package/skills/artifacts/SKILL.md +16 -0
  123. package/{dist/recipes/pipeline-artifact-bundle.json → skills/artifacts/recipes/bundle.json} +4 -4
  124. package/{recipes/utility-artifact-write.json → skills/artifacts/recipes/file-write.json} +1 -3
  125. package/{recipes/utility-artifact-manifest.json → skills/artifacts/recipes/manifest.json} +1 -3
  126. package/{dist/recipes/pipeline-artifact-report.json → skills/artifacts/recipes/report.json} +2 -2
  127. package/{recipes/pipeline-artifact-write.json → skills/artifacts/recipes/write.json} +3 -3
  128. package/skills/artifacts/scripts/artifact-utils.mjs +63 -0
  129. package/skills/media/SKILL.md +16 -0
  130. package/{recipes/pipeline-media-library.json → skills/media/recipes/library.json} +2 -2
  131. package/{dist/recipes/music-player.json → skills/media/recipes/player.json} +1 -3
  132. package/{recipes/utility-playlist-build.json → skills/media/recipes/playlist-build.json} +1 -3
  133. package/skills/media/scripts/media-utils.mjs +47 -0
  134. package/{scripts → skills/media/scripts}/music-player.mjs +9 -3
  135. package/skills/project-work/SKILL.md +16 -0
  136. package/skills/project-work/recipes/changelog-section.json +11 -0
  137. package/{dist/recipes/pipeline-docs-maintenance.json → skills/project-work/recipes/docs-maintenance.json} +4 -4
  138. package/skills/project-work/recipes/package-summary.json +9 -0
  139. package/{dist/recipes/pipeline-release-readiness.json → skills/project-work/recipes/release-readiness.json} +6 -6
  140. package/{recipes/pipeline-release-summary.json → skills/project-work/recipes/release-summary.json} +5 -5
  141. package/{dist/recipes/pipeline-repo-health.json → skills/project-work/recipes/repo-health.json} +6 -6
  142. package/{dist/recipes/pipeline-async-run-ops.json → skills/project-work/recipes/run-ops.json} +3 -3
  143. package/skills/project-work/recipes/skill-summary.json +11 -0
  144. package/skills/project-work/scripts/project-utils.mjs +89 -0
  145. package/skills/recipe-memory/SKILL.md +16 -0
  146. package/skills/swarm/SKILL.md +4 -4
  147. package/{dist/recipes/pipeline-architect-coordinator.json → skills/swarm/recipes/architect.json} +5 -5
  148. package/{dist/recipes/pipeline-checkpoint-continuation.json → skills/swarm/recipes/checkpoint-continuation.json} +3 -3
  149. package/{recipes/pipeline-development-tasking.json → skills/swarm/recipes/development-tasking.json} +4 -4
  150. package/{recipes/lens-swarm.json → skills/swarm/recipes/lens-review.json} +1 -1
  151. package/{recipes/pipeline-quorum-review.json → skills/swarm/recipes/quorum-review.json} +4 -4
  152. package/{dist/recipes/pipeline-research-synthesis.json → skills/swarm/recipes/research-synthesis.json} +6 -6
  153. package/{dist/recipes/pipeline-review-readiness.json → skills/swarm/recipes/review-readiness.json} +1 -1
  154. package/{dist/recipes/subagents-prompts.json → skills/swarm/recipes/subagent-prompts.json} +1 -1
  155. package/{dist → skills/swarm}/recipes/subagent-quorum.json +1 -1
  156. package/{recipes → skills/swarm/recipes}/subagent-review-coordinator.json +6 -6
  157. package/dist/recipes/utility-changelog-section.json +0 -13
  158. package/dist/recipes/utility-package-summary.json +0 -11
  159. package/dist/recipes/utility-run-summary.json +0 -11
  160. package/dist/recipes/utility-skill-summary.json +0 -13
  161. package/dist/recipes/utility-validate-recipe.json +0 -13
  162. package/dist/scripts/executable-block-style.d.mts +0 -1
  163. package/dist/scripts/executable-block-style.mjs +0 -73
  164. package/dist/scripts/recipe-utils.mjs +0 -404
  165. package/dist/scripts/release-gates.mjs +0 -281
  166. package/recipes/utility-changelog-section.json +0 -13
  167. package/recipes/utility-package-summary.json +0 -11
  168. package/recipes/utility-run-summary.json +0 -11
  169. package/recipes/utility-skill-summary.json +0 -13
  170. package/recipes/utility-validate-recipe.json +0 -13
  171. package/scripts/executable-block-style.d.mts +0 -1
  172. package/scripts/executable-block-style.mjs +0 -73
  173. package/scripts/recipe-utils.mjs +0 -404
  174. package/scripts/release-gates.mjs +0 -281
  175. /package/dist/{recipes/utility-validation-wrapper.json → skills/actors/recipes/command-validate.json} +0 -0
  176. /package/dist/{recipes/utility-jsonl-tail.json → skills/actors/recipes/jsonl-tail.json} +0 -0
  177. /package/dist/{recipes/utility-run-state-files.json → skills/actors/recipes/run-state-files.json} +0 -0
  178. /package/dist/{recipes/utility-playlist-scan.json → skills/media/recipes/playlist-scan.json} +0 -0
  179. /package/dist/{recipes/utility-changelog-head.json → skills/project-work/recipes/changelog-head.json} +0 -0
  180. /package/dist/{recipes/utility-git-log.json → skills/project-work/recipes/git-log.json} +0 -0
  181. /package/dist/{recipes/utility-git-status.json → skills/project-work/recipes/git-status.json} +0 -0
  182. /package/dist/{recipes/utility-markdown-index.json → skills/project-work/recipes/markdown-index.json} +0 -0
  183. /package/dist/{recipes → skills/recipe-memory/recipes}/draft-review.json +0 -0
  184. /package/dist/{recipes → skills/recipe-memory/recipes}/tool-review.json +0 -0
  185. /package/dist/{recipes → skills/swarm/recipes}/subagent-artifact.json +0 -0
  186. /package/dist/{recipes → skills/swarm/recipes}/subagent-checkpoint.json +0 -0
  187. /package/dist/{recipes → skills/swarm/recipes}/subagent-conflict-report.json +0 -0
  188. /package/dist/{recipes → skills/swarm/recipes}/subagent-contradiction-map.json +0 -0
  189. /package/dist/{recipes → skills/swarm/recipes}/subagent-critic.json +0 -0
  190. /package/dist/{recipes → skills/swarm/recipes}/subagent-evidence-map.json +0 -0
  191. /package/dist/{recipes → skills/swarm/recipes}/subagent-followup.json +0 -0
  192. /package/dist/{recipes → skills/swarm/recipes}/subagent-judge.json +0 -0
  193. /package/dist/{recipes → skills/swarm/recipes}/subagent-merge.json +0 -0
  194. /package/dist/{recipes → skills/swarm/recipes}/subagent-normalize.json +0 -0
  195. /package/dist/{recipes → skills/swarm/recipes}/subagent-plan.json +0 -0
  196. /package/dist/{recipes → skills/swarm/recipes}/subagent-preflight.json +0 -0
  197. /package/dist/{recipes → skills/swarm/recipes}/subagent-prompt.json +0 -0
  198. /package/dist/{recipes → skills/swarm/recipes}/subagent-review.json +0 -0
  199. /package/dist/{recipes → skills/swarm/recipes}/subagent-task-card.json +0 -0
  200. /package/dist/{recipes → skills/swarm/recipes}/subagent-tools.json +0 -0
  201. /package/dist/{recipes → skills/swarm/recipes}/subagent-verify.json +0 -0
  202. /package/{recipes/utility-validation-wrapper.json → skills/actors/recipes/command-validate.json} +0 -0
  203. /package/{recipes/utility-jsonl-tail.json → skills/actors/recipes/jsonl-tail.json} +0 -0
  204. /package/{recipes/utility-run-state-files.json → skills/actors/recipes/run-state-files.json} +0 -0
  205. /package/{recipes/utility-playlist-scan.json → skills/media/recipes/playlist-scan.json} +0 -0
  206. /package/{recipes/utility-changelog-head.json → skills/project-work/recipes/changelog-head.json} +0 -0
  207. /package/{recipes/utility-git-log.json → skills/project-work/recipes/git-log.json} +0 -0
  208. /package/{recipes/utility-git-status.json → skills/project-work/recipes/git-status.json} +0 -0
  209. /package/{recipes/utility-markdown-index.json → skills/project-work/recipes/markdown-index.json} +0 -0
  210. /package/{recipes → skills/recipe-memory/recipes}/draft-review.json +0 -0
  211. /package/{recipes → skills/recipe-memory/recipes}/tool-review.json +0 -0
  212. /package/{recipes → skills/swarm/recipes}/subagent-artifact.json +0 -0
  213. /package/{recipes → skills/swarm/recipes}/subagent-checkpoint.json +0 -0
  214. /package/{recipes → skills/swarm/recipes}/subagent-conflict-report.json +0 -0
  215. /package/{recipes → skills/swarm/recipes}/subagent-contradiction-map.json +0 -0
  216. /package/{recipes → skills/swarm/recipes}/subagent-critic.json +0 -0
  217. /package/{recipes → skills/swarm/recipes}/subagent-evidence-map.json +0 -0
  218. /package/{recipes → skills/swarm/recipes}/subagent-followup.json +0 -0
  219. /package/{recipes → skills/swarm/recipes}/subagent-judge.json +0 -0
  220. /package/{recipes → skills/swarm/recipes}/subagent-merge.json +0 -0
  221. /package/{recipes → skills/swarm/recipes}/subagent-normalize.json +0 -0
  222. /package/{recipes → skills/swarm/recipes}/subagent-plan.json +0 -0
  223. /package/{recipes → skills/swarm/recipes}/subagent-preflight.json +0 -0
  224. /package/{recipes → skills/swarm/recipes}/subagent-prompt.json +0 -0
  225. /package/{recipes → skills/swarm/recipes}/subagent-review.json +0 -0
  226. /package/{recipes → skills/swarm/recipes}/subagent-task-card.json +0 -0
  227. /package/{recipes → skills/swarm/recipes}/subagent-tools.json +0 -0
  228. /package/{recipes → skills/swarm/recipes}/subagent-verify.json +0 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ![pi-actors banner](https://raw.githubusercontent.com/llblab/pi-actors/main/banner.jpg)
4
4
 
5
- Local Run kernel and persistent tool registry for [Pi](https://github.com/badlogic/pi-mono).
5
+ Local Run kernel and persistent tool registry for [Pi](https://github.com/earendil-works/pi).
6
6
 
7
7
  ```text
8
8
  Recipe --spawn--> Run
@@ -23,17 +23,18 @@ For local development:
23
23
  pi install /path/to/pi-actors
24
24
  ```
25
25
 
26
- The package contributes the extension, packaged Recipes, and the `actors` and `swarm` skills.
26
+ The package contributes the extension and six capability-owning Skills for actors, artifacts, media, project work, Recipe memory, and swarm orchestration.
27
27
 
28
28
  ## Public Tools
29
29
 
30
30
  ### `spawn`
31
31
 
32
- Create a Run from a packaged/local Recipe or an inline command template:
32
+ Create a Run from an active-Skill Recipe, an explicit Recipe file, or an inline command template:
33
33
 
34
34
  ```text
35
35
  spawn template="sleep 30" as=run:demo
36
- spawn recipe=pipeline-repo-health values={"repo":"/work/project","model":"provider/model"}
36
+ spawn recipe=project-work/repo-health values={"repo":"/work/project","model":"provider/model"}
37
+ spawn recipe=media/player values={"source":"/music"} as=run:player
37
38
  spawn template="make test" as=run:test
38
39
  ```
39
40
 
@@ -80,7 +81,7 @@ A Run exposes exactly `recipe`, `trace`, and `control` views.
80
81
 
81
82
  ### `register_tool`
82
83
 
83
- Persist a trusted command template or Recipe-backed capability under `~/.pi/agent/recipes`. Registration remains separate from running Control.
84
+ Persist a trusted command template or Recipe-backed capability under `~/.pi/agent/recipes`. Registration remains separate from running Control. Treat it as callable in the current session only when the result reports `callable_now: true`; persistence, Recipe spawning, and registered-tool invocation are distinct states.
84
85
 
85
86
  ## Recipe
86
87
 
@@ -99,13 +100,25 @@ Example controlled Recipe:
99
100
  "async": true,
100
101
  "control": ["pause", "resume", "stop"],
101
102
  "artifacts": { "state": "{state_dir}/player-state.json" },
102
- "template": "{repo}/scripts/player.mjs --state-dir {state_dir}"
103
+ "template": "{skill_dir}/scripts/player.mjs --state-dir {state_dir}"
103
104
  }
104
105
  ```
105
106
 
106
107
  Ordinary one-shot Recipes should omit `control`. Recipe imports compose definitions inside one Run; they do not create peer actors.
107
108
 
108
- File-backed Recipes receive immutable `{recipe_dir}`; Recipes under a Pi-active Skill also receive `{skill_dir}`. Use `std:<recipe>` for an exact packaged component and `skill:<skill>/<recipe-path>` for an exact active-Skill component. Skill Recipes are namespaced reusable components and do not become tools automatically.
109
+ ```json
110
+ {
111
+ "imports": {
112
+ "report": "artifacts/report",
113
+ "review": "swarm/quorum-review"
114
+ },
115
+ "template": [{ "name": "report" }, { "name": "review" }]
116
+ }
117
+ ```
118
+
119
+ Skill Recipe identity is `<active Skill name>/<Recipe filename stem>`. Recipe files have no top-level `name`; the filename is identity. `SKILL.md` `name` remains Pi host metadata and matches the Skill directory—pi-actors adds no second Skill identity field.
120
+
121
+ References have two classes: exact active-Skill identities such as `project-work/repo-health`, and explicit `.json` / `.md` paths. Entry file paths resolve from invocation `cwd`; relative imports resolve from the importing Recipe's directory; absolute paths remain exact. File-backed Recipes receive immutable `{recipe_dir}` and Skill Recipes also receive `{skill_dir}`. Skill components never become tools automatically.
109
122
 
110
123
  String command-template leaves execute directly without shell interpretation. Use template arrays for sequencing or an explicit trusted shell/script when shell semantics matter.
111
124
 
@@ -175,15 +188,16 @@ Open the owner-filtered TUI:
175
188
 
176
189
  It presents actor instances through Recipe, Trace, and Control tabs, with source filtering, detail navigation, refresh, and generation-fenced Run kill.
177
190
 
178
- ## Packaged Recipes
191
+ ## Skill Recipes
179
192
 
180
193
  Useful entry points include:
181
194
 
182
- - `pipeline-repo-health`
183
- - `pipeline-quorum-review`
184
- - `pipeline-artifact-bundle`
185
- - `music-player` — controlled playback service
186
- - `resource-locker` — optional controlled resource-lock service
195
+ - `project-work/repo-health`
196
+ - `project-work/release-readiness`
197
+ - `swarm/quorum-review`
198
+ - `artifacts/bundle`
199
+ - `media/player` — controlled playback service
200
+ - `actors/resource-locker` — optional controlled resource-lock service
187
201
 
188
202
  Validate Recipes with:
189
203
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "music-player",
3
- "path": "recipes/music-player.json",
3
+ "path": "skills/media/recipes/player.json",
4
4
  "location": "packaged",
5
5
  "active": true,
6
6
  "args": ["repo", "command", "source", "loop", "volume", "player", "state_dir"],
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ export default function toolRegistryExtension(pi) {
11
11
  pi.on("session_start", async (_event, ctx) => runtime.onSessionStart(ctx));
12
12
  pi.on("agent_end", async (_event, ctx) => runtime.onAgentEnd(ctx));
13
13
  pi.on("session_shutdown", async (event, ctx) => runtime.onSessionShutdown(event.reason, ctx));
14
- pi.on("before_agent_start", async (event) => runtime.beforeAgentStart(event.systemPrompt, event.systemPromptOptions.skills ?? []));
14
+ pi.on("before_agent_start", async (event, ctx) => runtime.beforeAgentStart(event.systemPrompt, event.systemPromptOptions.skills ?? [], ctx));
15
15
  InspectorCommand.registerActorInspectorCommand(pi, runtime.getRunOwnerId);
16
16
  runtime.registerCoreTools();
17
17
  }
@@ -68,6 +68,7 @@ export interface AsyncRunMeta {
68
68
  argv: string[];
69
69
  createdAt: string;
70
70
  cwd: string;
71
+ launch_kind?: AsyncRunLaunchSource;
71
72
  launch_source?: AsyncRunLaunchSource;
72
73
  launch_correlation?: {
73
74
  correlation_id?: string;
@@ -98,7 +99,10 @@ export interface AsyncRunMeta {
98
99
  export { safeRunId } from "./runs-identity.ts";
99
100
  export { resolveArtifactManifest } from "./runs-artifacts.ts";
100
101
  export type { RunArtifactDeclaration, RunArtifactManifestEntry, } from "./runs-artifacts.ts";
101
- export declare function startRun(params: AsyncRunStartParams, cwd: string): AsyncRunMeta;
102
+ export interface AsyncRunStartOptions {
103
+ skillContext?: RecipesReferences.ActiveSkillRecipeContext;
104
+ }
105
+ export declare function startRun(params: AsyncRunStartParams, cwd: string, options?: AsyncRunStartOptions): AsyncRunMeta;
102
106
  export declare function getRunStatus(runOrDir: string): Record<string, unknown>;
103
107
  export type { RunStateIndexEntry } from "./runs-index.ts";
104
108
  export declare function listRunStateDirs(stateRoot?: string): string[];
@@ -105,10 +105,11 @@ function resolveStateDir(params, run) {
105
105
  function assertNoActiveRunState(stateDir) {
106
106
  RunsStart.assertNoActiveRunState(stateDir, readJson, RUNNER_PATH);
107
107
  }
108
- function resolveRecipeFile(file) {
109
- return (RecipesReferences.resolveRecipeReferencePath(file, Paths.getRecipeRoot()) ??
110
- RecipesReferences.getRecipePath(file, Paths.getRecipeRoot()) ??
111
- RecipesReferences.resolveRecipePath(file, Paths.getRecipeRoot()));
108
+ function resolveRecipeFile(file, cwd, options) {
109
+ const path = RecipesReferences.resolveRecipeReferencePath(file, cwd, options.skillContext);
110
+ if (path)
111
+ return path;
112
+ throw new Error(`Recipe reference not found. Use <skill>/<recipe> or an explicit .json/.md file path: ${file}`);
112
113
  }
113
114
  function isMutableUsageRecipeFile(file) {
114
115
  const userRoot = resolve(DEFAULT_RECIPE_ROOT);
@@ -116,12 +117,13 @@ function isMutableUsageRecipeFile(file) {
116
117
  const relation = relative(userRoot, resolved);
117
118
  return relation !== "" && !relation.startsWith("..") && !isAbsolute(relation);
118
119
  }
119
- function readRecipeFile(file) {
120
- const path = resolveRecipeFile(file);
120
+ function readRecipeFile(file, cwd, options) {
121
+ const path = resolveRecipeFile(file, cwd, options);
121
122
  const raw = RecipesReferences.readRawRecipeConfig(path);
122
123
  const includeActorRecipeContext = raw?.actor_context !== false && raw?.actor_context !== "off";
123
124
  const config = RecipesReferences.readResolvedRecipeConfig(path, [], {
124
125
  includeActorRecipeContext,
126
+ skillContext: options.skillContext,
125
127
  });
126
128
  if (!config) {
127
129
  throw new Error(`Template recipe must define template: ${path}`);
@@ -141,10 +143,10 @@ function getRunIdFromFile(file) {
141
143
  const name = basename(file, extname(file));
142
144
  return name || undefined;
143
145
  }
144
- function resolveStartParams(params) {
146
+ function resolveStartParams(params, cwd, options) {
145
147
  if (!params.file)
146
148
  return params;
147
- const fileParams = readRecipeFile(params.file);
149
+ const fileParams = readRecipeFile(params.file, cwd, options);
148
150
  return {
149
151
  ...fileParams,
150
152
  ...params,
@@ -239,23 +241,13 @@ function acquireStateStartLock(stateDir, options = {}) {
239
241
  function prepareStateDirForStart(stateDir) {
240
242
  RunsStart.prepareStateDirForStart(stateDir, readJson, RUNNER_PATH);
241
243
  }
242
- export function startRun(params, cwd) {
243
- const startParams = resolveStartParams(params);
244
+ export function startRun(params, cwd, options = {}) {
245
+ const startParams = resolveStartParams(params, cwd, options);
244
246
  const resolved = resolveRunTemplate(startParams);
245
247
  const run = safeRunId(startParams.run_id);
246
248
  const stateDir = resolveStateDir(startParams, run);
247
249
  const recipeFile = startParams.file
248
- ? resolveRecipeFile(startParams.file)
249
- : undefined;
250
- const packagedRecipeRoot = resolve(Paths.getPackagedRecipeRoot());
251
- const recipeRelation = recipeFile
252
- ? relative(packagedRecipeRoot, recipeFile)
253
- : undefined;
254
- const packagedRepo = startParams.defaults?.repo === "~/.pi/agent/extensions/pi-actors" &&
255
- recipeRelation &&
256
- !recipeRelation.startsWith("..") &&
257
- !isAbsolute(recipeRelation)
258
- ? dirname(packagedRecipeRoot)
250
+ ? resolveRecipeFile(startParams.file, cwd, options)
259
251
  : undefined;
260
252
  const argSpec = Schema.parseToolArgDeclarationList(startParams.args ?? []);
261
253
  if (argSpec.error)
@@ -268,7 +260,6 @@ export function startRun(params, cwd) {
268
260
  const values = Schema.normalizeRuntimeValues({
269
261
  ...argSpec.defaults,
270
262
  ...(startParams.defaults || {}),
271
- ...(packagedRepo ? { repo: packagedRepo } : {}),
272
263
  ...(startParams.values || {}),
273
264
  run_id: run,
274
265
  state_dir: stateDir,
@@ -306,7 +297,15 @@ export function startRun(params, cwd) {
306
297
  const includeActorRecipeContext = startParams.actor_context !== false &&
307
298
  startParams.actor_context !== "off";
308
299
  const recipeContextRecords = recipeFile && includeActorRecipeContext
309
- ? RecipesReferences.buildRecipeContextRecords(recipeFile)
300
+ ? RecipesReferences.buildRecipeContextRecords(recipeFile, options.skillContext).map((record, index) => index === 0 &&
301
+ startParams.launch_source === "tool" &&
302
+ record.source_kind === "explicit_file_recipe"
303
+ ? {
304
+ ...record,
305
+ logical_reference: record.name,
306
+ source_kind: "user_registry_capability",
307
+ }
308
+ : record)
310
309
  : undefined;
311
310
  if (recipeFile &&
312
311
  isMutableUsageRecipeFile(recipeFile) &&
@@ -327,7 +326,10 @@ export function startRun(params, cwd) {
327
326
  createdAt: new Date().toISOString(),
328
327
  cwd,
329
328
  ...(startParams.launch_source
330
- ? { launch_source: startParams.launch_source }
329
+ ? {
330
+ launch_kind: startParams.launch_source,
331
+ launch_source: startParams.launch_source,
332
+ }
331
333
  : {}),
332
334
  ...(startParams.launch_correlation
333
335
  ? { launch_correlation: startParams.launch_correlation } : {}),
@@ -4,6 +4,7 @@
4
4
  * Owns automatic-review lifecycle wiring without owning review decisions or filesystem transactions.
5
5
  */
6
6
  import type * as Pi from "./pi.ts";
7
+ import * as RecipesReferences from "./recipes-references.ts";
7
8
  export interface AutomaticReviewRuntime {
8
9
  close(): void;
9
10
  handleControl(action: string, input: unknown): Record<string, unknown>;
@@ -15,4 +16,5 @@ export interface AutomaticReviewRuntimeDeps {
15
16
  getRunOwnerId(ctx: Pi.ExtensionContext): string;
16
17
  getThinkingLevel(): unknown;
17
18
  }
19
+ export declare const PACKAGE_RECIPE_MEMORY_CONTEXT: RecipesReferences.ActiveSkillRecipeContext;
18
20
  export declare function createAutomaticReviewRuntime(deps: AutomaticReviewRuntimeDeps): AutomaticReviewRuntime;
@@ -3,13 +3,20 @@
3
3
  * Zones: session-bound review schedulers, silent reviewer launch adapters, review controls
4
4
  * Owns automatic-review lifecycle wiring without owning review decisions or filesystem transactions.
5
5
  */
6
- import { join } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
7
  import * as AsyncRuns from "./async-runs.js";
8
8
  import * as DraftSleep from "./draft-sleep.js";
9
9
  import * as ModelContext from "./model-context.js";
10
10
  import * as Paths from "./paths.js";
11
+ import * as RecipesReferences from "./recipes-references.js";
11
12
  import * as ReviewControl from "./review-control.js";
12
13
  import * as ToolReviewScheduler from "./tool-review-scheduler.js";
14
+ export const PACKAGE_RECIPE_MEMORY_CONTEXT = RecipesReferences.createActiveSkillRecipeContext([
15
+ {
16
+ name: "recipe-memory",
17
+ filePath: fileURLToPath(new URL("../skills/recipe-memory/SKILL.md", import.meta.url)),
18
+ },
19
+ ]);
13
20
  export function createAutomaticReviewRuntime(deps) {
14
21
  let draftScheduler;
15
22
  let toolScheduler;
@@ -56,14 +63,14 @@ export function createAutomaticReviewRuntime(deps) {
56
63
  throw new Error("Draft review session changed before launch.");
57
64
  }
58
65
  return AsyncRuns.startRun({
59
- file: join(Paths.getPackagedRecipeRoot(), "draft-review.json"),
66
+ file: "recipe-memory/draft-review",
60
67
  launch_source: "tool",
61
68
  notification_policy: "silent",
62
69
  ownerId: deps.getRunOwnerId(ctx),
63
70
  policy_values: policyValues(ctx),
64
71
  run_id: DraftSleep.draftSleepRunId(batch.batchId),
65
72
  values: { input_path: batch.reviewerInputPath },
66
- }, ctx.cwd);
73
+ }, ctx.cwd, { skillContext: PACKAGE_RECIPE_MEMORY_CONTEXT });
67
74
  },
68
75
  process: (state) => DraftSleep.processDraftSleepReview(state, {
69
76
  getRunStatus: AsyncRuns.getRunStatus,
@@ -77,14 +84,14 @@ export function createAutomaticReviewRuntime(deps) {
77
84
  throw new Error("Tool review session changed before launch.");
78
85
  }
79
86
  return AsyncRuns.startRun({
80
- file: join(Paths.getPackagedRecipeRoot(), "tool-review.json"),
87
+ file: "recipe-memory/tool-review",
81
88
  launch_source: "tool",
82
89
  notification_policy: "silent",
83
90
  ownerId: deps.getRunOwnerId(ctx),
84
91
  policy_values: policyValues(ctx),
85
92
  run_id: ToolReviewScheduler.toolReviewRunId(batch.reviewId),
86
93
  values: { input_path: batch.reviewerInputPath },
87
- }, ctx.cwd);
94
+ }, ctx.cwd, { skillContext: PACKAGE_RECIPE_MEMORY_CONTEXT });
88
95
  },
89
96
  process: (state) => ToolReviewScheduler.processToolReviewResult(state, {
90
97
  getRunStatus: AsyncRuns.getRunStatus,
@@ -31,7 +31,6 @@ function readState(path) {
31
31
  function defaultActiveTools(recipeRoot) {
32
32
  const discovered = RecipesDiscovery.discoverRecipeSources([
33
33
  { root: recipeRoot, defaultTool: true, mutableUsage: true },
34
- { root: Paths.getPackagedRecipeRoot() },
35
34
  ]);
36
35
  return [...discovered.active.values()]
37
36
  .filter((entry) => existsSync(entry.path))
@@ -72,6 +72,7 @@ export interface RegisteredToolExecutionResult {
72
72
  command: string;
73
73
  fullOutputPath?: string;
74
74
  killed: boolean;
75
+ launch_kind: "tool";
75
76
  stderrBytes?: number;
76
77
  stderrCapturedBytes?: number;
77
78
  stderrFile?: string;
@@ -709,6 +709,7 @@ export async function executeRegisteredTool(cfg, params, exec, cwd, signal) {
709
709
  command,
710
710
  fullOutputPath: result.stdoutFile ?? formatted.fullOutputPath,
711
711
  killed: result.killed,
712
+ launch_kind: "tool",
712
713
  ...getCaptureDetails(result),
713
714
  ...(executed.branches.length > 0 ? { branches: executed.branches } : {}),
714
715
  ...(executed.failures.length > 0
@@ -6,7 +6,7 @@
6
6
  import * as Pi from "./pi.ts";
7
7
  import * as RecipesReferences from "./recipes-references.ts";
8
8
  export interface ActorExtensionRuntime {
9
- beforeAgentStart(systemPrompt: string, skills: RecipesReferences.ActiveSkillRecipeSource[]): {
9
+ beforeAgentStart(systemPrompt: string, skills: RecipesReferences.ActiveSkillRecipeSource[], ctx: Pi.ExtensionContext): {
10
10
  systemPrompt: string;
11
11
  };
12
12
  discoverResources(metaUrl: string): {
@@ -8,6 +8,7 @@ import * as CommandTemplates from "./command-templates.js";
8
8
  import * as Paths from "./paths.js";
9
9
  import * as Pi from "./pi.js";
10
10
  import * as Prompts from "./prompts.js";
11
+ import * as RecipeResolution from "./recipes-context.js";
11
12
  import * as RecipesReferences from "./recipes-references.js";
12
13
  import * as RunUiRuntime from "./run-ui-runtime.js";
13
14
  import * as Runtime from "./runtime.js";
@@ -16,7 +17,16 @@ import * as Tools from "./tools.js";
16
17
  import * as ToolsResponse from "./tools-response.js";
17
18
  export function createActorExtensionRuntime(pi) {
18
19
  let activeRunContext;
20
+ const recipeResolutionContextsBySession = new Map();
19
21
  const getRunOwnerId = Pi.getSessionId;
22
+ const getRecipeResolutionContext = (ctx) => {
23
+ const sessionId = getRunOwnerId(ctx);
24
+ const resolutionContext = recipeResolutionContextsBySession.get(sessionId);
25
+ if (!resolutionContext) {
26
+ throw new Error(`Recipe resolution context is unavailable for session ${sessionId}.`);
27
+ }
28
+ return resolutionContext;
29
+ };
20
30
  const automaticReview = AutomaticReviewRuntime.createAutomaticReviewRuntime({
21
31
  getActiveContext: () => activeRunContext,
22
32
  getRunOwnerId,
@@ -41,6 +51,7 @@ export function createActorExtensionRuntime(pi) {
41
51
  if (ctx && typeof ctx === "object") {
42
52
  nextArgs[4] = {
43
53
  ...ctx,
54
+ recipeResolutionContext: getRecipeResolutionContext(ctx),
44
55
  getThinkingLevel: () => pi.getThinkingLevel(),
45
56
  };
46
57
  }
@@ -57,6 +68,7 @@ export function createActorExtensionRuntime(pi) {
57
68
  configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
58
69
  exec: CommandTemplates.execCommandTemplate,
59
70
  getActiveTools: () => pi.getActiveTools(),
71
+ getAllTools: () => pi.getAllTools(),
60
72
  registerTool: (definition) => {
61
73
  const wrapped = withCurrentThinkingContext(definition);
62
74
  actorToolDefinitions.set(wrapped.name, wrapped);
@@ -65,10 +77,17 @@ export function createActorExtensionRuntime(pi) {
65
77
  reservedToolNames: Tools.RESERVED_TOOL_NAMES,
66
78
  setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
67
79
  });
68
- const recipeReload = Runtime.createRecipeToolReloadWatcher(runtime);
80
+ const recipeReload = Runtime.createRecipeToolReloadWatcher(runtime, {
81
+ getResolutionContext: () => activeRunContext
82
+ ? getRecipeResolutionContext(activeRunContext)
83
+ : undefined,
84
+ });
69
85
  return {
70
- beforeAgentStart(systemPrompt, skills) {
71
- RecipesReferences.setActiveSkillRecipeSources(skills);
86
+ beforeAgentStart(systemPrompt, skills, ctx) {
87
+ const sessionId = getRunOwnerId(ctx);
88
+ const resolutionContext = RecipeResolution.createRecipeResolutionContext(sessionId, ctx.cwd, RecipesReferences.createActiveSkillRecipeContext(skills));
89
+ recipeResolutionContextsBySession.set(sessionId, resolutionContext);
90
+ runtime.loadTools(ctx, resolutionContext);
72
91
  return {
73
92
  systemPrompt: `${systemPrompt}\n\n${Prompts.ONBOARDING_SYSTEM_PROMPT}`,
74
93
  };
@@ -83,12 +102,15 @@ export function createActorExtensionRuntime(pi) {
83
102
  automaticReview.schedule();
84
103
  },
85
104
  onSessionShutdown(reason, ctx) {
105
+ recipeResolutionContextsBySession.delete(getRunOwnerId(ctx));
86
106
  activeRunContext = undefined;
87
107
  automaticReview.close();
88
108
  recipeReload.close();
89
109
  runUiRuntime.shutdown(reason, ctx);
90
110
  },
91
111
  async onSessionStart(ctx) {
112
+ const sessionId = getRunOwnerId(ctx);
113
+ recipeResolutionContextsBySession.set(sessionId, RecipeResolution.createEmptyRecipeResolutionContext(sessionId, ctx.cwd));
92
114
  ctx.ui.setWidget("zz-pi-actors-comms", undefined);
93
115
  activeRunContext = ctx;
94
116
  runUiRuntime.close();
@@ -98,7 +120,6 @@ export function createActorExtensionRuntime(pi) {
98
120
  if (activeRunContext !== ctx)
99
121
  return;
100
122
  automaticReview.start(ctx);
101
- runtime.loadTools(ctx);
102
123
  runUiRuntime.start(ctx);
103
124
  recipeReload.watch(ctx);
104
125
  },
@@ -107,6 +128,7 @@ export function createActorExtensionRuntime(pi) {
107
128
  configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
108
129
  getActiveTools: () => pi.getActiveTools(),
109
130
  getRuntimeTool: (name) => Tools.resolveActiveRuntimeTool(name, runtime.getTools(), (activeName) => actorToolDefinitions.get(activeName)),
131
+ getRuntimeToolStatus: runtime.getToolStatus,
110
132
  handleRuntimeControl: automaticReview.handleControl,
111
133
  registryRuntime: runtime,
112
134
  setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
@@ -56,9 +56,37 @@ export function readActorInspectorRecipe(stateDir) {
56
56
  !Array.isArray(primary.recipe)
57
57
  ? primary.recipe
58
58
  : undefined;
59
- const redactedRecord = (value) => SessionEvidence.redactSessionEvidenceValue(Object.fromEntries(Object.entries(value).filter(([key, entry]) => entry !== undefined &&
60
- key !== "recipe_dir" &&
61
- key !== "skill_dir")));
59
+ const stripPrivateOrigins = (value) => {
60
+ if (Array.isArray(value))
61
+ return value.map(stripPrivateOrigins);
62
+ if (!value || typeof value !== "object")
63
+ return value;
64
+ return Object.fromEntries(Object.entries(value)
65
+ .filter(([key, entry]) => entry !== undefined &&
66
+ key !== "recipe_dir" &&
67
+ key !== "skill_dir" &&
68
+ key !== "source_file")
69
+ .map(([key, entry]) => [
70
+ key,
71
+ key === "actorRecipeContext" && entry && typeof entry === "object"
72
+ ? stripPrivateOrigins(Object.fromEntries(Object.entries(entry).filter(([contextKey]) => contextKey !== "file")))
73
+ : stripPrivateOrigins(entry),
74
+ ]));
75
+ };
76
+ const redactedRecord = (value) => SessionEvidence.redactSessionEvidenceValue(stripPrivateOrigins(value));
77
+ const primarySourceKind = primary?.source_kind === "active_skill_component"
78
+ ? "active_skill_component"
79
+ : primary?.source_kind === "user_registry_capability" ||
80
+ meta.launch_source === "tool"
81
+ ? "user_registry_capability"
82
+ : "explicit_file_recipe";
83
+ const primaryLogicalReference = typeof primary?.logical_reference === "string"
84
+ ? primary.logical_reference
85
+ : typeof primary?.name === "string"
86
+ ? primary.name
87
+ : typeof meta.recipe === "string"
88
+ ? meta.recipe
89
+ : "unknown";
62
90
  const launchValues = meta.values && typeof meta.values === "object" && !Array.isArray(meta.values)
63
91
  ? Object.fromEntries(Object.entries(meta.values).filter(([key]) => key !== "recipe_dir" && key !== "skill_dir"))
64
92
  : meta.values;
@@ -66,17 +94,28 @@ export function readActorInspectorRecipe(stateDir) {
66
94
  composition: contexts.map((entry) => redactedRecord({
67
95
  ...(typeof entry.alias === "string" ? { alias: entry.alias } : {}),
68
96
  depth: entry.depth,
69
- file: entry.file,
70
97
  import_path: entry.import_path,
71
- name: entry.name,
72
- qualified_name: entry.qualified_name,
98
+ logical_reference: entry.logical_reference ?? entry.name,
99
+ recipe_stem: entry.name,
100
+ role: entry.role,
101
+ ...(typeof entry.skill === "string" ? { skill: entry.skill } : {}),
102
+ source_kind: entry.source_kind === "active_skill_component"
103
+ ? "active_skill_component"
104
+ : entry.source_kind === "user_registry_capability" ||
105
+ (entry.depth === 0 && meta.launch_source === "tool")
106
+ ? "user_registry_capability"
107
+ : "explicit_file_recipe",
73
108
  })),
74
109
  ...(definition ? { definition: redactedRecord(definition) } : {}),
75
110
  diagnostics: result.diagnostics.map((diagnostic) => diagnostic.message),
76
111
  identity: redactedRecord({
77
112
  run: meta.run,
78
113
  recipe: meta.recipe,
79
- recipe_file: meta.recipe_file,
114
+ recipe_stem: primary?.name ?? meta.recipe,
115
+ logical_reference: primaryLogicalReference,
116
+ ...(typeof primary?.skill === "string" ? { skill: primary.skill } : {}),
117
+ source_kind: primarySourceKind,
118
+ launch_kind: meta.launch_kind ?? meta.launch_source,
80
119
  launch_source: meta.launch_source,
81
120
  }),
82
121
  launch: redactedRecord({
@@ -25,4 +25,3 @@ export declare function getExtensionSkillsDir(extensionUrl: string): string;
25
25
  export declare function getExistingExtensionSkillPaths(extensionUrl: string): string[];
26
26
  export declare function getRecipeRoot(agentDir?: string): string;
27
27
  export declare function getRecipeDraftRoot(agentDir?: string): string;
28
- export declare function getPackagedRecipeRoot(): string;
package/dist/lib/paths.js CHANGED
@@ -70,10 +70,3 @@ export function getRecipeRoot(agentDir = getAgentDir()) {
70
70
  export function getRecipeDraftRoot(agentDir = getAgentDir()) {
71
71
  return join(getRecipeRoot(agentDir), "drafts");
72
72
  }
73
- export function getPackagedRecipeRoot() {
74
- const here = dirname(fileURLToPath(import.meta.url));
75
- const compiledRoot = resolve(here, "..", "..", "recipes");
76
- if (existsSync(compiledRoot))
77
- return compiledRoot;
78
- return resolve(here, "..", "recipes");
79
- }
@@ -6,7 +6,7 @@
6
6
  export declare const REGISTER_TOOL_DESCRIPTION: string;
7
7
  export declare const REGISTER_TOOL_PROMPT_SNIPPET = "Register persistent command templates as agent-callable tools";
8
8
  export declare const REGISTER_TOOL_GUIDELINES: string[];
9
- export declare const ONBOARDING_SYSTEM_PROMPT = "pi-actors quick model:\n- Local-first actor memory: persist trusted local capabilities instead of rebuilding shell recipes.\n- Layers: task -> command template -> recipe/tool -> spawn -> run:<id>; tool:<name> wraps registered capabilities.\n- Command templates stay sync and shell-free: string leaves split into executable + argv, infer .js/.mjs through node\u2192bun\u2192deno run and .sh through bash, and treat operators such as && as literal arguments; use template arrays for sequencing or an explicit trusted shell/script when shell semantics are required. Flags include args/defaults, parallel, concurrency, min_successful, when, timeout, delay, retry, failure, recover, repeat, accept_output, output.\n- Placeholders support typed/default args plus {value??fallback} and {flag?yes:no}.\n- ~/.pi/agent/recipes/*.json is actor muscle memory: every recipe there is auto-registered as an agent tool across sessions; register_tool writes there.\n- Recipes own template directly and may declare metadata/defaults/imports/control/artifacts; files >1 MiB or import depth >32 fail closed.\n- Recipe imports are local variables; imported recipes are definitions, not nested async runs; parent async:true creates one run.\n- Actor-mode trigger: if work may outlive this turn, need steering/follow-up/artifacts, run as a service, fan out, or be resumed/inspected later, use spawn -> message -> inspect instead of ad hoc shell backgrounding.\n- Use spawn/message/inspect for actor-level start/send/observe; short foreground checks can stay ordinary tools/templates; avoid internal transport vocabulary in public guidance.\n- Run state lives under ~/.pi/agent/tmp/pi-actors/runs. Inspect intentionally and avoid busy-polling. Terminal and coordinator-bound notifications queue as Pi follow-ups so concurrently completed actors can reach the coordinator after current work instead of steering between tool calls. Terminal follow-up content stays minimal: run, status, one base path, and relative artifact names only; semantic output stays in non-LLM details and run state. When a deferred actor result gates the next step, wait for its terminal follow-up; do not schedule continuation loops, repeatedly inspect, or mutate its reviewed scope while it runs. Inspect early only for an operator request, a meaningful actor event, or diagnosis of an overdue/stuck run.\n- Maintain ~/.pi/agent/recipes like MEMORY.md for capabilities: keep useful tools, curate stale ones, and fix/remove/disable invalid recipes flagged by registry warnings; packaged/ad hoc recipes are lower-priority components; offer to save successful recurring patterns only after confirmation.\n- Prefer maintained packaged recipes/pipelines with spawn file=<recipe> before ad hoc scripts/wrappers; review swarms inherit current model/thinking, preflight before fanout, and expose quorum/concurrency/TTL knobs unless explicit args are passed.\n- For any non-trivial actor use or pi-actors change, read the bundled actors skill first. Before launching multiple actors/subagents for parallel implementation, independent artifact generation, delegated audit, or review, also read the bundled swarm skill; the coordinator owns decomposition, disjoint scopes, launch correctness, integration, and final validation. For deeper guidance, inspect installed extension sources/docs/recipes because README/docs are not automatically in context.";
9
+ export declare const ONBOARDING_SYSTEM_PROMPT = "pi-actors quick model:\n- Local-first actor memory: persist trusted local capabilities instead of rebuilding shell recipes.\n- Layers: task -> command template -> recipe/tool -> spawn -> run:<id>; tool:<name> wraps registered capabilities.\n- Command templates stay sync and shell-free: string leaves split into executable + argv, infer .js/.mjs through node\u2192bun\u2192deno run and .sh through bash, and treat operators such as && as literal arguments; use template arrays for sequencing or an explicit trusted shell/script when shell semantics are required. Flags include args/defaults, parallel, concurrency, min_successful, when, timeout, delay, retry, failure, recover, repeat, accept_output, output.\n- Placeholders support typed/default args plus {value??fallback} and {flag?yes:no}.\n- ~/.pi/agent/recipes/*.json is actor muscle memory: valid admitted recipes are reconciled as tools across sessions; register_tool writes there and reports current activation truth.\n- Recipes own template directly and may declare metadata/defaults/imports/control/artifacts; files >1 MiB or import depth >32 fail closed.\n- Recipe imports are local variables; imported recipes are definitions, not nested async runs; parent async:true creates one run.\n- Actor-mode trigger: if work may outlive this turn, need steering/follow-up/artifacts, run as a service, fan out, or be resumed/inspected later, use spawn -> message -> inspect instead of ad hoc shell backgrounding.\n- Use spawn/message/inspect for actor-level start/send/observe; short foreground checks can stay ordinary tools/templates; avoid internal transport vocabulary in public guidance.\n- Run state lives under ~/.pi/agent/tmp/pi-actors/runs. Inspect intentionally and avoid busy-polling. Terminal and coordinator-bound notifications queue as Pi follow-ups so concurrently completed actors can reach the coordinator after current work instead of steering between tool calls. Terminal follow-up content stays minimal: run, status, one base path, and relative artifact names only; semantic output stays in non-LLM details and run state. When a deferred actor result gates the next step, wait for its terminal follow-up; do not schedule continuation loops, repeatedly inspect, or mutate its reviewed scope while it runs. Inspect early only for an operator request, a meaningful actor event, or diagnosis of an overdue/stuck run.\n- Maintain ~/.pi/agent/recipes like MEMORY.md for capabilities: keep useful tools, curate stale ones, and fix/remove/disable invalid recipes flagged by registry warnings; active-Skill and explicit file Recipes remain components outside user tool discovery; offer to save successful recurring patterns only after confirmation.\n- Prefer maintained active-Skill Recipes with spawn recipe=<skill>/<recipe> before ad hoc scripts/wrappers; explicit file Recipes use exact .json/.md paths; review swarms inherit current model/thinking, preflight before fanout, and expose quorum/concurrency/TTL knobs unless explicit args are passed.\n- For any non-trivial actor use or pi-actors change, read the bundled actors skill first. Before launching multiple actors/subagents for parallel implementation, independent artifact generation, delegated audit, or review, also read the bundled swarm skill; the coordinator owns decomposition, disjoint scopes, launch correctness, integration, and final validation. For deeper guidance, inspect installed extension sources/docs/recipes because README/docs are not automatically in context.";
10
10
  export declare const REGISTER_TOOL_PARAM_DESCRIPTIONS: {
11
11
  readonly name: "Tool name in snake_case (e.g., 'transcribe')";
12
12
  readonly description: "Describe what the tool does for the LLM. Required unless deleting; omitted updates keep the old description.";
@@ -9,7 +9,7 @@ export const REGISTER_TOOL_DESCRIPTION = "Register a persistent custom tool from
9
9
  export const REGISTER_TOOL_PROMPT_SNIPPET = "Register persistent command templates as agent-callable tools";
10
10
  export const REGISTER_TOOL_GUIDELINES = [
11
11
  "Use register_tool to wrap trusted local commands, scripts, programs, libraries, or template recipes as persistent pi tools.",
12
- "After register_tool succeeds, the new tool is immediately callable and remains available after reload.",
12
+ "After register_tool succeeds, trust its callable_now and activation result; persisted definitions remain available for admission after reload.",
13
13
  'Set template=null or template="" in register_tool to delete a persisted tool.',
14
14
  "Set update=true in register_tool to overwrite an existing tool registration.",
15
15
  ];
@@ -18,14 +18,14 @@ export const ONBOARDING_SYSTEM_PROMPT = `pi-actors quick model:
18
18
  - Layers: task -> command template -> recipe/tool -> spawn -> run:<id>; tool:<name> wraps registered capabilities.
19
19
  - Command templates stay sync and shell-free: string leaves split into executable + argv, infer .js/.mjs through node→bun→deno run and .sh through bash, and treat operators such as && as literal arguments; use template arrays for sequencing or an explicit trusted shell/script when shell semantics are required. Flags include args/defaults, parallel, concurrency, min_successful, when, timeout, delay, retry, failure, recover, repeat, accept_output, output.
20
20
  - Placeholders support typed/default args plus {value??fallback} and {flag?yes:no}.
21
- - ~/.pi/agent/recipes/*.json is actor muscle memory: every recipe there is auto-registered as an agent tool across sessions; register_tool writes there.
21
+ - ~/.pi/agent/recipes/*.json is actor muscle memory: valid admitted recipes are reconciled as tools across sessions; register_tool writes there and reports current activation truth.
22
22
  - Recipes own template directly and may declare metadata/defaults/imports/control/artifacts; files >1 MiB or import depth >32 fail closed.
23
23
  - Recipe imports are local variables; imported recipes are definitions, not nested async runs; parent async:true creates one run.
24
24
  - Actor-mode trigger: if work may outlive this turn, need steering/follow-up/artifacts, run as a service, fan out, or be resumed/inspected later, use spawn -> message -> inspect instead of ad hoc shell backgrounding.
25
25
  - Use spawn/message/inspect for actor-level start/send/observe; short foreground checks can stay ordinary tools/templates; avoid internal transport vocabulary in public guidance.
26
26
  - Run state lives under ~/.pi/agent/tmp/pi-actors/runs. Inspect intentionally and avoid busy-polling. Terminal and coordinator-bound notifications queue as Pi follow-ups so concurrently completed actors can reach the coordinator after current work instead of steering between tool calls. Terminal follow-up content stays minimal: run, status, one base path, and relative artifact names only; semantic output stays in non-LLM details and run state. When a deferred actor result gates the next step, wait for its terminal follow-up; do not schedule continuation loops, repeatedly inspect, or mutate its reviewed scope while it runs. Inspect early only for an operator request, a meaningful actor event, or diagnosis of an overdue/stuck run.
27
- - Maintain ~/.pi/agent/recipes like MEMORY.md for capabilities: keep useful tools, curate stale ones, and fix/remove/disable invalid recipes flagged by registry warnings; packaged/ad hoc recipes are lower-priority components; offer to save successful recurring patterns only after confirmation.
28
- - Prefer maintained packaged recipes/pipelines with spawn file=<recipe> before ad hoc scripts/wrappers; review swarms inherit current model/thinking, preflight before fanout, and expose quorum/concurrency/TTL knobs unless explicit args are passed.
27
+ - Maintain ~/.pi/agent/recipes like MEMORY.md for capabilities: keep useful tools, curate stale ones, and fix/remove/disable invalid recipes flagged by registry warnings; active-Skill and explicit file Recipes remain components outside user tool discovery; offer to save successful recurring patterns only after confirmation.
28
+ - Prefer maintained active-Skill Recipes with spawn recipe=<skill>/<recipe> before ad hoc scripts/wrappers; explicit file Recipes use exact .json/.md paths; review swarms inherit current model/thinking, preflight before fanout, and expose quorum/concurrency/TTL knobs unless explicit args are passed.
29
29
  - For any non-trivial actor use or pi-actors change, read the bundled actors skill first. Before launching multiple actors/subagents for parallel implementation, independent artifact generation, delegated audit, or review, also read the bundled swarm skill; the coordinator owns decomposition, disjoint scopes, launch correctness, integration, and final validation. For deeper guidance, inspect installed extension sources/docs/recipes because README/docs are not automatically in context.`;
30
30
  export const REGISTER_TOOL_PARAM_DESCRIPTIONS = {
31
31
  name: "Tool name in snake_case (e.g., 'transcribe')",
@@ -1,10 +1,19 @@
1
1
  /**
2
- * Recipe context prompt assembly.
3
- * Zones: async runner prompt context, recipe provenance, LLM child launches
4
- * Owns compact actor recipe context records appended to child-agent prompts.
2
+ * Recipe context contracts and prompt assembly.
3
+ * Zones: live session resolution, async runner prompt context, recipe provenance, LLM child launches
4
+ * Owns the immutable live Recipe environment and compact actor context appended to child-agent prompts.
5
5
  */
6
6
  import type { CommandTemplateActorRecipeContext } from "./command-templates.ts";
7
+ import * as RecipesReferences from "./recipes-references.ts";
7
8
  import type { TemplateRecipeContextRecord } from "./recipes-references.ts";
9
+ export interface RecipeResolutionContext {
10
+ readonly activeSkills: RecipesReferences.ActiveSkillRecipeContext;
11
+ readonly cwd: string;
12
+ readonly generation: string;
13
+ readonly sessionId: string;
14
+ }
15
+ export declare function createRecipeResolutionContext(sessionId: string, cwd: string, activeSkills: RecipesReferences.ActiveSkillRecipeContext): RecipeResolutionContext;
16
+ export declare function createEmptyRecipeResolutionContext(sessionId: string, cwd: string): RecipeResolutionContext;
8
17
  export interface MarkedRecipeContextRecord extends TemplateRecipeContextRecord {
9
18
  you_are_here?: true;
10
19
  you_are_here_path?: string;