@llblab/pi-actors 0.45.1 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/AGENTS.md +9 -7
  2. package/CHANGELOG.md +8 -1
  3. package/README.md +26 -12
  4. package/dist/fixtures/protocol/recipe-summary.json +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/lib/async-runs.d.ts +4 -1
  7. package/dist/lib/async-runs.js +22 -23
  8. package/dist/lib/automatic-review-runtime.d.ts +2 -0
  9. package/dist/lib/automatic-review-runtime.js +12 -5
  10. package/dist/lib/draft-sleep.js +0 -1
  11. package/dist/lib/extension-runtime.d.ts +1 -1
  12. package/dist/lib/extension-runtime.js +8 -2
  13. package/dist/lib/inspector.js +45 -7
  14. package/dist/lib/paths.d.ts +0 -1
  15. package/dist/lib/paths.js +0 -7
  16. package/dist/lib/prompts.d.ts +1 -1
  17. package/dist/lib/prompts.js +2 -2
  18. package/dist/lib/recipes-context.js +2 -2
  19. package/dist/lib/recipes-references.d.ts +24 -9
  20. package/dist/lib/recipes-references.js +152 -126
  21. package/dist/lib/runtime.d.ts +0 -1
  22. package/dist/lib/runtime.js +1 -3
  23. package/dist/lib/tools-inspect.d.ts +0 -1
  24. package/dist/lib/tools-inspect.js +35 -8
  25. package/dist/lib/tools-local.d.ts +2 -0
  26. package/dist/lib/tools-local.js +1 -1
  27. package/dist/lib/tools-spawn.d.ts +2 -0
  28. package/dist/lib/tools-spawn.js +24 -52
  29. package/dist/scripts/build-dist.mjs +13 -4
  30. package/dist/skills/actors/SKILL.md +6 -6
  31. package/dist/skills/actors/recipes/recipe-validate.json +11 -0
  32. package/{recipes/utility-coordinator-lock-snapshot.json → dist/skills/actors/recipes/resource-locker-snapshot.json} +1 -3
  33. package/dist/{recipes → skills/actors/recipes}/resource-locker.json +1 -3
  34. package/dist/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json} +1 -3
  35. package/dist/skills/actors/recipes/run-summary.json +9 -0
  36. package/dist/{scripts/locker.mjs → skills/actors/scripts/resource-locker.mjs} +2 -2
  37. package/dist/skills/actors/scripts/run-utils.mjs +164 -0
  38. package/{scripts → dist/skills/actors/scripts}/validate-recipe.mjs +134 -17
  39. package/dist/skills/artifacts/SKILL.md +16 -0
  40. package/{recipes/pipeline-artifact-bundle.json → dist/skills/artifacts/recipes/bundle.json} +4 -4
  41. package/dist/{recipes/utility-artifact-write.json → skills/artifacts/recipes/file-write.json} +1 -3
  42. package/dist/{recipes/utility-artifact-manifest.json → skills/artifacts/recipes/manifest.json} +1 -3
  43. package/{recipes/pipeline-artifact-report.json → dist/skills/artifacts/recipes/report.json} +2 -2
  44. package/dist/{recipes/pipeline-artifact-write.json → skills/artifacts/recipes/write.json} +3 -3
  45. package/dist/skills/artifacts/scripts/artifact-utils.mjs +63 -0
  46. package/dist/skills/media/SKILL.md +16 -0
  47. package/dist/{recipes/pipeline-media-library.json → skills/media/recipes/library.json} +2 -2
  48. package/{recipes/music-player.json → dist/skills/media/recipes/player.json} +1 -3
  49. package/dist/{recipes/utility-playlist-build.json → skills/media/recipes/playlist-build.json} +1 -3
  50. package/dist/skills/media/scripts/media-utils.mjs +47 -0
  51. package/dist/{scripts → skills/media/scripts}/music-player.mjs +9 -3
  52. package/dist/skills/project-work/SKILL.md +16 -0
  53. package/dist/skills/project-work/recipes/changelog-section.json +11 -0
  54. package/{recipes/pipeline-docs-maintenance.json → dist/skills/project-work/recipes/docs-maintenance.json} +4 -4
  55. package/dist/skills/project-work/recipes/package-summary.json +9 -0
  56. package/{recipes/pipeline-release-readiness.json → dist/skills/project-work/recipes/release-readiness.json} +6 -6
  57. package/dist/{recipes/pipeline-release-summary.json → skills/project-work/recipes/release-summary.json} +5 -5
  58. package/{recipes/pipeline-repo-health.json → dist/skills/project-work/recipes/repo-health.json} +6 -6
  59. package/{recipes/pipeline-async-run-ops.json → dist/skills/project-work/recipes/run-ops.json} +3 -3
  60. package/dist/skills/project-work/recipes/skill-summary.json +11 -0
  61. package/dist/skills/project-work/scripts/project-utils.mjs +89 -0
  62. package/dist/skills/recipe-memory/SKILL.md +16 -0
  63. package/dist/skills/swarm/SKILL.md +4 -4
  64. package/{recipes/pipeline-architect-coordinator.json → dist/skills/swarm/recipes/architect.json} +5 -5
  65. package/{recipes/pipeline-checkpoint-continuation.json → dist/skills/swarm/recipes/checkpoint-continuation.json} +3 -3
  66. package/dist/{recipes/pipeline-development-tasking.json → skills/swarm/recipes/development-tasking.json} +4 -4
  67. package/dist/{recipes/lens-swarm.json → skills/swarm/recipes/lens-review.json} +1 -1
  68. package/dist/{recipes/pipeline-quorum-review.json → skills/swarm/recipes/quorum-review.json} +4 -4
  69. package/{recipes/pipeline-research-synthesis.json → dist/skills/swarm/recipes/research-synthesis.json} +6 -6
  70. package/{recipes/pipeline-review-readiness.json → dist/skills/swarm/recipes/review-readiness.json} +1 -1
  71. package/{recipes/subagents-prompts.json → dist/skills/swarm/recipes/subagent-prompts.json} +1 -1
  72. package/{recipes → dist/skills/swarm/recipes}/subagent-quorum.json +1 -1
  73. package/dist/{recipes → skills/swarm/recipes}/subagent-review-coordinator.json +6 -6
  74. package/docs/actor-inspector.md +4 -3
  75. package/docs/async-runs.md +2 -2
  76. package/docs/recipe-library.md +23 -23
  77. package/docs/releasing.md +2 -2
  78. package/docs/template-recipes.md +30 -14
  79. package/docs/tool-registry.md +2 -2
  80. package/fixtures/protocol/recipe-summary.json +1 -1
  81. package/index.ts +2 -1
  82. package/lib/async-runs.ts +47 -24
  83. package/lib/automatic-review-runtime.ts +16 -3
  84. package/lib/draft-sleep.ts +0 -1
  85. package/lib/extension-runtime.ts +21 -2
  86. package/lib/inspector.ts +56 -11
  87. package/lib/paths.ts +0 -7
  88. package/lib/prompts.ts +2 -2
  89. package/lib/recipes-context.ts +2 -2
  90. package/lib/recipes-references.ts +223 -134
  91. package/lib/runtime.ts +1 -5
  92. package/lib/tools-inspect.ts +42 -9
  93. package/lib/tools-local.ts +2 -0
  94. package/lib/tools-spawn.ts +37 -74
  95. package/package.json +2 -4
  96. package/scripts/build-dist.mjs +13 -4
  97. package/skills/actors/SKILL.md +6 -6
  98. package/skills/actors/recipes/recipe-validate.json +11 -0
  99. package/{dist/recipes/utility-coordinator-lock-snapshot.json → skills/actors/recipes/resource-locker-snapshot.json} +1 -3
  100. package/{recipes → skills/actors/recipes}/resource-locker.json +1 -3
  101. package/{recipes/utility-run-ops-snapshot.json → skills/actors/recipes/run-ops-snapshot.json} +1 -3
  102. package/skills/actors/recipes/run-summary.json +9 -0
  103. package/{scripts/locker.mjs → skills/actors/scripts/resource-locker.mjs} +2 -2
  104. package/skills/actors/scripts/run-utils.mjs +164 -0
  105. package/{dist → skills/actors}/scripts/validate-recipe.mjs +134 -17
  106. package/skills/artifacts/SKILL.md +16 -0
  107. package/{dist/recipes/pipeline-artifact-bundle.json → skills/artifacts/recipes/bundle.json} +4 -4
  108. package/{recipes/utility-artifact-write.json → skills/artifacts/recipes/file-write.json} +1 -3
  109. package/{recipes/utility-artifact-manifest.json → skills/artifacts/recipes/manifest.json} +1 -3
  110. package/{dist/recipes/pipeline-artifact-report.json → skills/artifacts/recipes/report.json} +2 -2
  111. package/{recipes/pipeline-artifact-write.json → skills/artifacts/recipes/write.json} +3 -3
  112. package/skills/artifacts/scripts/artifact-utils.mjs +63 -0
  113. package/skills/media/SKILL.md +16 -0
  114. package/{recipes/pipeline-media-library.json → skills/media/recipes/library.json} +2 -2
  115. package/{dist/recipes/music-player.json → skills/media/recipes/player.json} +1 -3
  116. package/{recipes/utility-playlist-build.json → skills/media/recipes/playlist-build.json} +1 -3
  117. package/skills/media/scripts/media-utils.mjs +47 -0
  118. package/{scripts → skills/media/scripts}/music-player.mjs +9 -3
  119. package/skills/project-work/SKILL.md +16 -0
  120. package/skills/project-work/recipes/changelog-section.json +11 -0
  121. package/{dist/recipes/pipeline-docs-maintenance.json → skills/project-work/recipes/docs-maintenance.json} +4 -4
  122. package/skills/project-work/recipes/package-summary.json +9 -0
  123. package/{dist/recipes/pipeline-release-readiness.json → skills/project-work/recipes/release-readiness.json} +6 -6
  124. package/{recipes/pipeline-release-summary.json → skills/project-work/recipes/release-summary.json} +5 -5
  125. package/{dist/recipes/pipeline-repo-health.json → skills/project-work/recipes/repo-health.json} +6 -6
  126. package/{dist/recipes/pipeline-async-run-ops.json → skills/project-work/recipes/run-ops.json} +3 -3
  127. package/skills/project-work/recipes/skill-summary.json +11 -0
  128. package/skills/project-work/scripts/project-utils.mjs +89 -0
  129. package/skills/recipe-memory/SKILL.md +16 -0
  130. package/skills/swarm/SKILL.md +4 -4
  131. package/{dist/recipes/pipeline-architect-coordinator.json → skills/swarm/recipes/architect.json} +5 -5
  132. package/{dist/recipes/pipeline-checkpoint-continuation.json → skills/swarm/recipes/checkpoint-continuation.json} +3 -3
  133. package/{recipes/pipeline-development-tasking.json → skills/swarm/recipes/development-tasking.json} +4 -4
  134. package/{recipes/lens-swarm.json → skills/swarm/recipes/lens-review.json} +1 -1
  135. package/{recipes/pipeline-quorum-review.json → skills/swarm/recipes/quorum-review.json} +4 -4
  136. package/{dist/recipes/pipeline-research-synthesis.json → skills/swarm/recipes/research-synthesis.json} +6 -6
  137. package/{dist/recipes/pipeline-review-readiness.json → skills/swarm/recipes/review-readiness.json} +1 -1
  138. package/{dist/recipes/subagents-prompts.json → skills/swarm/recipes/subagent-prompts.json} +1 -1
  139. package/{dist → skills/swarm}/recipes/subagent-quorum.json +1 -1
  140. package/{recipes → skills/swarm/recipes}/subagent-review-coordinator.json +6 -6
  141. package/dist/recipes/utility-changelog-section.json +0 -13
  142. package/dist/recipes/utility-package-summary.json +0 -11
  143. package/dist/recipes/utility-run-summary.json +0 -11
  144. package/dist/recipes/utility-skill-summary.json +0 -13
  145. package/dist/recipes/utility-validate-recipe.json +0 -13
  146. package/dist/scripts/executable-block-style.d.mts +0 -1
  147. package/dist/scripts/executable-block-style.mjs +0 -73
  148. package/dist/scripts/recipe-utils.mjs +0 -404
  149. package/dist/scripts/release-gates.mjs +0 -281
  150. package/recipes/utility-changelog-section.json +0 -13
  151. package/recipes/utility-package-summary.json +0 -11
  152. package/recipes/utility-run-summary.json +0 -11
  153. package/recipes/utility-skill-summary.json +0 -13
  154. package/recipes/utility-validate-recipe.json +0 -13
  155. package/scripts/executable-block-style.d.mts +0 -1
  156. package/scripts/executable-block-style.mjs +0 -73
  157. package/scripts/recipe-utils.mjs +0 -404
  158. package/scripts/release-gates.mjs +0 -281
  159. /package/dist/{recipes/utility-validation-wrapper.json → skills/actors/recipes/command-validate.json} +0 -0
  160. /package/dist/{recipes/utility-jsonl-tail.json → skills/actors/recipes/jsonl-tail.json} +0 -0
  161. /package/dist/{recipes/utility-run-state-files.json → skills/actors/recipes/run-state-files.json} +0 -0
  162. /package/dist/{recipes/utility-playlist-scan.json → skills/media/recipes/playlist-scan.json} +0 -0
  163. /package/dist/{recipes/utility-changelog-head.json → skills/project-work/recipes/changelog-head.json} +0 -0
  164. /package/dist/{recipes/utility-git-log.json → skills/project-work/recipes/git-log.json} +0 -0
  165. /package/dist/{recipes/utility-git-status.json → skills/project-work/recipes/git-status.json} +0 -0
  166. /package/dist/{recipes/utility-markdown-index.json → skills/project-work/recipes/markdown-index.json} +0 -0
  167. /package/dist/{recipes → skills/recipe-memory/recipes}/draft-review.json +0 -0
  168. /package/dist/{recipes → skills/recipe-memory/recipes}/tool-review.json +0 -0
  169. /package/dist/{recipes → skills/swarm/recipes}/subagent-artifact.json +0 -0
  170. /package/dist/{recipes → skills/swarm/recipes}/subagent-checkpoint.json +0 -0
  171. /package/dist/{recipes → skills/swarm/recipes}/subagent-conflict-report.json +0 -0
  172. /package/dist/{recipes → skills/swarm/recipes}/subagent-contradiction-map.json +0 -0
  173. /package/dist/{recipes → skills/swarm/recipes}/subagent-critic.json +0 -0
  174. /package/dist/{recipes → skills/swarm/recipes}/subagent-evidence-map.json +0 -0
  175. /package/dist/{recipes → skills/swarm/recipes}/subagent-followup.json +0 -0
  176. /package/dist/{recipes → skills/swarm/recipes}/subagent-judge.json +0 -0
  177. /package/dist/{recipes → skills/swarm/recipes}/subagent-merge.json +0 -0
  178. /package/dist/{recipes → skills/swarm/recipes}/subagent-normalize.json +0 -0
  179. /package/dist/{recipes → skills/swarm/recipes}/subagent-plan.json +0 -0
  180. /package/dist/{recipes → skills/swarm/recipes}/subagent-preflight.json +0 -0
  181. /package/dist/{recipes → skills/swarm/recipes}/subagent-prompt.json +0 -0
  182. /package/dist/{recipes → skills/swarm/recipes}/subagent-review.json +0 -0
  183. /package/dist/{recipes → skills/swarm/recipes}/subagent-task-card.json +0 -0
  184. /package/dist/{recipes → skills/swarm/recipes}/subagent-tools.json +0 -0
  185. /package/dist/{recipes → skills/swarm/recipes}/subagent-verify.json +0 -0
  186. /package/{recipes/utility-validation-wrapper.json → skills/actors/recipes/command-validate.json} +0 -0
  187. /package/{recipes/utility-jsonl-tail.json → skills/actors/recipes/jsonl-tail.json} +0 -0
  188. /package/{recipes/utility-run-state-files.json → skills/actors/recipes/run-state-files.json} +0 -0
  189. /package/{recipes/utility-playlist-scan.json → skills/media/recipes/playlist-scan.json} +0 -0
  190. /package/{recipes/utility-changelog-head.json → skills/project-work/recipes/changelog-head.json} +0 -0
  191. /package/{recipes/utility-git-log.json → skills/project-work/recipes/git-log.json} +0 -0
  192. /package/{recipes/utility-git-status.json → skills/project-work/recipes/git-status.json} +0 -0
  193. /package/{recipes/utility-markdown-index.json → skills/project-work/recipes/markdown-index.json} +0 -0
  194. /package/{recipes → skills/recipe-memory/recipes}/draft-review.json +0 -0
  195. /package/{recipes → skills/recipe-memory/recipes}/tool-review.json +0 -0
  196. /package/{recipes → skills/swarm/recipes}/subagent-artifact.json +0 -0
  197. /package/{recipes → skills/swarm/recipes}/subagent-checkpoint.json +0 -0
  198. /package/{recipes → skills/swarm/recipes}/subagent-conflict-report.json +0 -0
  199. /package/{recipes → skills/swarm/recipes}/subagent-contradiction-map.json +0 -0
  200. /package/{recipes → skills/swarm/recipes}/subagent-critic.json +0 -0
  201. /package/{recipes → skills/swarm/recipes}/subagent-evidence-map.json +0 -0
  202. /package/{recipes → skills/swarm/recipes}/subagent-followup.json +0 -0
  203. /package/{recipes → skills/swarm/recipes}/subagent-judge.json +0 -0
  204. /package/{recipes → skills/swarm/recipes}/subagent-merge.json +0 -0
  205. /package/{recipes → skills/swarm/recipes}/subagent-normalize.json +0 -0
  206. /package/{recipes → skills/swarm/recipes}/subagent-plan.json +0 -0
  207. /package/{recipes → skills/swarm/recipes}/subagent-preflight.json +0 -0
  208. /package/{recipes → skills/swarm/recipes}/subagent-prompt.json +0 -0
  209. /package/{recipes → skills/swarm/recipes}/subagent-review.json +0 -0
  210. /package/{recipes → skills/swarm/recipes}/subagent-task-card.json +0 -0
  211. /package/{recipes → skills/swarm/recipes}/subagent-tools.json +0 -0
  212. /package/{recipes → skills/swarm/recipes}/subagent-verify.json +0 -0
