agentplane 0.3.11 → 0.3.13

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 (259) hide show
  1. package/assets/AGENTS.md +2 -2
  2. package/assets/RUNNER.md +1 -1
  3. package/assets/agents/CODER.json +4 -0
  4. package/assets/agents/CREATOR.json +1 -0
  5. package/assets/agents/DOCS.json +2 -1
  6. package/assets/agents/INTEGRATOR.json +2 -1
  7. package/assets/agents/ORCHESTRATOR.json +3 -1
  8. package/assets/agents/PLANNER.json +3 -1
  9. package/assets/agents/REVIEWER.json +1 -0
  10. package/assets/agents/TESTER.json +2 -2
  11. package/assets/agents/UPDATER.json +1 -0
  12. package/assets/agents/UPGRADER.json +1 -1
  13. package/assets/codex-plugin/assets/header.png +0 -0
  14. package/assets/codex-plugin/assets/icon.svg +1 -0
  15. package/assets/codex-plugin/assets/logo.svg +1 -0
  16. package/assets/codex-plugin/skills/agentplane/SKILL.md +35 -0
  17. package/assets/policy/governance.md +4 -2
  18. package/assets/policy/incidents.md +3 -19
  19. package/assets/policy/workflow.release.md +5 -2
  20. package/bin/agentplane.js +58 -3
  21. package/bin/stale-dist-policy.js +6 -1
  22. package/dist/.build-manifest.json +271 -161
  23. package/dist/cli/exit-codes.d.ts.map +1 -1
  24. package/dist/cli/exit-codes.js +1 -0
  25. package/dist/cli/reason-codes.d.ts +1 -1
  26. package/dist/cli/reason-codes.d.ts.map +1 -1
  27. package/dist/cli/reason-codes.js +12 -0
  28. package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
  29. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
  30. package/dist/cli/run-cli/command-catalog/core.js +22 -1
  31. package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
  32. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
  33. package/dist/cli/run-cli/command-catalog/project.js +21 -3
  34. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  35. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  36. package/dist/cli/run-cli/commands/codex.d.ts +14 -0
  37. package/dist/cli/run-cli/commands/codex.d.ts.map +1 -0
  38. package/dist/cli/run-cli/commands/codex.js +100 -0
  39. package/dist/cli/run-cli/commands/core.d.ts +1 -0
  40. package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
  41. package/dist/cli/run-cli/commands/core.js +1 -0
  42. package/dist/cli/run-cli/commands/init/recipes.d.ts +9 -1
  43. package/dist/cli/run-cli/commands/init/recipes.d.ts.map +1 -1
  44. package/dist/cli/run-cli/commands/init/recipes.js +32 -22
  45. package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
  46. package/dist/cli/run-cli/commands/init.js +26 -21
  47. package/dist/cli/run-cli/error-guidance.js +20 -0
  48. package/dist/cli/run-cli.test-helpers.d.ts +1 -0
  49. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  50. package/dist/cli/run-cli.test-helpers.js +36 -19
  51. package/dist/commands/branch/cleanup-merged.d.ts +1 -0
  52. package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
  53. package/dist/commands/branch/cleanup-merged.js +18 -9
  54. package/dist/commands/branch/work-start.d.ts.map +1 -1
  55. package/dist/commands/branch/work-start.js +82 -5
  56. package/dist/commands/codex/plugin-install.d.ts +26 -0
  57. package/dist/commands/codex/plugin-install.d.ts.map +1 -0
  58. package/dist/commands/codex/plugin-install.js +209 -0
  59. package/dist/commands/doctor/branch-pr.js +2 -2
  60. package/dist/commands/guard/impl/commands.d.ts +1 -0
  61. package/dist/commands/guard/impl/commands.d.ts.map +1 -1
  62. package/dist/commands/guard/impl/commands.js +78 -8
  63. package/dist/commands/hooks/index.d.ts +1 -1
  64. package/dist/commands/hooks/index.d.ts.map +1 -1
  65. package/dist/commands/hooks/index.js +48 -12
  66. package/dist/commands/pr/check.d.ts.map +1 -1
  67. package/dist/commands/pr/check.js +3 -0
  68. package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
  69. package/dist/commands/pr/integrate/cmd.js +103 -2
  70. package/dist/commands/pr/integrate/internal/cleanup.d.ts +1 -11
  71. package/dist/commands/pr/integrate/internal/cleanup.d.ts.map +1 -1
  72. package/dist/commands/pr/integrate/internal/cleanup.js +1 -46
  73. package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
  74. package/dist/commands/pr/integrate/internal/finalize.js +3 -0
  75. package/dist/commands/pr/integrate/internal/github-protection.d.ts +5 -0
  76. package/dist/commands/pr/integrate/internal/github-protection.d.ts.map +1 -0
  77. package/dist/commands/pr/integrate/internal/github-protection.js +13 -0
  78. package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts +15 -0
  79. package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts.map +1 -0
  80. package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.js +35 -0
  81. package/dist/commands/pr/integrate/internal/prepare.d.ts +1 -0
  82. package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
  83. package/dist/commands/pr/integrate/internal/prepare.js +46 -7
  84. package/dist/commands/pr/internal/auto-commit.d.ts +7 -0
  85. package/dist/commands/pr/internal/auto-commit.d.ts.map +1 -0
  86. package/dist/commands/pr/internal/auto-commit.js +69 -0
  87. package/dist/commands/pr/internal/freshness.d.ts +1 -0
  88. package/dist/commands/pr/internal/freshness.d.ts.map +1 -1
  89. package/dist/commands/pr/internal/freshness.js +2 -0
  90. package/dist/commands/pr/internal/sync.d.ts.map +1 -1
  91. package/dist/commands/pr/internal/sync.js +98 -27
  92. package/dist/commands/pr/open.d.ts.map +1 -1
  93. package/dist/commands/pr/open.js +52 -3
  94. package/dist/commands/pr/update.d.ts.map +1 -1
  95. package/dist/commands/pr/update.js +13 -2
  96. package/dist/commands/recipes/active.command.d.ts +7 -0
  97. package/dist/commands/recipes/active.command.d.ts.map +1 -0
  98. package/dist/commands/recipes/active.command.js +12 -0
  99. package/dist/commands/recipes/add.command.d.ts +8 -0
  100. package/dist/commands/recipes/add.command.d.ts.map +1 -0
  101. package/dist/commands/recipes/add.command.js +33 -0
  102. package/dist/commands/recipes/detach.command.d.ts +7 -0
  103. package/dist/commands/recipes/detach.command.d.ts.map +1 -0
  104. package/dist/commands/recipes/detach.command.js +19 -0
  105. package/dist/commands/recipes/disable.command.d.ts +7 -0
  106. package/dist/commands/recipes/disable.command.d.ts.map +1 -0
  107. package/dist/commands/recipes/disable.command.js +10 -0
  108. package/dist/commands/recipes/enable.command.d.ts +7 -0
  109. package/dist/commands/recipes/enable.command.d.ts.map +1 -0
  110. package/dist/commands/recipes/enable.command.js +10 -0
  111. package/dist/commands/recipes/explain-active.command.d.ts +5 -0
  112. package/dist/commands/recipes/explain-active.command.d.ts.map +1 -0
  113. package/dist/commands/recipes/explain-active.command.js +11 -0
  114. package/dist/commands/recipes/explain.command.d.ts.map +1 -1
  115. package/dist/commands/recipes/explain.command.js +4 -2
  116. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  117. package/dist/commands/recipes/impl/apply.js +33 -14
  118. package/dist/commands/recipes/impl/commands/active.d.ts +6 -0
  119. package/dist/commands/recipes/impl/commands/active.d.ts.map +1 -0
  120. package/dist/commands/recipes/impl/commands/active.js +46 -0
  121. package/dist/commands/recipes/impl/commands/add.d.ts +7 -0
  122. package/dist/commands/recipes/impl/commands/add.d.ts.map +1 -0
  123. package/dist/commands/recipes/impl/commands/add.js +100 -0
  124. package/dist/commands/recipes/impl/commands/detach.d.ts +6 -0
  125. package/dist/commands/recipes/impl/commands/detach.d.ts.map +1 -0
  126. package/dist/commands/recipes/impl/commands/detach.js +85 -0
  127. package/dist/commands/recipes/impl/commands/disable.d.ts +6 -0
  128. package/dist/commands/recipes/impl/commands/disable.d.ts.map +1 -0
  129. package/dist/commands/recipes/impl/commands/disable.js +21 -0
  130. package/dist/commands/recipes/impl/commands/enable.d.ts +6 -0
  131. package/dist/commands/recipes/impl/commands/enable.d.ts.map +1 -0
  132. package/dist/commands/recipes/impl/commands/enable.js +39 -0
  133. package/dist/commands/recipes/impl/commands/explain-active.d.ts +5 -0
  134. package/dist/commands/recipes/impl/commands/explain-active.d.ts.map +1 -0
  135. package/dist/commands/recipes/impl/commands/explain-active.js +20 -0
  136. package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
  137. package/dist/commands/recipes/impl/commands/explain.js +40 -3
  138. package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
  139. package/dist/commands/recipes/impl/commands/info.js +21 -8
  140. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  141. package/dist/commands/recipes/impl/commands/install.js +32 -29
  142. package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
  143. package/dist/commands/recipes/impl/commands/list.js +11 -11
  144. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  145. package/dist/commands/recipes/impl/commands/remove.js +5 -0
  146. package/dist/commands/recipes/impl/commands/update.d.ts +7 -0
  147. package/dist/commands/recipes/impl/commands/update.d.ts.map +1 -0
  148. package/dist/commands/recipes/impl/commands/update.js +93 -0
  149. package/dist/commands/recipes/impl/commands.d.ts +7 -0
  150. package/dist/commands/recipes/impl/commands.d.ts.map +1 -1
  151. package/dist/commands/recipes/impl/commands.js +7 -0
  152. package/dist/commands/recipes/impl/constants.d.ts +1 -14
  153. package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
  154. package/dist/commands/recipes/impl/constants.js +1 -18
  155. package/dist/commands/recipes/impl/manifest.d.ts +2 -2
  156. package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
  157. package/dist/commands/recipes/impl/manifest.js +4 -226
  158. package/dist/commands/recipes/impl/overlay-project.d.ts +32 -0
  159. package/dist/commands/recipes/impl/overlay-project.d.ts.map +1 -0
  160. package/dist/commands/recipes/impl/overlay-project.js +282 -0
  161. package/dist/commands/recipes/impl/paths.d.ts +20 -2
  162. package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
  163. package/dist/commands/recipes/impl/paths.js +23 -5
  164. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +2 -4
  165. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -1
  166. package/dist/commands/recipes/impl/project-installed-recipes.js +30 -74
  167. package/dist/commands/recipes/impl/project-recipe-state.d.ts +18 -0
  168. package/dist/commands/recipes/impl/project-recipe-state.d.ts.map +1 -0
  169. package/dist/commands/recipes/impl/project-recipe-state.js +94 -0
  170. package/dist/commands/recipes/impl/project-registry.d.ts +20 -0
  171. package/dist/commands/recipes/impl/project-registry.d.ts.map +1 -0
  172. package/dist/commands/recipes/impl/project-registry.js +104 -0
  173. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -1
  174. package/dist/commands/recipes/impl/resolver.js +5 -3
  175. package/dist/commands/recipes/impl/types.d.ts +1 -240
  176. package/dist/commands/recipes/impl/types.d.ts.map +1 -1
  177. package/dist/commands/recipes/info.command.js +2 -2
  178. package/dist/commands/recipes/install.spec.js +4 -4
  179. package/dist/commands/recipes/list.command.js +4 -4
  180. package/dist/commands/recipes/remove.command.js +2 -2
  181. package/dist/commands/recipes/update.command.d.ts +8 -0
  182. package/dist/commands/recipes/update.command.d.ts.map +1 -0
  183. package/dist/commands/recipes/update.command.js +35 -0
  184. package/dist/commands/recipes.d.ts +7 -4
  185. package/dist/commands/recipes.d.ts.map +1 -1
  186. package/dist/commands/recipes.js +6 -3
  187. package/dist/commands/recipes.test-helpers.d.ts +3 -3
  188. package/dist/commands/recipes.test-helpers.d.ts.map +1 -1
  189. package/dist/commands/recipes.test-helpers.js +105 -15
  190. package/dist/commands/release/apply.command.d.ts +3 -1
  191. package/dist/commands/release/apply.command.d.ts.map +1 -1
  192. package/dist/commands/release/apply.command.js +354 -18
  193. package/dist/commands/release/apply.mutation.d.ts.map +1 -1
  194. package/dist/commands/release/apply.mutation.js +1 -0
  195. package/dist/commands/release/apply.reporting.d.ts +1 -0
  196. package/dist/commands/release/apply.reporting.d.ts.map +1 -1
  197. package/dist/commands/release/apply.reporting.js +12 -8
  198. package/dist/commands/release/apply.types.d.ts +13 -0
  199. package/dist/commands/release/apply.types.d.ts.map +1 -1
  200. package/dist/commands/release/plan.command.d.ts.map +1 -1
  201. package/dist/commands/release/plan.command.js +48 -0
  202. package/dist/commands/scenario/execute.command.js +4 -4
  203. package/dist/commands/scenario/impl/commands.js +4 -4
  204. package/dist/commands/scenario/info.command.js +4 -4
  205. package/dist/commands/scenario/list.command.js +3 -3
  206. package/dist/commands/scenario/run.command.js +5 -5
  207. package/dist/commands/scenario/scenario.command.js +7 -7
  208. package/dist/commands/shared/merged-branch-cleanup.d.ts +12 -0
  209. package/dist/commands/shared/merged-branch-cleanup.d.ts.map +1 -0
  210. package/dist/commands/shared/merged-branch-cleanup.js +46 -0
  211. package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -1
  212. package/dist/commands/shared/post-commit-pr-artifacts.js +35 -0
  213. package/dist/commands/shared/task-backend.d.ts.map +1 -1
  214. package/dist/commands/shared/task-backend.js +37 -5
  215. package/dist/commands/shared/task-handoff.d.ts +2 -1
  216. package/dist/commands/shared/task-handoff.d.ts.map +1 -1
  217. package/dist/commands/shared/task-handoff.js +15 -0
  218. package/dist/commands/shared/task-local-freshness.d.ts +2 -0
  219. package/dist/commands/shared/task-local-freshness.d.ts.map +1 -1
  220. package/dist/commands/shared/task-local-freshness.js +7 -1
  221. package/dist/commands/task/finish-shared.d.ts +1 -0
  222. package/dist/commands/task/finish-shared.d.ts.map +1 -1
  223. package/dist/commands/task/finish-shared.js +1 -0
  224. package/dist/commands/task/handoff-show.command.d.ts.map +1 -1
  225. package/dist/commands/task/handoff-show.command.js +24 -0
  226. package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -1
  227. package/dist/commands/task/hosted-close-pr.command.js +35 -0
  228. package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
  229. package/dist/commands/task/hosted-close.command.js +185 -18
  230. package/dist/commands/task/hosted-merge-sync.d.ts +4 -1
  231. package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
  232. package/dist/commands/task/hosted-merge-sync.js +52 -10
  233. package/dist/commands/task/start-ready.d.ts.map +1 -1
  234. package/dist/commands/task/start-ready.js +0 -86
  235. package/dist/runner/context/base-prompts.d.ts +2 -1
  236. package/dist/runner/context/base-prompts.d.ts.map +1 -1
  237. package/dist/runner/context/base-prompts.js +109 -13
  238. package/dist/runner/context/recipe-context.d.ts.map +1 -1
  239. package/dist/runner/context/recipe-context.js +40 -8
  240. package/dist/runner/types.d.ts +4 -0
  241. package/dist/runner/types.d.ts.map +1 -1
  242. package/dist/runner/usecases/task-run.d.ts.map +1 -1
  243. package/dist/runner/usecases/task-run.js +2 -1
  244. package/dist/runtime/behavior/resolve.d.ts +2 -1
  245. package/dist/runtime/behavior/resolve.d.ts.map +1 -1
  246. package/dist/runtime/behavior/resolve.js +25 -5
  247. package/dist/runtime/behavior/types.d.ts +1 -0
  248. package/dist/runtime/behavior/types.d.ts.map +1 -1
  249. package/dist/runtime/capabilities/recipe.d.ts +2 -1
  250. package/dist/runtime/capabilities/recipe.d.ts.map +1 -1
  251. package/dist/runtime/capabilities/recipe.js +88 -28
  252. package/dist/shared/errors.d.ts +1 -1
  253. package/dist/shared/errors.d.ts.map +1 -1
  254. package/dist/shared/runtime-source.d.ts.map +1 -1
  255. package/dist/shared/runtime-source.js +8 -3
  256. package/package.json +3 -2
  257. package/dist/cli/recipes-bundled.d.ts +0 -10
  258. package/dist/cli/recipes-bundled.d.ts.map +0 -1
  259. package/dist/cli/recipes-bundled.js +0 -36
