@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
@@ -12,6 +12,7 @@ import { join } from "node:path";
12
12
  import * as CommandTemplates from "./command-templates.ts";
13
13
  import type { RegisteredTool } from "./config.ts";
14
14
  import * as ModelContext from "./model-context.ts";
15
+ import type { RecipeResolutionContext } from "./recipes-context.ts";
15
16
  import type { TemplateRecipeConfig } from "./recipes-references.ts";
16
17
  import * as RecipesReferences from "./recipes-references.ts";
17
18
  import * as RecipesUsage from "./recipes-usage.ts";
@@ -29,6 +30,7 @@ export interface DiscoveredRecipe {
29
30
  disabled: boolean;
30
31
  tool: boolean;
31
32
  mutableUsage: boolean;
33
+ resolutionContext?: RecipeResolutionContext;
32
34
  diagnostics: string[];
33
35
  riskLabels: CommandTemplates.CommandTemplateRiskLabel[];
34
36
  shadows: string[];
@@ -58,6 +60,22 @@ export interface RecipesDiscoverySource {
58
60
  file?: string;
59
61
  defaultTool?: boolean;
60
62
  mutableUsage?: boolean;
63
+ resolutionContext?: RecipeResolutionContext;
64
+ }
65
+
66
+ export interface UserRecipeAdmission {
67
+ args?: string[];
68
+ argTypes?: RegisteredTool["argTypes"];
69
+ artifacts?: Record<string, string>;
70
+ async?: boolean;
71
+ control?: string[];
72
+ defaults?: Record<string, unknown>;
73
+ diagnostics: string[];
74
+ effectiveRecipe?: TemplateRecipeConfig;
75
+ identity: string;
76
+ sourcePath: string;
77
+ tool?: RegisteredTool;
78
+ validated: boolean;
61
79
  }
62
80
 
63
81
  function assertToolSafeRepeatConfig(
@@ -185,10 +203,13 @@ function readDiscoveredRecipe(
185
203
  priority: number,
186
204
  defaultTool = false,
187
205
  mutableUsage = false,
206
+ resolutionContext?: RecipeResolutionContext,
188
207
  ): DiscoveredRecipe {
189
208
  const id = RecipesReferences.getRecipeIdFromPath(file);
190
209
  try {
191
- const config = RecipesReferences.readResolvedRecipeConfig(file);
210
+ const config = RecipesReferences.readResolvedRecipeConfig(file, [], {
211
+ skillContext: resolutionContext?.activeSkills,
212
+ });
192
213
  const invalid = !config;
193
214
  const disabled = config?.disabled === true;
194
215
  return {
@@ -203,6 +224,7 @@ function readDiscoveredRecipe(
203
224
  disabled,
204
225
  tool: defaultTool && !disabled && !invalid,
205
226
  mutableUsage,
227
+ resolutionContext,
206
228
  diagnostics: getRecipeConfigDiagnostics(file, config),
207
229
  riskLabels: getRecipeRiskLabels(config),
208
230
  shadows: [],
@@ -219,6 +241,7 @@ function readDiscoveredRecipe(
219
241
  disabled: false,
220
242
  tool: false,
221
243
  mutableUsage,
244
+ resolutionContext,
222
245
  diagnostics: [
223
246
  `Failed to load recipe ${file}: ${error instanceof Error ? error.message : String(error)}`,
224
247
  ],
@@ -233,6 +256,7 @@ function filesForSource(source: RecipesDiscoverySource): Array<{
233
256
  file: string;
234
257
  defaultTool: boolean;
235
258
  mutableUsage: boolean;
259
+ resolutionContext?: RecipeResolutionContext;
236
260
  }> {
237
261
  const defaultTool = source.defaultTool === true;
238
262
  const mutableUsage = source.mutableUsage === true;
@@ -243,6 +267,7 @@ function filesForSource(source: RecipesDiscoverySource): Array<{
243
267
  file: source.file,
244
268
  defaultTool,
245
269
  mutableUsage,
270
+ resolutionContext: source.resolutionContext,
246
271
  },
247
272
  ];
248
273
  return source.root
@@ -251,6 +276,7 @@ function filesForSource(source: RecipesDiscoverySource): Array<{
251
276
  file,
252
277
  defaultTool,
253
278
  mutableUsage,
279
+ resolutionContext: source.resolutionContext,
254
280
  }))
255
281
  : [];
256
282
  }
@@ -338,8 +364,16 @@ export function discoverRecipeSources(
338
364
  sources: RecipesDiscoverySource[],
339
365
  ): RecipesDiscoveryResult {
340
366
  const entries = sources.flatMap((source, priority) =>
341
- filesForSource(source).map(({ root, file, defaultTool, mutableUsage }) =>
342
- readDiscoveredRecipe(root, file, priority, defaultTool, mutableUsage),
367
+ filesForSource(source).map(
368
+ ({ root, file, defaultTool, mutableUsage, resolutionContext }) =>
369
+ readDiscoveredRecipe(
370
+ root,
371
+ file,
372
+ priority,
373
+ defaultTool,
374
+ mutableUsage,
375
+ resolutionContext,
376
+ ),
343
377
  ),
344
378
  );
345
379
  const byId = new Map<string, DiscoveredRecipe[]>();
@@ -836,14 +870,13 @@ export function summarizeDiscovery(
836
870
  };
837
871
  }
838
872
 
839
- export function toRegisteredTool(
840
- entry: DiscoveredRecipe,
841
- ): RegisteredTool | undefined {
842
- if (!entry.tool || entry.invalid || entry.disabled || !entry.config)
843
- return undefined;
844
- const cfg = entry.config;
845
- const template = entry.path;
846
- const description = cfg.description ?? `Execute template recipe: ${entry.id}`;
873
+ function projectRegisteredTool(
874
+ identity: string,
875
+ path: string,
876
+ cfg: TemplateRecipeConfig,
877
+ mutableUsage: boolean,
878
+ ): RegisteredTool {
879
+ const description = cfg.description ?? `Execute template recipe: ${identity}`;
847
880
  const argTemplate = cfg.template;
848
881
  const argTemplateConfig =
849
882
  typeof argTemplate === "object" && !Array.isArray(argTemplate)
@@ -867,27 +900,38 @@ export function toRegisteredTool(
867
900
  explicitArgTypes,
868
901
  { ...(cfg.defaults ?? {}), ...(cfg.values ?? {}) },
869
902
  );
870
- const argTypes = Schema.getTemplateArgTypes(argTemplateConfig);
871
- Schema.assertCompatibleToolArgTypes(explicitArgTypes, argTypes);
903
+ const inferredArgTypes = Schema.getTemplateArgTypes(argTemplateConfig);
904
+ Schema.assertCompatibleToolArgTypes(explicitArgTypes, inferredArgTypes);
905
+ const effectiveArgTypes = { ...inferredArgTypes, ...explicitArgTypes };
906
+ const args = Schema.getToolArgNames(argTemplateConfig).filter(
907
+ (arg) => !RecipesReferences.isRuntimeOwnedRecipeInput(arg),
908
+ );
909
+ const callerArgSet = new Set(args);
910
+ const argTypes = Object.fromEntries(
911
+ Object.entries(effectiveArgTypes).filter(([arg]) => callerArgSet.has(arg)),
912
+ );
913
+ const defaults = Object.fromEntries(
914
+ Object.entries(cfg.defaults ?? {}).filter(([arg]) => callerArgSet.has(arg)),
915
+ );
916
+ const storedArgs = cfg.args?.filter((arg) =>
917
+ callerArgSet.has(Schema.parseToolArgToken(String(arg)).arg),
918
+ );
872
919
  return {
873
- name: entry.id,
920
+ name: identity,
874
921
  description,
875
- template,
922
+ template: path,
876
923
  recipe: cfg,
877
- args: Schema.getToolArgNames(argTemplateConfig),
924
+ args,
878
925
  defaults: Object.fromEntries(
879
- Object.entries(cfg.defaults ?? {}).map(([key, value]) => [
880
- key,
881
- String(value),
882
- ]),
926
+ Object.entries(defaults).map(([key, value]) => [key, String(value)]),
883
927
  ),
884
928
  ...(Object.keys(argTypes).length > 0 ? { argTypes } : {}),
885
- ...(entry.mutableUsage ? { sourcePath: entry.path } : {}),
886
- ...(cfg.args ? { storedArgs: cfg.args } : {}),
887
- ...(cfg.defaults
929
+ ...(mutableUsage ? { sourcePath: path } : {}),
930
+ ...(storedArgs ? { storedArgs } : {}),
931
+ ...(Object.keys(defaults).length > 0
888
932
  ? {
889
933
  storedDefaults: Object.fromEntries(
890
- Object.entries(cfg.defaults).map(([key, value]) => [
934
+ Object.entries(defaults).map(([key, value]) => [
891
935
  key,
892
936
  String(value),
893
937
  ]),
@@ -896,3 +940,99 @@ export function toRegisteredTool(
896
940
  : {}),
897
941
  };
898
942
  }
943
+
944
+ function boundedAdmissionDiagnostic(error: unknown): string {
945
+ const message = error instanceof Error ? error.message : String(error);
946
+ return message.length <= 4096 ? message : `${message.slice(0, 4095)}…`;
947
+ }
948
+
949
+ export function admitUserRecipe(
950
+ sourcePath: string,
951
+ resolutionContext: RecipeResolutionContext,
952
+ authoredRecipe?: Record<string, unknown>,
953
+ mutableUsage = true,
954
+ ): UserRecipeAdmission {
955
+ const identity = RecipesReferences.getRecipeIdFromPath(sourcePath);
956
+ try {
957
+ const effectiveRecipe = RecipesReferences.readResolvedRecipeConfig(
958
+ sourcePath,
959
+ [],
960
+ {
961
+ ...(authoredRecipe
962
+ ? { authoredEntry: { path: sourcePath, recipe: authoredRecipe } }
963
+ : {}),
964
+ skillContext: resolutionContext.activeSkills,
965
+ },
966
+ );
967
+ if (!effectiveRecipe) {
968
+ return {
969
+ diagnostics: [
970
+ authoredRecipe
971
+ ? "Recipe must define a valid template."
972
+ : RecipesReferences.diagnoseRawRecipeConfigFailure(sourcePath) ??
973
+ "Recipe must define a valid template.",
974
+ ],
975
+ identity,
976
+ sourcePath,
977
+ validated: false,
978
+ };
979
+ }
980
+ if (effectiveRecipe.disabled === true) {
981
+ return {
982
+ diagnostics: ["Recipe is disabled."],
983
+ effectiveRecipe,
984
+ identity,
985
+ sourcePath,
986
+ validated: false,
987
+ };
988
+ }
989
+ const tool = projectRegisteredTool(
990
+ identity,
991
+ sourcePath,
992
+ effectiveRecipe,
993
+ mutableUsage,
994
+ );
995
+ return {
996
+ args: tool.args,
997
+ argTypes: tool.argTypes,
998
+ artifacts: effectiveRecipe.artifacts,
999
+ async: effectiveRecipe.async === true,
1000
+ control: effectiveRecipe.control,
1001
+ defaults: effectiveRecipe.defaults,
1002
+ diagnostics: [],
1003
+ effectiveRecipe,
1004
+ identity,
1005
+ sourcePath,
1006
+ tool,
1007
+ validated: true,
1008
+ };
1009
+ } catch (error) {
1010
+ return {
1011
+ diagnostics: [boundedAdmissionDiagnostic(error)],
1012
+ identity,
1013
+ sourcePath,
1014
+ validated: false,
1015
+ };
1016
+ }
1017
+ }
1018
+
1019
+ export function toRegisteredTool(
1020
+ entry: DiscoveredRecipe,
1021
+ ): RegisteredTool | undefined {
1022
+ if (!entry.tool || entry.invalid || entry.disabled || !entry.config)
1023
+ return undefined;
1024
+ if (entry.resolutionContext) {
1025
+ return admitUserRecipe(
1026
+ entry.path,
1027
+ entry.resolutionContext,
1028
+ undefined,
1029
+ entry.mutableUsage,
1030
+ ).tool;
1031
+ }
1032
+ return projectRegisteredTool(
1033
+ entry.id,
1034
+ entry.path,
1035
+ entry.config,
1036
+ entry.mutableUsage,
1037
+ );
1038
+ }