package/AGENTS.md CHANGED
@@ -36,11 +36,11 @@ Pi host
36
36
  -> lib/observability.ts terminal + Trace-attention observation
37
37
  -> lib/inspector*.ts owner-filtered actor-instance inspection
38
38
  -> scripts/*.mjs process/service entrypoints
39
- -> recipes/*.json packaged Recipe library
39
+ -> skills/*/recipes/* Skill-owned Recipe components
40
40
  -> skills/* + docs/* agent and human guidance
41
41
  ```
42
42
 
43
- `index.ts` wires Pi ports and must not own domain behavior. Keep the local TypeScript import graph acyclic.
43
+ `index.ts` wires Pi ports and must not own domain behavior. Keep the local TypeScript import graph acyclic. For architecture-affecting work, load and follow `.agents/skills/domain-dag/SKILL.md`; its validator is local agent tooling, not an npm, CI, or release gate.
44
44
 
45
45
  ## Key Domains
46
46
 
@@ -58,17 +58,20 @@ Pi host
58
58
  - `observability.ts`, `run-ui-runtime.ts`: Trace attention, terminal reconciliation, and Pi follow-up delivery.
59
59
  - automatic draft/tool review domains: structurally redacted model review, journaled mutation, lineage, recovery, and explicit retry/reset safety.
60
60
 
61
- Scripts remain self-contained when no non-script consumer justifies a TypeScript domain. Command-template script leaves infer `.js`/`.mjs` in order through Node, Bun, or `deno run` and `.sh` through Bash without shell evaluation. Helper-backed packaged Recipes self-locate their installed package root while explicit caller values remain authoritative. Recipes stay optional, composable, policy-light, and caller-configurable.
61
+ The bundled Skill Recipe dependency DAG is `artifacts → actors, swarm`, `media → artifacts`, and `project-work → actors, artifacts, swarm`; `actors`, `swarm`, and `recipe-memory` have no cross-Skill Recipe dependencies.
62
+
63
+ Scripts remain self-contained when no non-script consumer justifies a TypeScript domain. Command-template script leaves infer `.js`/`.mjs` in order through Node, Bun, or `deno run` and `.sh` through Bash without shell evaluation. Helper-backed Skill Recipes self-locate through runtime-owned `{skill_dir}`. Recipes stay optional, composable, policy-light, and caller-configurable.
62
64
 
63
65
  ## Operating Principles
64
66
 
65
67
  ### Recipe
66
68
 
69
+ - Skill Recipe identity is `<active Skill name>/<Recipe filename stem>`; Recipe files have no top-level `name`. `SKILL.md` `name` is Pi host metadata matching the Skill directory, not a second pi-actors identity field.
67
70
  - Recipe files may define args/defaults, imports, artifacts, command-template flags, and `control`.
68
71
  - Declare actor-local actions only when a long-lived process implements them.
69
72
  - Actions are lowercase, unique, and cannot use runtime-reserved lifecycle names.
70
73
  - Removed communication-plane metadata fails explicitly; never translate it.
71
- - User Recipes shadow packaged definitions; invalid shadowing blocks fallback.
74
+ - User Recipes are discovered only from the persistent user registry; Skill Recipes are exact components outside tool discovery. Explicit entry paths resolve from invocation `cwd`; relative imports resolve from their importing file.
72
75
  - Files over 1 MiB, import depth over 32, and import cycles fail closed.
73
76
 
74
77
  ### Trace
@@ -136,11 +139,10 @@ When a deferred Run result gates the next step, wait for its terminal follow-up.
136
139
  ## Documentation and Release Discipline
137
140
 
138
141
  - Keep published text portable: use `~`, `<repo>`, or relative paths.
139
- - Keep executable JavaScript and TypeScript blocks compact: no blank lines inside function bodies or control-flow blocks. Structural object, type, interface, class, and module bodies are exempt.
140
142
  - Update `skills/actors/SKILL.md` when durable operating mechanics change.
141
143
  - Keep `skills/swarm/SKILL.md` focused on multi-agent methodology rather than kernel internals.
142
- - Recipe `description` is optional because discovery supplies stable fallback tool copy; packaged Recipe QA must report zero diagnostics and zero release-blocking warnings without component boilerplate.
143
- - Before release run build, full tests, preservation tests, Recipe QA, Domain DAG validation, ABCd context validation, line-count gates, and release gates.
144
+ - Recipe `description` is optional. Skill Recipe QA recursively validates direct filesystem-owned components and capability semantics with zero diagnostics or warnings; it does not enforce aesthetics or architecture policy.
145
+ - Before release run the normal product validation and dependency audit. Use the project-local Domain DAG Skill during architecture-affecting development, not as publication automation.
144
146
  - `.github/workflows/release.yml` owns the immutable sequence reusable validation → npm Trusted Publisher publication/verification → GitHub Release convergence; follow [docs/releasing.md](docs/releasing.md).
145
147
  - Keep npm publication tokenless: use the exact npm Trusted Publisher binding and job-scoped OIDC permission, never a long-lived npm token or token fallback.
146
148
  - Until a stable version beyond `1.x`, prefer clean breaking simplification over compatibility aliases or renamed legacy abstractions.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Changelog
2
2
 
3
- > Each release keeps at most 8 outcome records of at most 512 characters.
3
+ ## 0.46.0: Skill-Owned Capability Packs
4
+
5
+ - `Breaking Recipe Grammar`: File-backed identity now comes only from the filename; top-level Recipe `name`, nested Skill identities, JSON/Markdown stem collisions, bare references, and the old `std:` / `skill:` prefixes fail with migration guidance. Composition accepts exact `<active-skill>/<stem>` references or explicit `.json` / `.md` paths, with entry paths based at invocation cwd and relative imports based at their owning Recipe.
6
+ - `Skill-Owned Distribution`: All 58 bundled components move from the root Recipe library into six flat Pi Skills—Actors, Artifacts, Media, Project Work, Recipe Memory, and Swarm—with 67 explicit imports and an acyclic cross-Skill graph. Root and `dist` Recipe libraries, package-root discovery, fallback/shadowing, wrapper installation, and obsolete root capability helpers are removed; Skill components never auto-register as tools.
7
+ - `Scoped Resolution and Provenance`: Immutable active-Skill contexts are session-scoped and captured per Run. Recipe inspection distinguishes user registry capabilities, active Skill components, and explicit files while recording entry/import roles, filename stems, logical identities, Skill ownership, and alias ancestry without exposing private `source_file`, `{skill_dir}`, or `{recipe_dir}` values to model/Inspector surfaces.
8
+ - `Capability Safety`: Automatic review resolves exact package-owned `recipe-memory/*` components so user files cannot redirect reviewers. Helpers self-locate through runtime-owned `{skill_dir}`; Control, Trace, lifecycle fencing, review transactions, and the public `spawn`, `message`, `inspect`, `register_tool` plus Recipe/Trace/Control view contracts remain unchanged.
9
+ - `Validation and Architecture`: Recursive Skill QA validates direct identity, parse/import semantics, origins, Control, portable paths, and helper targets in source and installed packages. The custom release-gate and executable-style policy scanners are removed; CI runs product validation plus dependency audit, while a non-packaged project-local Domain DAG Skill supports architecture work without becoming a release gate.
10
+ - `Dogfood and Migration`: Source and installed tests execute repository health, release readiness, quorum review, artifact bundle, media player, and package-owned draft review through qualified Skill references, plus relative/absolute file imports and all breaking failures. Migrate `std:foo` to `owning-skill/foo`, `skill:foo/bar` to `foo/bar`, root Recipes to their owning Skill filename, and delete Recipe `name` fields.
4
11
 
5
12
  ## 0.45.1: Entrypoint and Release Policy
6
13
 
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
 
@@ -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
  }
@@ -98,7 +98,10 @@ export interface AsyncRunMeta {
98
98
  export { safeRunId } from "./runs-identity.ts";
99
99
  export { resolveArtifactManifest } from "./runs-artifacts.ts";
100
100
  export type { RunArtifactDeclaration, RunArtifactManifestEntry, } from "./runs-artifacts.ts";
101
- export declare function startRun(params: AsyncRunStartParams, cwd: string): AsyncRunMeta;
101
+ export interface AsyncRunStartOptions {
102
+ skillContext?: RecipesReferences.ActiveSkillRecipeContext;
103
+ }
104
+ export declare function startRun(params: AsyncRunStartParams, cwd: string, options?: AsyncRunStartOptions): AsyncRunMeta;
102
105
  export declare function getRunStatus(runOrDir: string): Record<string, unknown>;
103
106
  export type { RunStateIndexEntry } from "./runs-index.ts";
104
107
  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) &&
@@ -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))
@@ -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): {
@@ -16,7 +16,10 @@ import * as Tools from "./tools.js";
16
16
  import * as ToolsResponse from "./tools-response.js";
17
17
  export function createActorExtensionRuntime(pi) {
18
18
  let activeRunContext;
19
+ const skillContextsBySession = new Map();
19
20
  const getRunOwnerId = Pi.getSessionId;
21
+ const getSkillContext = (ctx) => skillContextsBySession.get(getRunOwnerId(ctx)) ??
22
+ RecipesReferences.EMPTY_ACTIVE_SKILL_RECIPE_CONTEXT;
20
23
  const automaticReview = AutomaticReviewRuntime.createAutomaticReviewRuntime({
21
24
  getActiveContext: () => activeRunContext,
22
25
  getRunOwnerId,
@@ -41,6 +44,7 @@ export function createActorExtensionRuntime(pi) {
41
44
  if (ctx && typeof ctx === "object") {
42
45
  nextArgs[4] = {
43
46
  ...ctx,
47
+ activeSkillRecipeContext: getSkillContext(ctx),
44
48
  getThinkingLevel: () => pi.getThinkingLevel(),
45
49
  };
46
50
  }
@@ -67,8 +71,8 @@ export function createActorExtensionRuntime(pi) {
67
71
  });
68
72
  const recipeReload = Runtime.createRecipeToolReloadWatcher(runtime);
69
73
  return {
70
- beforeAgentStart(systemPrompt, skills) {
71
- RecipesReferences.setActiveSkillRecipeSources(skills);
74
+ beforeAgentStart(systemPrompt, skills, ctx) {
75
+ skillContextsBySession.set(getRunOwnerId(ctx), RecipesReferences.createActiveSkillRecipeContext(skills));
72
76
  return {
73
77
  systemPrompt: `${systemPrompt}\n\n${Prompts.ONBOARDING_SYSTEM_PROMPT}`,
74
78
  };
@@ -83,12 +87,14 @@ export function createActorExtensionRuntime(pi) {
83
87
  automaticReview.schedule();
84
88
  },
85
89
  onSessionShutdown(reason, ctx) {
90
+ skillContextsBySession.delete(getRunOwnerId(ctx));
86
91
  activeRunContext = undefined;
87
92
  automaticReview.close();
88
93
  recipeReload.close();
89
94
  runUiRuntime.shutdown(reason, ctx);
90
95
  },
91
96
  async onSessionStart(ctx) {
97
+ skillContextsBySession.set(getRunOwnerId(ctx), RecipesReferences.EMPTY_ACTIVE_SKILL_RECIPE_CONTEXT);
92
98
  ctx.ui.setWidget("zz-pi-actors-comms", undefined);
93
99
  activeRunContext = ctx;
94
100
  runUiRuntime.close();
@@ -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,27 @@ 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,
80
118
  launch_source: meta.launch_source,
81
119
  }),
82
120
  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: 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; 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.";
@@ -24,8 +24,8 @@ export const ONBOARDING_SYSTEM_PROMPT = `pi-actors quick model:
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')",
@@ -78,7 +78,7 @@ export function findPiPrintPromptIndex(args) {
78
78
  function matchesActorContext(record, context) {
79
79
  if (!context)
80
80
  return record.role === "entry";
81
- if (context.file && context.file === record.file)
81
+ if (context.file && context.file === record.source_file)
82
82
  return true;
83
83
  if (context.name && context.name === record.name)
84
84
  return true;
@@ -105,7 +105,7 @@ export function markRecipeContextRecords(records, context) {
105
105
  }
106
106
  export function formatRecipeContextJsonl(records, context) {
107
107
  return markRecipeContextRecords(records, context)
108
- .map((record) => JSON.stringify(record))
108
+ .map(({ source_file: _sourceFile, ...record }) => JSON.stringify(record))
109
109
  .join("\n");
110
110
  }
111
111
  export function buildRecipeContextPromptBlock(records, context) {