@@ -1,102 +1,58 @@
1
- import { mkdir, readdir, readFile } from "node:fs/promises";
1
+ import { stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { fileExists, getPathKind } from "../../../cli/fs-utils.js";
4
3
  import { invalidFieldMessage, missingFileMessage } from "../../../cli/output.js";
5
- import { isRecord } from "../../../shared/guards.js";
6
- import { writeJsonStableIfChanged } from "../../../shared/write-if-changed.js";
7
- import { resolveProjectInstalledRecipeDir, resolveProjectRecipeInstallMetaPath, resolveProjectRecipesDir, } from "./paths.js";
8
- import { readRecipeManifest } from "./manifest.js";
9
4
  import { normalizeRecipeTags } from "./normalize.js";
10
- function validateRecipeInstallMetadata(raw) {
11
- if (!isRecord(raw))
12
- throw new Error(invalidFieldMessage("recipe install metadata", "object"));
13
- const id = typeof raw.id === "string" ? raw.id.trim() : "";
14
- const version = typeof raw.version === "string" ? raw.version.trim() : "";
15
- const source = typeof raw.source === "string" ? raw.source.trim() : "";
16
- const installedAt = typeof raw.installed_at === "string" ? raw.installed_at.trim() : "";
17
- const installMode = raw.install_mode === undefined || raw.install_mode === "project-local"
18
- ? raw.install_mode
19
- : null;
20
- if (raw.schema_version !== 1) {
21
- throw new Error(invalidFieldMessage("recipe install metadata.schema_version", "1"));
22
- }
23
- if (!id || !version || !source || !installedAt) {
24
- throw new Error(invalidFieldMessage("recipe install metadata", "id, version, source, installed_at"));
25
- }
26
- if (installMode === null) {
27
- throw new Error(invalidFieldMessage("recipe install metadata.install_mode", '"project-local"'));
28
- }
29
- const tags = normalizeRecipeTags(raw.tags ?? []);
30
- return {
31
- schema_version: 1,
32
- id,
33
- version,
34
- source,
35
- installed_at: installedAt,
36
- tags,
37
- install_mode: installMode,
38
- };
39
- }
5
+ import { readProjectRecipesRegistry } from "./project-registry.js";
6
+ import { readRecipeManifest } from "./manifest.js";
7
+ import { resolveProjectRecipesDir } from "./paths.js";
40
8
  function sortInstalledRecipes(entries) {
41
- return [...entries].toSorted((a, b) => a.id.localeCompare(b.id));
9
+ return [...entries].toSorted((left, right) => left.id.localeCompare(right.id));
42
10
  }
43
- export async function readRecipeInstallMetadata(filePath) {
11
+ async function pathExistsAsKind(filePath, kind) {
44
12
  try {
45
- const raw = JSON.parse(await readFile(filePath, "utf8"));
46
- return validateRecipeInstallMetadata(raw);
13
+ const stats = await stat(filePath);
14
+ return kind === "dir" ? stats.isDirectory() : stats.isFile();
47
15
  }
48
- catch (err) {
49
- const code = err?.code;
50
- if (code === "ENOENT")
51
- return null;
52
- throw err;
16
+ catch {
17
+ return false;
53
18
  }
54
19
  }
55
- export async function writeRecipeInstallMetadata(filePath, metadata) {
56
- await mkdir(path.dirname(filePath), { recursive: true });
57
- await writeJsonStableIfChanged(filePath, metadata);
58
- }
59
20
  export async function readProjectInstalledRecipes(opts) {
60
- const recipesDir = resolveProjectRecipesDir(opts);
61
- if ((await getPathKind(recipesDir)) !== "dir") {
21
+ const registry = await readProjectRecipesRegistry(opts);
22
+ if (registry.recipes.length === 0) {
62
23
  return { schema_version: 1, updated_at: "", recipes: [] };
63
24
  }
64
25
  const entries = [];
65
- const dirs = await readdir(recipesDir, { withFileTypes: true });
66
- for (const dirent of dirs) {
67
- if (!dirent.isDirectory())
68
- continue;
69
- const recipeDir = resolveProjectInstalledRecipeDir(opts, dirent.name);
26
+ for (const registryEntry of registry.recipes) {
27
+ const recipeDir = path.join(resolveProjectRecipesDir(opts), registryEntry.path);
28
+ if (!(await pathExistsAsKind(recipeDir, "dir"))) {
29
+ throw new Error(missingFileMessage("vendored recipe directory", recipeDir));
30
+ }
70
31
  const manifestPath = path.join(recipeDir, "manifest.json");
71
- if (!(await fileExists(manifestPath))) {
32
+ if (!(await pathExistsAsKind(manifestPath, "file"))) {
72
33
  throw new Error(missingFileMessage("installed recipe manifest", manifestPath));
73
34
  }
74
35
  const manifest = await readRecipeManifest(manifestPath);
75
- if (manifest.id !== dirent.name) {
76
- throw new Error(invalidFieldMessage(`installed recipe directory ${dirent.name}`, `manifest.id=${dirent.name}`));
77
- }
78
- const metadata = await readRecipeInstallMetadata(resolveProjectRecipeInstallMetaPath(opts, dirent.name));
79
- if (metadata && (metadata.id !== manifest.id || metadata.version !== manifest.version)) {
80
- throw new Error(invalidFieldMessage(`recipe install metadata ${dirent.name}`, "id/version matching manifest"));
36
+ if (manifest.id !== registryEntry.id || manifest.version !== registryEntry.version) {
37
+ throw new Error(invalidFieldMessage(`installed recipe directory ${registryEntry.id}`, `manifest.id=${registryEntry.id} and manifest.version=${registryEntry.version}`));
81
38
  }
82
39
  entries.push({
83
40
  id: manifest.id,
84
41
  version: manifest.version,
85
- source: metadata?.source ?? "project-local",
86
- installed_at: metadata?.installed_at ?? "",
87
- tags: normalizeRecipeTags(metadata?.tags ?? manifest.tags ?? []),
42
+ source: registryEntry.source_ref,
43
+ source_ref: registryEntry.source_ref,
44
+ source_sha256: registryEntry.source_sha256,
45
+ vendored_sha256: registryEntry.vendored_sha256,
46
+ materialization: registryEntry.materialization,
47
+ installed_at: registryEntry.installed_at,
48
+ project_path: registryEntry.path,
49
+ tags: normalizeRecipeTags(registryEntry.tags ?? manifest.tags ?? []),
88
50
  manifest,
89
51
  });
90
52
  }
91
- const sorted = sortInstalledRecipes(entries);
92
- const updatedAt = sorted
93
- .map((entry) => entry.installed_at)
94
- .filter(Boolean)
95
- .toSorted()
96
- .at(-1);
97
53
  return {
98
54
  schema_version: 1,
99
- updated_at: updatedAt ?? "",
100
- recipes: sorted,
55
+ updated_at: registry.updated_at,
56
+ recipes: sortInstalledRecipes(entries),
101
57
  };
102
58
  }
@@ -0,0 +1,18 @@
1
+ import type { ProjectInstalledRecipeEntry, ProjectRecipeState } from "./types.js";
2
+ export declare function hashRecipeTree(rootDir: string): Promise<string>;
3
+ export type ProjectRecipeInspection = {
4
+ entry: ProjectInstalledRecipeEntry;
5
+ recipe_dir: string;
6
+ source_dir: string;
7
+ cache_present: boolean;
8
+ current_source_sha256?: string;
9
+ current_vendored_sha256: string;
10
+ state: ProjectRecipeState;
11
+ };
12
+ export declare function inspectProjectRecipe(opts: {
13
+ project: {
14
+ agentplaneDir: string;
15
+ };
16
+ recipeId: string;
17
+ }): Promise<ProjectRecipeInspection>;
18
+ //# sourceMappingURL=project-recipe-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-recipe-state.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/project-recipe-state.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA+BlF,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIrE;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,2BAA2B,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,KAAK,EAAE,kBAAkB,CAAC;CAC3B,CAAC;AA2BF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAwCnC"}
@@ -0,0 +1,94 @@
1
+ import { createHash } from "node:crypto";
2
+ import { lstat, readFile, readdir } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { readProjectInstalledRecipes } from "./project-installed-recipes.js";
5
+ import { resolveInstalledRecipeDir, resolveProjectVendoredRecipeDir } from "./paths.js";
6
+ async function hashTreeEntry(rootDir, relativeDir, hash) {
7
+ const directoryPath = relativeDir ? path.join(rootDir, relativeDir) : rootDir;
8
+ const directoryEntries = await readdir(directoryPath, { withFileTypes: true });
9
+ const entries = directoryEntries.toSorted((left, right) => left.name.localeCompare(right.name));
10
+ for (const entry of entries) {
11
+ const relativePath = relativeDir ? path.posix.join(relativeDir, entry.name) : entry.name;
12
+ const absolutePath = path.join(rootDir, relativePath);
13
+ if (entry.isDirectory()) {
14
+ hash.update(`dir:${relativePath}\n`);
15
+ await hashTreeEntry(rootDir, relativePath, hash);
16
+ continue;
17
+ }
18
+ if (entry.isSymbolicLink()) {
19
+ hash.update(`symlink:${relativePath}\n`);
20
+ continue;
21
+ }
22
+ const data = await readFile(absolutePath);
23
+ hash.update(`file:${relativePath}\n`);
24
+ hash.update(data);
25
+ hash.update("\n");
26
+ }
27
+ }
28
+ export async function hashRecipeTree(rootDir) {
29
+ const hash = createHash("sha256");
30
+ await hashTreeEntry(rootDir, "", hash);
31
+ return hash.digest("hex");
32
+ }
33
+ function classifyRecipeState(opts) {
34
+ if (opts.entry.materialization === "link" && !opts.vendoredPathIsSymlink) {
35
+ return "modified";
36
+ }
37
+ const vendoredModified = opts.currentVendoredSha256 !== opts.entry.vendored_sha256;
38
+ const cacheDiverged = opts.cachePresent && opts.currentSourceSha256 !== undefined
39
+ ? opts.currentSourceSha256 !== opts.entry.source_sha256
40
+ : false;
41
+ if (opts.entry.materialization === "link") {
42
+ if (cacheDiverged)
43
+ return "diverged_from_cache";
44
+ if (vendoredModified)
45
+ return "modified";
46
+ return "clean";
47
+ }
48
+ if (vendoredModified)
49
+ return "modified";
50
+ if (cacheDiverged)
51
+ return "diverged_from_cache";
52
+ return "clean";
53
+ }
54
+ export async function inspectProjectRecipe(opts) {
55
+ const installed = await readProjectInstalledRecipes(opts.project);
56
+ const entry = installed.recipes.find((recipe) => recipe.id === opts.recipeId);
57
+ if (!entry) {
58
+ throw new Error(`Recipe not installed: ${opts.recipeId}`);
59
+ }
60
+ const recipeDir = resolveProjectVendoredRecipeDir(opts.project, entry.id);
61
+ const sourceDir = resolveInstalledRecipeDir({ id: entry.id, version: entry.version });
62
+ const vendoredPathStat = await lstat(recipeDir);
63
+ const vendoredPathIsSymlink = vendoredPathStat.isSymbolicLink();
64
+ const currentVendoredSha256 = await hashRecipeTree(recipeDir);
65
+ let cachePresent = false;
66
+ let currentSourceSha256;
67
+ try {
68
+ const sourceStat = await lstat(sourceDir);
69
+ if (sourceStat.isDirectory() || sourceStat.isSymbolicLink()) {
70
+ cachePresent = true;
71
+ currentSourceSha256 = await hashRecipeTree(sourceDir);
72
+ }
73
+ }
74
+ catch (error) {
75
+ const code = error?.code;
76
+ if (code !== "ENOENT")
77
+ throw error;
78
+ }
79
+ return {
80
+ entry,
81
+ recipe_dir: recipeDir,
82
+ source_dir: sourceDir,
83
+ cache_present: cachePresent,
84
+ current_source_sha256: currentSourceSha256,
85
+ current_vendored_sha256: currentVendoredSha256,
86
+ state: classifyRecipeState({
87
+ entry,
88
+ cachePresent,
89
+ currentSourceSha256,
90
+ currentVendoredSha256,
91
+ vendoredPathIsSymlink,
92
+ }),
93
+ };
94
+ }
@@ -0,0 +1,20 @@
1
+ import type { ProjectRecipeRegistryEntry, ProjectRecipesRegistryFile } from "./types.js";
2
+ export declare function readProjectRecipesRegistry(opts: {
3
+ agentplaneDir: string;
4
+ }): Promise<ProjectRecipesRegistryFile>;
5
+ export declare function writeProjectRecipesRegistry(opts: {
6
+ agentplaneDir: string;
7
+ }, file: ProjectRecipesRegistryFile): Promise<void>;
8
+ export declare function upsertProjectRecipeRegistryEntry(opts: {
9
+ project: {
10
+ agentplaneDir: string;
11
+ };
12
+ entry: ProjectRecipeRegistryEntry;
13
+ }): Promise<ProjectRecipesRegistryFile>;
14
+ export declare function removeProjectRecipeRegistryEntry(opts: {
15
+ project: {
16
+ agentplaneDir: string;
17
+ };
18
+ recipeId: string;
19
+ }): Promise<ProjectRecipesRegistryFile>;
20
+ //# sourceMappingURL=project-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-registry.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/project-registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAsDpB,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAwBtC;AAED,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,EAC/B,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,gCAAgC,CAAC,IAAI,EAAE;IAC3D,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,KAAK,EAAE,0BAA0B,CAAC;CACnC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAOtC;AAED,wBAAsB,gCAAgC,CAAC,IAAI,EAAE;IAC3D,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAStC"}
@@ -0,0 +1,104 @@
1
+ import { mkdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { invalidFieldMessage } from "../../../cli/output.js";
4
+ import { isRecord } from "../../../shared/guards.js";
5
+ import { writeJsonStableIfChanged } from "../../../shared/write-if-changed.js";
6
+ import { normalizeRecipeId, normalizeRecipeTags } from "./normalize.js";
7
+ import { resolveProjectRecipesRegistryPath } from "./paths.js";
8
+ function validateMaterialization(raw) {
9
+ if (raw === "copy" || raw === "link")
10
+ return raw;
11
+ throw new Error(invalidFieldMessage("recipes registry materialization", '"copy" | "link"'));
12
+ }
13
+ function validateRegistryEntry(raw) {
14
+ if (!isRecord(raw))
15
+ throw new Error(invalidFieldMessage("recipes registry entry", "object"));
16
+ const id = normalizeRecipeId(typeof raw.id === "string" ? raw.id.trim() : "");
17
+ const version = typeof raw.version === "string" ? raw.version.trim() : "";
18
+ const entryPath = typeof raw.path === "string" ? raw.path.trim() : "";
19
+ const sourceRef = typeof raw.source_ref === "string" ? raw.source_ref.trim() : "";
20
+ const sourceSha256 = typeof raw.source_sha256 === "string" ? raw.source_sha256.trim() : "";
21
+ const vendoredSha256 = typeof raw.vendored_sha256 === "string" ? raw.vendored_sha256.trim() : "";
22
+ const installedAt = typeof raw.installed_at === "string" ? raw.installed_at.trim() : "";
23
+ if (!id ||
24
+ !version ||
25
+ !entryPath ||
26
+ !sourceRef ||
27
+ !sourceSha256 ||
28
+ !vendoredSha256 ||
29
+ !installedAt) {
30
+ throw new Error(invalidFieldMessage("recipes registry entry", "id, version, path, source_ref, source_sha256, vendored_sha256, installed_at"));
31
+ }
32
+ return {
33
+ id,
34
+ version,
35
+ path: entryPath,
36
+ active: raw.active === true,
37
+ materialization: validateMaterialization(raw.materialization),
38
+ source_ref: sourceRef,
39
+ source_sha256: sourceSha256,
40
+ vendored_sha256: vendoredSha256,
41
+ installed_at: installedAt,
42
+ tags: normalizeRecipeTags(raw.tags ?? []),
43
+ };
44
+ }
45
+ function sortRegistry(file) {
46
+ return {
47
+ schema_version: 1,
48
+ updated_at: file.updated_at,
49
+ recipes: [...file.recipes].toSorted((left, right) => left.id.localeCompare(right.id)),
50
+ };
51
+ }
52
+ export async function readProjectRecipesRegistry(opts) {
53
+ try {
54
+ const raw = JSON.parse(await readFile(resolveProjectRecipesRegistryPath(opts), "utf8"));
55
+ if (!isRecord(raw))
56
+ throw new Error(invalidFieldMessage("recipes registry", "object"));
57
+ if (raw.schema_version !== 1) {
58
+ throw new Error(invalidFieldMessage("recipes registry.schema_version", "1"));
59
+ }
60
+ if (!Array.isArray(raw.recipes)) {
61
+ throw new Error(invalidFieldMessage("recipes registry.recipes", "array"));
62
+ }
63
+ return sortRegistry({
64
+ schema_version: 1,
65
+ updated_at: typeof raw.updated_at === "string" ? raw.updated_at : "",
66
+ recipes: raw.recipes.map((entry) => validateRegistryEntry(entry)),
67
+ });
68
+ }
69
+ catch (err) {
70
+ const code = err?.code;
71
+ if (code === "ENOENT") {
72
+ return { schema_version: 1, updated_at: "", recipes: [] };
73
+ }
74
+ throw err;
75
+ }
76
+ }
77
+ export async function writeProjectRecipesRegistry(opts, file) {
78
+ const sorted = sortRegistry({
79
+ schema_version: 1,
80
+ updated_at: new Date().toISOString(),
81
+ recipes: file.recipes,
82
+ });
83
+ const filePath = resolveProjectRecipesRegistryPath(opts);
84
+ await mkdir(path.dirname(filePath), { recursive: true });
85
+ await writeJsonStableIfChanged(filePath, sorted);
86
+ }
87
+ export async function upsertProjectRecipeRegistryEntry(opts) {
88
+ const registry = await readProjectRecipesRegistry(opts.project);
89
+ const recipes = registry.recipes.filter((entry) => entry.id !== opts.entry.id);
90
+ recipes.push(opts.entry);
91
+ const next = { schema_version: 1, updated_at: registry.updated_at, recipes };
92
+ await writeProjectRecipesRegistry(opts.project, next);
93
+ return readProjectRecipesRegistry(opts.project);
94
+ }
95
+ export async function removeProjectRecipeRegistryEntry(opts) {
96
+ const registry = await readProjectRecipesRegistry(opts.project);
97
+ const next = {
98
+ schema_version: 1,
99
+ updated_at: registry.updated_at,
100
+ recipes: registry.recipes.filter((entry) => entry.id !== opts.recipeId),
101
+ };
102
+ await writeProjectRecipesRegistry(opts.project, next);
103
+ return readProjectRecipesRegistry(opts.project);
104
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAEhC,KAAK,qBAAqB,EAE1B,KAAK,wBAAwB,EAE7B,KAAK,mCAAmC,EACxC,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACrC,MAAM,YAAY,CAAC;AA+BpB,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,OAAO,EAAE,eAAe,CAAC;CAC1B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CASjC;AAYD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,OAAO,EAAE,qBAAqB,CAAC;CAChC,GAAG,2BAA2B,CAkG9B;AAED,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,wBAAwB,GACjC,wBAAwB,CAO1B;AAmDD,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAsBpC;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,mCAAmC,CAAC;CAC5C,GAAG,OAAO,CAAC,+BAA+B,CAAC,CA6D3C"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAEhC,KAAK,qBAAqB,EAE1B,KAAK,wBAAwB,EAE7B,KAAK,mCAAmC,EACxC,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACrC,MAAM,YAAY,CAAC;AA+BpB,wBAAsB,0BAA0B,CAAC,IAAI,EAAE;IACrD,OAAO,EAAE,eAAe,CAAC;CAC1B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CASjC;AAYD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,OAAO,EAAE,qBAAqB,CAAC;CAChC,GAAG,2BAA2B,CAkG9B;AAED,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,wBAAwB,GACjC,wBAAwB,CAO1B;AAqDD,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAsBpC;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,mCAAmC,CAAC;CAC5C,GAAG,OAAO,CAAC,+BAA+B,CAAC,CA6D3C"}
@@ -3,7 +3,7 @@ import { fileExists } from "../../../cli/fs-utils.js";
3
3
  import { getVersion } from "../../../meta/version.js";
4
4
  import { dedupeStrings } from "../../../shared/strings.js";
5
5
  import { compareVersions } from "../../../shared/version-compare.js";
6
- import { resolveProjectInstalledRecipeDir } from "./paths.js";
6
+ import { resolveProjectRecipesDir, resolveProjectInstalledRecipeDir } from "./paths.js";
7
7
  import { readProjectInstalledRecipes } from "./project-installed-recipes.js";
8
8
  import { readScenarioDefinition } from "./scenario.js";
9
9
  const SUPPORTED_MANIFEST_API_VERSION = "1";
@@ -109,8 +109,10 @@ export function normalizeResolvedRecipeRunProfile(scenario) {
109
109
  };
110
110
  }
111
111
  function toResolvedRecipeScenarios(opts) {
112
- const recipeDir = resolveProjectInstalledRecipeDir(opts.project, opts.entry.id);
113
- return opts.entry.manifest.scenarios
112
+ const recipeDir = opts.entry.project_path
113
+ ? path.join(resolveProjectRecipesDir(opts.project), opts.entry.project_path)
114
+ : resolveProjectInstalledRecipeDir(opts.project, opts.entry.id);
115
+ return (opts.entry.manifest.scenarios ?? [])
114
116
  .map((scenario) => ({
115
117
  recipe_id: opts.entry.id,
116
118
  recipe_version: opts.entry.version,
@@ -1,243 +1,4 @@
1
- export type RecipeCompatibility = {
2
- min_agentplane_version?: string;
3
- manifest_api_version?: string;
4
- scenario_api_version?: string;
5
- runtime_api_version?: string;
6
- platforms?: string[];
7
- repo_types?: string[];
8
- };
9
- export type RecipeRunProfile = {
10
- mode: string;
11
- sandbox?: string;
12
- writes_artifacts_to?: string[];
13
- };
14
- export type RecipeTaskTemplateDoc = {
15
- summary?: string;
16
- scope?: string;
17
- plan?: string;
18
- verify_steps?: string;
19
- rollback_plan?: string;
20
- findings?: string;
21
- };
22
- export type RecipeTaskTemplate = {
23
- title: string;
24
- description: string;
25
- owner: string;
26
- priority?: "low" | "normal" | "med" | "high";
27
- tags?: string[];
28
- verify?: string[];
29
- doc?: RecipeTaskTemplateDoc;
30
- };
31
- export type RecipeSkillDefinition = {
32
- id: string;
33
- summary: string;
34
- kind: string;
35
- file: string;
36
- };
37
- export type RecipeToolDefinition = {
38
- id: string;
39
- summary: string;
40
- runtime: "node" | "bash";
41
- entrypoint: string;
42
- permissions?: string[];
43
- timeout_ms?: number;
44
- cwd_policy?: string;
45
- };
46
- export type RecipeAgentDefinition = {
47
- id: string;
48
- display_name: string;
49
- role: string;
50
- summary: string;
51
- skills?: string[];
52
- tools?: string[];
53
- file: string;
54
- };
55
- export type RecipeScenarioDescriptor = {
56
- id: string;
57
- name: string;
58
- summary: string;
59
- description?: string;
60
- use_when: string[];
61
- avoid_when?: string[];
62
- required_inputs: string[];
63
- outputs: string[];
64
- permissions: string[];
65
- artifacts: string[];
66
- agents_involved: string[];
67
- skills_used: string[];
68
- tools_used: string[];
69
- run_profile: RecipeRunProfile;
70
- file: string;
71
- };
72
- export type RecipeResolverContext = {
73
- agentplane_version: string;
74
- manifest_api_version: "1";
75
- scenario_api_version: "1";
76
- runtime_api_version: "1";
77
- platform: string;
78
- repo_types: string[];
79
- };
80
- export type RecipeResolverCompatibilityFailure = {
81
- field: "min_agentplane_version" | "manifest_api_version" | "scenario_api_version" | "runtime_api_version" | "platforms" | "repo_types";
82
- expected: string | string[];
83
- actual: string | string[] | null;
84
- reason: string;
85
- };
86
- export type RecipeResolverCompatibility = {
87
- ok: boolean;
88
- reasons: string[];
89
- failures: RecipeResolverCompatibilityFailure[];
90
- };
91
- export type ResolvedRecipeRunProfile = {
92
- mode: string;
93
- sandbox?: string;
94
- writes_artifacts_to: string[];
95
- };
96
- export type ResolvedRecipeScenario = {
97
- recipe_id: string;
98
- recipe_version: string;
99
- recipe_name: string;
100
- recipe_summary: string;
101
- recipe_tags: string[];
102
- recipe_dir: string;
103
- scenario_id: string;
104
- scenario_name: string;
105
- scenario_summary: string;
106
- scenario_description?: string;
107
- use_when: string[];
108
- avoid_when: string[];
109
- required_inputs: string[];
110
- outputs: string[];
111
- permissions: string[];
112
- artifacts: string[];
113
- agents_involved: string[];
114
- skills_used: string[];
115
- tools_used: string[];
116
- scenario_file: string;
117
- compatibility: RecipeResolverCompatibility;
118
- run_profile: ResolvedRecipeRunProfile;
119
- task_template?: RecipeTaskTemplate;
120
- };
121
- export type ResolveRecipeScenarioSelectionFlags = {
122
- recipeId?: string;
123
- scenarioId?: string;
124
- tags?: string[];
125
- mode?: string;
126
- available_inputs?: string[];
127
- includeIncompatible?: boolean;
128
- };
129
- export type ResolvedRecipeScenarioSelection = ResolvedRecipeScenario & {
130
- selection_reasons: string[];
131
- };
132
- export type RecipeManifest = {
133
- schema_version: "1";
134
- id: string;
135
- version: string;
136
- name: string;
137
- summary: string;
138
- description: string;
139
- tags?: string[];
140
- compatibility?: RecipeCompatibility;
141
- skills?: RecipeSkillDefinition[];
142
- agents?: RecipeAgentDefinition[];
143
- tools?: RecipeToolDefinition[];
144
- scenarios: RecipeScenarioDescriptor[];
145
- };
146
- export type RecipeConflictMode = "fail" | "rename" | "overwrite";
147
- export type RecipeInstallMetadata = {
148
- schema_version: 1;
149
- id: string;
150
- version: string;
151
- source: string;
152
- installed_at: string;
153
- tags?: string[];
154
- install_mode?: "project-local";
155
- };
156
- export type InstalledRecipeEntry = {
157
- id: string;
158
- version: string;
159
- source: string;
160
- installed_at: string;
161
- tags: string[];
162
- manifest: RecipeManifest;
163
- };
164
- export type InstalledRecipesFile = {
165
- schema_version: 1;
166
- updated_at: string;
167
- recipes: InstalledRecipeEntry[];
168
- };
169
- export type ScenarioDefinition = {
170
- schema_version: "1";
171
- id: string;
172
- summary?: string;
173
- description?: string;
174
- goal: string;
175
- task_template: RecipeTaskTemplate;
176
- inputs: unknown;
177
- outputs: unknown;
178
- evidence?: {
179
- required: boolean;
180
- files: string[];
181
- };
182
- steps: unknown[];
183
- };
184
- export type RecipeScenarioDetail = {
185
- id: string;
186
- name?: string;
187
- summary?: string;
188
- description?: string;
189
- use_when?: string[];
190
- avoid_when?: string[];
191
- required_inputs?: string[];
192
- permissions?: string[];
193
- artifacts?: string[];
194
- agents_involved?: string[];
195
- skills_used?: string[];
196
- tools_used?: string[];
197
- run_profile?: RecipeRunProfile;
198
- goal?: string;
199
- task_template?: RecipeTaskTemplate;
200
- inputs?: unknown;
201
- outputs?: unknown;
202
- evidence?: ScenarioDefinition["evidence"];
203
- file?: string;
204
- steps?: unknown[];
205
- source: "definition" | "index" | "manifest";
206
- };
207
- export type RecipesIndex = {
208
- schema_version: 1;
209
- recipes: {
210
- id: string;
211
- summary: string;
212
- description?: string;
213
- versions: {
214
- version: string;
215
- url: string;
216
- sha256: string;
217
- min_agentplane_version?: string;
218
- tags?: string[];
219
- }[];
220
- }[];
221
- };
222
- export type RecipesIndexSignature = {
223
- schema_version: 1;
224
- key_id: string;
225
- signature: string;
226
- algorithm?: string;
227
- };
228
- export type RecipeInstallSource = {
229
- type: "name";
230
- value: string;
231
- } | {
232
- type: "path";
233
- value: string;
234
- } | {
235
- type: "url";
236
- value: string;
237
- } | {
238
- type: "auto";
239
- value: string;
240
- };
1
+ export type { CompiledRecipeAssetEntry, CompiledRecipeAssetRegistry, CompiledOverlayBundle, CompiledOverlayPromptFragment, CompiledOverlayTraceEntry, CompiledOverlayValidator, InstalledRecipeEntry, InstalledRecipesFile, OverlayPromptFragment, OverlayStrength, OverlaySurface, OverlayValidator, OverlayWhen, ProjectOverlayManifestV2, ProjectInstalledRecipeEntry, ProjectInstalledRecipesFile, ProjectRecipeMaterialization, ProjectRecipeRegistryEntry, ProjectRecipesRegistryFile, ProjectRecipeState, ProjectRecipesLockEntry, ProjectRecipesLockFile, RecipeAgentDefinition, RecipeCompatibility, RecipeConflictMode, RecipeInstallSource, RecipeKind, RecipeManifest, RecipeResolverCompatibility, RecipeResolverCompatibilityFailure, RecipeResolverContext, RecipeRunProfile, RecipeScenarioDescriptor, RecipeScenarioDetail, RecipeSkillDefinition, RecipeTaskTemplate, RecipeTaskTemplateDoc, RecipeToolDefinition, RecipesIndex, RecipesIndexSignature, ResolveRecipeScenarioSelectionFlags, ResolvedRecipeRunProfile, ResolvedRecipeScenario, ResolvedRecipeScenarioSelection, ScenarioDefinition, } from "@agentplaneorg/recipes";
241
2
  export type RecipeCachePruneFlags = {
242
3
  dryRun: boolean;
243
4
  all: boolean;