agentplane 0.3.12 → 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 (180) hide show
  1. package/assets/RUNNER.md +1 -1
  2. package/assets/agents/ORCHESTRATOR.json +1 -1
  3. package/assets/codex-plugin/assets/header.png +0 -0
  4. package/assets/codex-plugin/assets/icon.svg +1 -0
  5. package/assets/codex-plugin/assets/logo.svg +1 -0
  6. package/assets/codex-plugin/skills/agentplane/SKILL.md +35 -0
  7. package/assets/policy/governance.md +4 -2
  8. package/assets/policy/incidents.md +3 -20
  9. package/assets/policy/workflow.release.md +5 -2
  10. package/dist/.build-manifest.json +203 -113
  11. package/dist/cli/exit-codes.d.ts.map +1 -1
  12. package/dist/cli/exit-codes.js +1 -0
  13. package/dist/cli/reason-codes.d.ts +1 -1
  14. package/dist/cli/reason-codes.d.ts.map +1 -1
  15. package/dist/cli/reason-codes.js +12 -0
  16. package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
  17. package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
  18. package/dist/cli/run-cli/command-catalog/core.js +16 -0
  19. package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
  20. package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
  21. package/dist/cli/run-cli/command-catalog/project.js +21 -3
  22. package/dist/cli/run-cli/command-catalog.d.ts +1 -1
  23. package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
  24. package/dist/cli/run-cli/commands/codex.d.ts +14 -0
  25. package/dist/cli/run-cli/commands/codex.d.ts.map +1 -0
  26. package/dist/cli/run-cli/commands/codex.js +100 -0
  27. package/dist/cli/run-cli/commands/core.d.ts +1 -0
  28. package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
  29. package/dist/cli/run-cli/commands/core.js +1 -0
  30. package/dist/cli/run-cli/commands/init/recipes.d.ts +9 -1
  31. package/dist/cli/run-cli/commands/init/recipes.d.ts.map +1 -1
  32. package/dist/cli/run-cli/commands/init/recipes.js +32 -22
  33. package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
  34. package/dist/cli/run-cli/commands/init.js +26 -21
  35. package/dist/cli/run-cli/error-guidance.js +20 -0
  36. package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
  37. package/dist/cli/run-cli.test-helpers.js +22 -19
  38. package/dist/commands/codex/plugin-install.d.ts +26 -0
  39. package/dist/commands/codex/plugin-install.d.ts.map +1 -0
  40. package/dist/commands/codex/plugin-install.js +209 -0
  41. package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
  42. package/dist/commands/pr/integrate/cmd.js +81 -5
  43. package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
  44. package/dist/commands/pr/integrate/internal/prepare.js +38 -7
  45. package/dist/commands/pr/internal/auto-commit.d.ts.map +1 -1
  46. package/dist/commands/pr/internal/auto-commit.js +11 -6
  47. package/dist/commands/pr/internal/sync.d.ts.map +1 -1
  48. package/dist/commands/pr/internal/sync.js +5 -1
  49. package/dist/commands/pr/open.d.ts.map +1 -1
  50. package/dist/commands/pr/open.js +46 -8
  51. package/dist/commands/recipes/active.command.d.ts +7 -0
  52. package/dist/commands/recipes/active.command.d.ts.map +1 -0
  53. package/dist/commands/recipes/active.command.js +12 -0
  54. package/dist/commands/recipes/add.command.d.ts +8 -0
  55. package/dist/commands/recipes/add.command.d.ts.map +1 -0
  56. package/dist/commands/recipes/add.command.js +33 -0
  57. package/dist/commands/recipes/detach.command.d.ts +7 -0
  58. package/dist/commands/recipes/detach.command.d.ts.map +1 -0
  59. package/dist/commands/recipes/detach.command.js +19 -0
  60. package/dist/commands/recipes/disable.command.d.ts +7 -0
  61. package/dist/commands/recipes/disable.command.d.ts.map +1 -0
  62. package/dist/commands/recipes/disable.command.js +10 -0
  63. package/dist/commands/recipes/enable.command.d.ts +7 -0
  64. package/dist/commands/recipes/enable.command.d.ts.map +1 -0
  65. package/dist/commands/recipes/enable.command.js +10 -0
  66. package/dist/commands/recipes/explain-active.command.d.ts +5 -0
  67. package/dist/commands/recipes/explain-active.command.d.ts.map +1 -0
  68. package/dist/commands/recipes/explain-active.command.js +11 -0
  69. package/dist/commands/recipes/explain.command.d.ts.map +1 -1
  70. package/dist/commands/recipes/explain.command.js +4 -2
  71. package/dist/commands/recipes/impl/apply.d.ts.map +1 -1
  72. package/dist/commands/recipes/impl/apply.js +33 -14
  73. package/dist/commands/recipes/impl/commands/active.d.ts +6 -0
  74. package/dist/commands/recipes/impl/commands/active.d.ts.map +1 -0
  75. package/dist/commands/recipes/impl/commands/active.js +46 -0
  76. package/dist/commands/recipes/impl/commands/add.d.ts +7 -0
  77. package/dist/commands/recipes/impl/commands/add.d.ts.map +1 -0
  78. package/dist/commands/recipes/impl/commands/add.js +100 -0
  79. package/dist/commands/recipes/impl/commands/detach.d.ts +6 -0
  80. package/dist/commands/recipes/impl/commands/detach.d.ts.map +1 -0
  81. package/dist/commands/recipes/impl/commands/detach.js +85 -0
  82. package/dist/commands/recipes/impl/commands/disable.d.ts +6 -0
  83. package/dist/commands/recipes/impl/commands/disable.d.ts.map +1 -0
  84. package/dist/commands/recipes/impl/commands/disable.js +21 -0
  85. package/dist/commands/recipes/impl/commands/enable.d.ts +6 -0
  86. package/dist/commands/recipes/impl/commands/enable.d.ts.map +1 -0
  87. package/dist/commands/recipes/impl/commands/enable.js +39 -0
  88. package/dist/commands/recipes/impl/commands/explain-active.d.ts +5 -0
  89. package/dist/commands/recipes/impl/commands/explain-active.d.ts.map +1 -0
  90. package/dist/commands/recipes/impl/commands/explain-active.js +20 -0
  91. package/dist/commands/recipes/impl/commands/explain.d.ts.map +1 -1
  92. package/dist/commands/recipes/impl/commands/explain.js +40 -3
  93. package/dist/commands/recipes/impl/commands/info.d.ts.map +1 -1
  94. package/dist/commands/recipes/impl/commands/info.js +21 -8
  95. package/dist/commands/recipes/impl/commands/install.d.ts.map +1 -1
  96. package/dist/commands/recipes/impl/commands/install.js +32 -29
  97. package/dist/commands/recipes/impl/commands/list.d.ts.map +1 -1
  98. package/dist/commands/recipes/impl/commands/list.js +11 -11
  99. package/dist/commands/recipes/impl/commands/remove.d.ts.map +1 -1
  100. package/dist/commands/recipes/impl/commands/remove.js +5 -0
  101. package/dist/commands/recipes/impl/commands/update.d.ts +7 -0
  102. package/dist/commands/recipes/impl/commands/update.d.ts.map +1 -0
  103. package/dist/commands/recipes/impl/commands/update.js +93 -0
  104. package/dist/commands/recipes/impl/commands.d.ts +7 -0
  105. package/dist/commands/recipes/impl/commands.d.ts.map +1 -1
  106. package/dist/commands/recipes/impl/commands.js +7 -0
  107. package/dist/commands/recipes/impl/constants.d.ts +1 -14
  108. package/dist/commands/recipes/impl/constants.d.ts.map +1 -1
  109. package/dist/commands/recipes/impl/constants.js +1 -18
  110. package/dist/commands/recipes/impl/manifest.d.ts +2 -2
  111. package/dist/commands/recipes/impl/manifest.d.ts.map +1 -1
  112. package/dist/commands/recipes/impl/manifest.js +4 -226
  113. package/dist/commands/recipes/impl/overlay-project.d.ts +32 -0
  114. package/dist/commands/recipes/impl/overlay-project.d.ts.map +1 -0
  115. package/dist/commands/recipes/impl/overlay-project.js +282 -0
  116. package/dist/commands/recipes/impl/paths.d.ts +20 -2
  117. package/dist/commands/recipes/impl/paths.d.ts.map +1 -1
  118. package/dist/commands/recipes/impl/paths.js +23 -5
  119. package/dist/commands/recipes/impl/project-installed-recipes.d.ts +2 -4
  120. package/dist/commands/recipes/impl/project-installed-recipes.d.ts.map +1 -1
  121. package/dist/commands/recipes/impl/project-installed-recipes.js +30 -74
  122. package/dist/commands/recipes/impl/project-recipe-state.d.ts +18 -0
  123. package/dist/commands/recipes/impl/project-recipe-state.d.ts.map +1 -0
  124. package/dist/commands/recipes/impl/project-recipe-state.js +94 -0
  125. package/dist/commands/recipes/impl/project-registry.d.ts +20 -0
  126. package/dist/commands/recipes/impl/project-registry.d.ts.map +1 -0
  127. package/dist/commands/recipes/impl/project-registry.js +104 -0
  128. package/dist/commands/recipes/impl/resolver.d.ts.map +1 -1
  129. package/dist/commands/recipes/impl/resolver.js +5 -3
  130. package/dist/commands/recipes/impl/types.d.ts +1 -240
  131. package/dist/commands/recipes/impl/types.d.ts.map +1 -1
  132. package/dist/commands/recipes/info.command.js +2 -2
  133. package/dist/commands/recipes/install.spec.js +4 -4
  134. package/dist/commands/recipes/list.command.js +4 -4
  135. package/dist/commands/recipes/remove.command.js +2 -2
  136. package/dist/commands/recipes/update.command.d.ts +8 -0
  137. package/dist/commands/recipes/update.command.d.ts.map +1 -0
  138. package/dist/commands/recipes/update.command.js +35 -0
  139. package/dist/commands/recipes.d.ts +7 -4
  140. package/dist/commands/recipes.d.ts.map +1 -1
  141. package/dist/commands/recipes.js +6 -3
  142. package/dist/commands/recipes.test-helpers.d.ts +3 -3
  143. package/dist/commands/recipes.test-helpers.d.ts.map +1 -1
  144. package/dist/commands/recipes.test-helpers.js +105 -15
  145. package/dist/commands/scenario/execute.command.js +4 -4
  146. package/dist/commands/scenario/impl/commands.js +4 -4
  147. package/dist/commands/scenario/info.command.js +4 -4
  148. package/dist/commands/scenario/list.command.js +3 -3
  149. package/dist/commands/scenario/run.command.js +5 -5
  150. package/dist/commands/scenario/scenario.command.js +7 -7
  151. package/dist/commands/shared/task-handoff.d.ts +2 -1
  152. package/dist/commands/shared/task-handoff.d.ts.map +1 -1
  153. package/dist/commands/shared/task-handoff.js +15 -0
  154. package/dist/commands/task/handoff-show.command.d.ts.map +1 -1
  155. package/dist/commands/task/handoff-show.command.js +24 -0
  156. package/dist/runner/context/base-prompts.d.ts +2 -1
  157. package/dist/runner/context/base-prompts.d.ts.map +1 -1
  158. package/dist/runner/context/base-prompts.js +109 -13
  159. package/dist/runner/context/recipe-context.d.ts.map +1 -1
  160. package/dist/runner/context/recipe-context.js +40 -8
  161. package/dist/runner/types.d.ts +4 -0
  162. package/dist/runner/types.d.ts.map +1 -1
  163. package/dist/runner/usecases/task-run.d.ts.map +1 -1
  164. package/dist/runner/usecases/task-run.js +2 -1
  165. package/dist/runtime/behavior/resolve.d.ts +2 -1
  166. package/dist/runtime/behavior/resolve.d.ts.map +1 -1
  167. package/dist/runtime/behavior/resolve.js +25 -5
  168. package/dist/runtime/behavior/types.d.ts +1 -0
  169. package/dist/runtime/behavior/types.d.ts.map +1 -1
  170. package/dist/runtime/capabilities/recipe.d.ts +2 -1
  171. package/dist/runtime/capabilities/recipe.d.ts.map +1 -1
  172. package/dist/runtime/capabilities/recipe.js +88 -28
  173. package/dist/shared/errors.d.ts +1 -1
  174. package/dist/shared/errors.d.ts.map +1 -1
  175. package/dist/shared/runtime-source.d.ts.map +1 -1
  176. package/dist/shared/runtime-source.js +8 -3
  177. package/package.json +3 -2
  178. package/dist/cli/recipes-bundled.d.ts +0 -10
  179. package/dist/cli/recipes-bundled.d.ts.map +0 -1
  180. package/dist/cli/recipes-bundled.js +0 -36
@@ -3,6 +3,8 @@ import { mapBackendError } from "../../cli/error-map.js";
3
3
  import { exitCodeForError } from "../../cli/exit-codes.js";
4
4
  import { createCliEmitter } from "../../cli/output.js";
5
5
  import { CliError } from "../../shared/errors.js";
6
+ import { execFileAsync, gitEnv } from "../shared/git.js";
7
+ import { gitBranchUpstream } from "../shared/git-ops.js";
6
8
  import { loadCommandContext } from "../shared/task-backend.js";
7
9
  import { maybeAutoCommitTaskPrArtifacts } from "./internal/auto-commit.js";
8
10
  import { syncPrArtifacts } from "./internal/sync.js";
@@ -16,6 +18,24 @@ function prOpenOutcomeDetails(meta, openOutcome) {
16
18
  }
17
19
  return "local PR artifacts synced; remote PR creation staged";
18
20
  }
21
+ async function pushTaskBranchUpstreamIfConfigured(opts) {
22
+ const upstream = await gitBranchUpstream(opts.gitRoot, opts.branch);
23
+ const trimmed = upstream?.trim() ?? "";
24
+ if (!trimmed)
25
+ return false;
26
+ const slashIndex = trimmed.indexOf("/");
27
+ if (slashIndex <= 0 || slashIndex === trimmed.length - 1)
28
+ return false;
29
+ const remote = trimmed.slice(0, slashIndex);
30
+ const upstreamBranch = trimmed.slice(slashIndex + 1);
31
+ if (!remote || !upstreamBranch)
32
+ return false;
33
+ await execFileAsync("git", ["push", "--no-verify", remote, `HEAD:${upstreamBranch}`], {
34
+ cwd: opts.gitRoot,
35
+ env: gitEnv(),
36
+ });
37
+ return true;
38
+ }
19
39
  export async function cmdPrOpen(opts) {
20
40
  try {
21
41
  const output = createCliEmitter();
@@ -27,25 +47,43 @@ export async function cmdPrOpen(opts) {
27
47
  message: "Invalid value for --author.",
28
48
  });
29
49
  }
30
- const { meta, prDir, resolved, openOutcome } = await syncPrArtifacts({
31
- ctx: opts.ctx,
50
+ const commandCtx = opts.ctx ??
51
+ (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
52
+ const initialSync = await syncPrArtifacts({
53
+ ctx: commandCtx,
32
54
  cwd: opts.cwd,
33
55
  rootOverride: opts.rootOverride,
34
56
  taskId: opts.taskId,
35
57
  mode: "open",
36
58
  author,
37
59
  branch: opts.branch,
38
- remoteMode: opts.syncOnly ? "sync-only" : "auto",
60
+ remoteMode: "sync-only",
39
61
  });
40
- const commandCtx = opts.ctx ??
41
- (await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
42
- if (meta.branch) {
43
- await maybeAutoCommitTaskPrArtifacts({
62
+ const didAutoCommit = initialSync.meta.branch
63
+ ? await maybeAutoCommitTaskPrArtifacts({
44
64
  ctx: commandCtx,
45
65
  taskId: opts.taskId,
46
- branch: meta.branch,
66
+ branch: initialSync.meta.branch,
67
+ })
68
+ : false;
69
+ if (didAutoCommit && !opts.syncOnly && initialSync.meta.branch) {
70
+ await pushTaskBranchUpstreamIfConfigured({
71
+ gitRoot: commandCtx.resolvedProject.gitRoot,
72
+ branch: initialSync.meta.branch,
47
73
  });
48
74
  }
75
+ const { meta, prDir, resolved, openOutcome } = opts.syncOnly
76
+ ? initialSync
77
+ : await syncPrArtifacts({
78
+ ctx: commandCtx,
79
+ cwd: opts.cwd,
80
+ rootOverride: opts.rootOverride,
81
+ taskId: opts.taskId,
82
+ mode: "open",
83
+ author,
84
+ branch: opts.branch,
85
+ remoteMode: "auto",
86
+ });
49
87
  output.success("pr open", path.relative(resolved.gitRoot, prDir), prOpenOutcomeDetails(meta, openOutcome ?? null));
50
88
  return 0;
51
89
  }
@@ -0,0 +1,7 @@
1
+ import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
2
+ export type RecipesActiveParsed = {
3
+ full: boolean;
4
+ };
5
+ export declare const recipesActiveSpec: CommandSpec<RecipesActiveParsed>;
6
+ export declare const runRecipesActive: CommandHandler<RecipesActiveParsed>;
7
+ //# sourceMappingURL=active.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"active.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/active.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,mBAAmB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpD,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CAS9D,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,mBAAmB,CAC2B,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { cmdRecipeActiveParsed } from "../recipes.js";
2
+ export const recipesActiveSpec = {
3
+ id: ["recipes", "active"],
4
+ group: "Recipes",
5
+ summary: "List active project overlays.",
6
+ options: [
7
+ { kind: "boolean", name: "full", default: false, description: "Print full JSON payload." },
8
+ ],
9
+ examples: [{ cmd: "agentplane recipes active", why: "Show overlays active for the project." }],
10
+ parse: (raw) => ({ full: raw.opts.full === true }),
11
+ };
12
+ export const runRecipesActive = (ctx, parsed) => cmdRecipeActiveParsed({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, full: parsed.full });
@@ -0,0 +1,8 @@
1
+ import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
2
+ export type RecipesAddParsed = {
3
+ recipeRef: string;
4
+ mode?: "copy" | "link";
5
+ };
6
+ export declare const recipesAddSpec: CommandSpec<RecipesAddParsed>;
7
+ export declare const runRecipesAdd: CommandHandler<RecipesAddParsed>;
8
+ //# sourceMappingURL=add.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/add.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAyBxD,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,cAAc,CAAC,gBAAgB,CAMvD,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { cmdRecipeAddParsed } from "../recipes.js";
2
+ export const recipesAddSpec = {
3
+ id: ["recipes", "add"],
4
+ group: "Recipes",
5
+ summary: "Vendor a cached recipe into the current project.",
6
+ args: [{ name: "recipe", required: true, valueHint: "<id|id@version>" }],
7
+ options: [
8
+ {
9
+ kind: "string",
10
+ name: "mode",
11
+ valueHint: "<copy|link>",
12
+ choices: ["copy", "link"],
13
+ description: "Materialization mode for the project-local package.",
14
+ },
15
+ ],
16
+ examples: [
17
+ { cmd: "agentplane recipes add tdd", why: "Vendor the latest cached recipe into the project." },
18
+ {
19
+ cmd: "agentplane recipes add tdd@1.2.0 --mode link",
20
+ why: "Link a cached recipe into the project for local recipe development.",
21
+ },
22
+ ],
23
+ parse: (raw) => ({
24
+ recipeRef: String(raw.args.recipe ?? "").trim(),
25
+ mode: raw.opts.mode === "copy" || raw.opts.mode === "link" ? raw.opts.mode : undefined,
26
+ }),
27
+ };
28
+ export const runRecipesAdd = (ctx, parsed) => cmdRecipeAddParsed({
29
+ cwd: ctx.cwd,
30
+ rootOverride: ctx.rootOverride,
31
+ recipeRef: parsed.recipeRef,
32
+ mode: parsed.mode,
33
+ });
@@ -0,0 +1,7 @@
1
+ import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
2
+ export type RecipesDetachParsed = {
3
+ id: string;
4
+ };
5
+ export declare const recipesDetachSpec: CommandSpec<RecipesDetachParsed>;
6
+ export declare const runRecipesDetach: CommandHandler<RecipesDetachParsed>;
7
+ //# sourceMappingURL=detach.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detach.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/detach.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,mBAAmB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CAY9D,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,mBAAmB,CAK7D,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { cmdRecipeDetachParsed } from "../recipes.js";
2
+ export const recipesDetachSpec = {
3
+ id: ["recipes", "detach"],
4
+ group: "Recipes",
5
+ summary: "Convert a linked vendored recipe into a project-local copy.",
6
+ args: [{ name: "id", required: true, valueHint: "<id>" }],
7
+ examples: [
8
+ {
9
+ cmd: "agentplane recipes detach tdd",
10
+ why: "Freeze a linked recipe into a portable project copy before sharing the repo.",
11
+ },
12
+ ],
13
+ parse: (raw) => ({ id: String(raw.args.id ?? "").trim() }),
14
+ };
15
+ export const runRecipesDetach = (ctx, parsed) => cmdRecipeDetachParsed({
16
+ cwd: ctx.cwd,
17
+ rootOverride: ctx.rootOverride,
18
+ id: parsed.id,
19
+ });
@@ -0,0 +1,7 @@
1
+ import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
2
+ export type RecipesDisableParsed = {
3
+ id: string;
4
+ };
5
+ export declare const recipesDisableSpec: CommandSpec<RecipesDisableParsed>;
6
+ export declare const runRecipesDisable: CommandHandler<RecipesDisableParsed>;
7
+ //# sourceMappingURL=disable.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disable.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/disable.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,oBAAoB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CAOhE,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,cAAc,CAAC,oBAAoB,CACsB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { cmdRecipeDisableParsed } from "../recipes.js";
2
+ export const recipesDisableSpec = {
3
+ id: ["recipes", "disable"],
4
+ group: "Recipes",
5
+ summary: "Disable an active project overlay for the current project.",
6
+ args: [{ name: "id", required: true, valueHint: "<recipe-id>" }],
7
+ examples: [{ cmd: "agentplane recipes disable tdd", why: "Deactivate an overlay." }],
8
+ parse: (raw) => ({ id: String(raw.args.id ?? "").trim() }),
9
+ };
10
+ export const runRecipesDisable = (ctx, parsed) => cmdRecipeDisableParsed({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, id: parsed.id });
@@ -0,0 +1,7 @@
1
+ import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
2
+ export type RecipesEnableParsed = {
3
+ id: string;
4
+ };
5
+ export declare const recipesEnableSpec: CommandSpec<RecipesEnableParsed>;
6
+ export declare const runRecipesEnable: CommandHandler<RecipesEnableParsed>;
7
+ //# sourceMappingURL=enable.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enable.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/enable.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,mBAAmB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CAO9D,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,mBAAmB,CACuB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { cmdRecipeEnableParsed } from "../recipes.js";
2
+ export const recipesEnableSpec = {
3
+ id: ["recipes", "enable"],
4
+ group: "Recipes",
5
+ summary: "Enable an installed project overlay for the current project.",
6
+ args: [{ name: "id", required: true, valueHint: "<recipe-id>" }],
7
+ examples: [{ cmd: "agentplane recipes enable tdd", why: "Activate an installed overlay." }],
8
+ parse: (raw) => ({ id: String(raw.args.id ?? "").trim() }),
9
+ };
10
+ export const runRecipesEnable = (ctx, parsed) => cmdRecipeEnableParsed({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, id: parsed.id });
@@ -0,0 +1,5 @@
1
+ import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
2
+ export type RecipesExplainActiveParsed = Record<string, never>;
3
+ export declare const recipesExplainActiveSpec: CommandSpec<RecipesExplainActiveParsed>;
4
+ export declare const runRecipesExplainActive: CommandHandler<RecipesExplainActiveParsed>;
5
+ //# sourceMappingURL=explain-active.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain-active.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/explain-active.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1E,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/D,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,0BAA0B,CAQ5E,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,cAAc,CAAC,0BAA0B,CACC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { cmdRecipeExplainActiveParsed } from "../recipes.js";
2
+ export const recipesExplainActiveSpec = {
3
+ id: ["recipes", "explain-active"],
4
+ group: "Recipes",
5
+ summary: "Print the compiled active overlay bundle.",
6
+ examples: [
7
+ { cmd: "agentplane recipes explain-active", why: "Inspect compiled overlay runtime data." },
8
+ ],
9
+ parse: () => ({}),
10
+ };
11
+ export const runRecipesExplainActive = (ctx) => cmdRecipeExplainActiveParsed({ cwd: ctx.cwd, rootOverride: ctx.rootOverride });
@@ -1 +1 @@
1
- {"version":3,"file":"explain.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/explain.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1E,MAAM,MAAM,oBAAoB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CAOhE,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,cAAc,CAAC,oBAAoB,CACiB,CAAC"}
1
+ {"version":3,"file":"explain.command.d.ts","sourceRoot":"","sources":["../../../src/commands/recipes/explain.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1E,MAAM,MAAM,oBAAoB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CAShE,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,cAAc,CAAC,oBAAoB,CACiB,CAAC"}
@@ -2,9 +2,11 @@ import { cmdRecipeExplainParsed } from "../recipes.js";
2
2
  export const recipesExplainSpec = {
3
3
  id: ["recipes", "explain"],
4
4
  group: "Recipes",
5
- summary: "Show detailed info for an installed recipe.",
5
+ summary: "Show detailed info for a vendored recipe.",
6
6
  args: [{ name: "id", required: true, valueHint: "<id>" }],
7
- examples: [{ cmd: "agentplane recipes explain viewer", why: "Show detailed recipe info." }],
7
+ examples: [
8
+ { cmd: "agentplane recipes explain viewer", why: "Show detailed project-local recipe info." },
9
+ ],
8
10
  parse: (raw) => ({ id: String(raw.args.id ?? "") }),
9
11
  };
10
12
  export const runRecipesExplain = (ctx, p) => cmdRecipeExplainParsed({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, id: p.id });
@@ -1 +1 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/apply.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAErE,wBAAsB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAarF;AAkBD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BhB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,kBAAkB,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDhB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhB"}
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../../src/commands/recipes/impl/apply.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAErE,wBAAsB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAarF;AAyBD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmChB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,kBAAkB,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDhB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhB"}
@@ -1,4 +1,4 @@
1
- import { cp, mkdir, readFile, readdir, rename, rm } from "node:fs/promises";
1
+ import { cp, mkdir, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { exitCodeForError } from "../../../cli/exit-codes.js";
4
4
  import { fileExists, getPathKind } from "../../../cli/fs-utils.js";
@@ -24,22 +24,29 @@ export async function moveRecipeDir(opts) {
24
24
  throw err;
25
25
  }
26
26
  }
27
- async function readRecipeJsonObject(recipeDir, relativePath, label) {
27
+ function isMarkdownAssetPath(relativePath) {
28
+ const normalized = relativePath.trim().toLowerCase();
29
+ return normalized.endsWith(".md") || normalized.endsWith(".markdown");
30
+ }
31
+ async function readRecipeMarkdownAsset(recipeDir, relativePath, label) {
28
32
  const sourcePath = path.join(recipeDir, relativePath);
29
33
  if (!(await fileExists(sourcePath))) {
30
34
  throw new Error(missingFileMessage(label, relativePath));
31
35
  }
32
- const raw = JSON.parse(await readFile(sourcePath, "utf8"));
33
- if (!isRecord(raw)) {
34
- throw new Error(invalidFieldMessage(label, "JSON object", relativePath));
36
+ if (!isMarkdownAssetPath(relativePath)) {
37
+ throw new Error(invalidFieldMessage(label, "markdown file (*.md)", relativePath));
38
+ }
39
+ const raw = await readFile(sourcePath, "utf8");
40
+ if (!raw.trim()) {
41
+ throw new Error(invalidFieldMessage(label, "non-empty markdown document", relativePath));
35
42
  }
36
43
  }
37
44
  export async function validateRecipeAssets(opts) {
38
45
  for (const skill of opts.manifest.skills ?? []) {
39
- await readRecipeJsonObject(opts.recipeDir, skill.file, "recipe skill file");
46
+ await readRecipeMarkdownAsset(opts.recipeDir, skill.file, "recipe skill file");
40
47
  }
41
48
  for (const agent of opts.manifest.agents ?? []) {
42
- await readRecipeJsonObject(opts.recipeDir, agent.file, "recipe agent file");
49
+ await readRecipeMarkdownAsset(opts.recipeDir, agent.file, "recipe agent file");
43
50
  }
44
51
  for (const tool of opts.manifest.tools ?? []) {
45
52
  const entrypointPath = path.join(opts.recipeDir, tool.entrypoint);
@@ -47,6 +54,12 @@ export async function validateRecipeAssets(opts) {
47
54
  throw new Error(missingFileMessage("recipe tool entrypoint", tool.entrypoint));
48
55
  }
49
56
  }
57
+ for (const prompt of opts.manifest.prompts ?? []) {
58
+ const sourcePath = path.join(opts.recipeDir, prompt.file);
59
+ if (!(await fileExists(sourcePath))) {
60
+ throw new Error(missingFileMessage("overlay prompt file", prompt.file));
61
+ }
62
+ }
50
63
  for (const scenario of opts.manifest.scenarios ?? []) {
51
64
  const sourcePath = path.join(opts.recipeDir, scenario.file);
52
65
  if (!(await fileExists(sourcePath))) {
@@ -75,13 +88,16 @@ export async function applyRecipeAgents(opts) {
75
88
  if (!(await fileExists(sourcePath))) {
76
89
  throw new Error(missingFileMessage("recipe agent file", rawFile));
77
90
  }
78
- const rawAgent = JSON.parse(await readFile(sourcePath, "utf8"));
79
- if (!isRecord(rawAgent)) {
80
- throw new Error(invalidFieldMessage("recipe agent file", "JSON object", rawFile));
91
+ if (!isMarkdownAssetPath(rawFile)) {
92
+ throw new Error(invalidFieldMessage("recipe agent file", "markdown file (*.md)", rawFile));
93
+ }
94
+ const rawAgent = await readFile(sourcePath, "utf8");
95
+ if (!rawAgent.trim()) {
96
+ throw new Error(invalidFieldMessage("recipe agent file", "non-empty markdown document", rawFile));
81
97
  }
82
98
  const baseId = `${opts.manifest.id}__${agentId}`;
83
99
  let targetId = baseId;
84
- let targetPath = path.join(agentsDir, `${targetId}.json`);
100
+ let targetPath = path.join(agentsDir, `${targetId}.md`);
85
101
  if (await getPathKind(targetPath)) {
86
102
  if (opts.onConflict === "fail") {
87
103
  throw new CliError({
@@ -94,13 +110,16 @@ export async function applyRecipeAgents(opts) {
94
110
  let counter = 1;
95
111
  while (await getPathKind(targetPath)) {
96
112
  targetId = `${baseId}__${counter}`;
97
- targetPath = path.join(agentsDir, `${targetId}.json`);
113
+ targetPath = path.join(agentsDir, `${targetId}.md`);
98
114
  counter += 1;
99
115
  }
100
116
  }
101
117
  }
102
- rawAgent.id = targetId;
103
- await writeJsonStableIfChanged(targetPath, rawAgent);
118
+ const namespacedHeader = `# Agent: ${targetId}\n\n`;
119
+ const content = rawAgent.startsWith("# Agent:")
120
+ ? rawAgent
121
+ : `${namespacedHeader}${rawAgent.trimStart()}`;
122
+ await writeFile(targetPath, content, "utf8");
104
123
  }
105
124
  }
106
125
  export async function applyRecipeScenarios(opts) {
@@ -0,0 +1,6 @@
1
+ export declare function cmdRecipeActiveParsed(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ full: boolean;
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=active.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"active.d.ts","sourceRoot":"","sources":["../../../../../src/commands/recipes/impl/commands/active.ts"],"names":[],"mappings":"AASA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CA2ClB"}
@@ -0,0 +1,46 @@
1
+ import { resolveProject } from "@agentplaneorg/core";
2
+ import { mapCoreError } from "../../../../cli/error-map.js";
3
+ import { emptyStateMessage } from "../../../../cli/output.js";
4
+ import { CliError } from "../../../../shared/errors.js";
5
+ import { readActiveRecipeIds } from "../overlay-project.js";
6
+ import { readProjectInstalledRecipes } from "../project-installed-recipes.js";
7
+ export async function cmdRecipeActiveParsed(opts) {
8
+ try {
9
+ const project = await resolveProject({
10
+ cwd: opts.cwd,
11
+ rootOverride: opts.rootOverride ?? null,
12
+ });
13
+ const [activeIds, installed] = await Promise.all([
14
+ readActiveRecipeIds(project),
15
+ readProjectInstalledRecipes(project),
16
+ ]);
17
+ const active = activeIds
18
+ .map((id) => installed.recipes.find((entry) => entry.id === id))
19
+ .filter(Boolean);
20
+ if (active.length === 0) {
21
+ process.stdout.write(`${emptyStateMessage("active overlays")}\n`);
22
+ return 0;
23
+ }
24
+ if (opts.full) {
25
+ process.stdout.write(`${JSON.stringify({
26
+ schema_version: 1,
27
+ active: active.map((entry) => ({
28
+ id: entry.id,
29
+ version: entry.version,
30
+ kind: entry.manifest.kind,
31
+ summary: entry.manifest.summary,
32
+ })),
33
+ }, null, 2)}\n`);
34
+ return 0;
35
+ }
36
+ for (const entry of active) {
37
+ process.stdout.write(`${entry.id}@${entry.version} [${entry.manifest.kind}]\n`);
38
+ }
39
+ return 0;
40
+ }
41
+ catch (err) {
42
+ if (err instanceof CliError)
43
+ throw err;
44
+ throw mapCoreError(err, { command: "recipes active", root: opts.rootOverride ?? null });
45
+ }
46
+ }
@@ -0,0 +1,7 @@
1
+ export declare function cmdRecipeAddParsed(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ recipeRef: string;
5
+ mode?: "copy" | "link";
6
+ }): Promise<number>;
7
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../../../src/commands/recipes/impl/commands/add.ts"],"names":[],"mappings":"AAqCA,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFlB"}
@@ -0,0 +1,100 @@
1
+ import { cp, mkdir, rm, symlink } from "node:fs/promises";
2
+ import { loadConfig, resolveProject } from "@agentplaneorg/core";
3
+ import { mapCoreError } from "../../../../cli/error-map.js";
4
+ import { exitCodeForError } from "../../../../cli/exit-codes.js";
5
+ import { CliError } from "../../../../shared/errors.js";
6
+ import { refreshProjectOverlayArtifacts } from "../overlay-project.js";
7
+ import { readInstalledRecipesFile } from "../installed-recipes.js";
8
+ import { normalizeRecipeTags } from "../normalize.js";
9
+ import { hashRecipeTree } from "../project-recipe-state.js";
10
+ import { readProjectRecipesRegistry, upsertProjectRecipeRegistryEntry, } from "../project-registry.js";
11
+ import { resolveInstalledRecipeDir, resolveInstalledRecipesPath, resolveProjectRecipesPackagesDir, resolveProjectVendoredRecipeDir, } from "../paths.js";
12
+ function parseRecipeRef(raw) {
13
+ const value = raw.trim();
14
+ if (!value) {
15
+ throw new CliError({
16
+ exitCode: 3,
17
+ code: "E_VALIDATION",
18
+ message: "Recipe id must not be empty",
19
+ });
20
+ }
21
+ const atIndex = value.lastIndexOf("@");
22
+ if (atIndex <= 0)
23
+ return { id: value };
24
+ return { id: value.slice(0, atIndex), version: value.slice(atIndex + 1) || undefined };
25
+ }
26
+ export async function cmdRecipeAddParsed(opts) {
27
+ try {
28
+ const project = await resolveProject({
29
+ cwd: opts.cwd,
30
+ rootOverride: opts.rootOverride ?? null,
31
+ });
32
+ const loaded = await loadConfig(project.agentplaneDir);
33
+ const requested = parseRecipeRef(opts.recipeRef);
34
+ const cache = await readInstalledRecipesFile(resolveInstalledRecipesPath());
35
+ const cachedEntries = cache.recipes
36
+ .filter((entry) => entry.id === requested.id)
37
+ .toSorted((left, right) => left.version.localeCompare(right.version));
38
+ const cached = requested.version
39
+ ? cachedEntries.find((entry) => entry.version === requested.version)
40
+ : cachedEntries.at(-1);
41
+ if (!cached) {
42
+ throw new CliError({
43
+ exitCode: exitCodeForError("E_IO"),
44
+ code: "E_IO",
45
+ message: requested.version
46
+ ? `Recipe not found in global cache: ${requested.id}@${requested.version}. Run agentplane recipes install ${requested.id}@${requested.version}`
47
+ : `Recipe not found in global cache: ${requested.id}. Run agentplane recipes install ${requested.id}`,
48
+ });
49
+ }
50
+ const materialization = opts.mode ?? (loaded.config.recipes?.storage_default === "link" ? "link" : "copy");
51
+ const sourceDir = resolveInstalledRecipeDir({ id: cached.id, version: cached.version });
52
+ const targetDir = resolveProjectVendoredRecipeDir(project, cached.id);
53
+ const registry = await readProjectRecipesRegistry(project);
54
+ const existing = registry.recipes.find((entry) => entry.id === cached.id);
55
+ if (existing) {
56
+ throw new CliError({
57
+ exitCode: exitCodeForError("E_USAGE"),
58
+ code: "E_USAGE",
59
+ message: existing.version === cached.version
60
+ ? `Recipe already vendored: ${cached.id}@${cached.version}. Use agentplane recipes update ${cached.id} to resync it from cache.`
61
+ : `Recipe already vendored: ${cached.id}@${existing.version}. Remove it first or use a dedicated update flow instead of overwriting it with recipes add.`,
62
+ });
63
+ }
64
+ await mkdir(resolveProjectRecipesPackagesDir(project), { recursive: true });
65
+ await rm(targetDir, { recursive: true, force: true });
66
+ await (materialization === "link"
67
+ ? symlink(sourceDir, targetDir, "dir")
68
+ : cp(sourceDir, targetDir, { recursive: true }));
69
+ const installedAt = new Date().toISOString();
70
+ const tags = normalizeRecipeTags(cached.tags ?? cached.manifest.tags ?? []);
71
+ const sourceSha256 = await hashRecipeTree(sourceDir);
72
+ const vendoredSha256 = await hashRecipeTree(targetDir);
73
+ await upsertProjectRecipeRegistryEntry({
74
+ project,
75
+ entry: {
76
+ id: cached.id,
77
+ version: cached.version,
78
+ path: `packages/${cached.id}`,
79
+ active: false,
80
+ materialization,
81
+ source_ref: `${cached.id}@${cached.version}`,
82
+ source_sha256: sourceSha256,
83
+ vendored_sha256: vendoredSha256,
84
+ installed_at: installedAt,
85
+ tags,
86
+ },
87
+ });
88
+ await refreshProjectOverlayArtifacts(project);
89
+ process.stdout.write(`Vendored recipe ${cached.id}@${cached.version} into project (${materialization})\n`);
90
+ if (materialization === "link") {
91
+ process.stdout.write("Warning: link mode is not portable; use `agentplane recipes detach` before sharing the repo.\n");
92
+ }
93
+ return 0;
94
+ }
95
+ catch (err) {
96
+ if (err instanceof CliError)
97
+ throw err;
98
+ throw mapCoreError(err, { command: "recipes add", root: opts.rootOverride ?? null });
99
+ }
100
+ }
@@ -0,0 +1,6 @@
1
+ export declare function cmdRecipeDetachParsed(opts: {
2
+ cwd: string;
3
+ rootOverride?: string;
4
+ id: string;
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=detach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detach.d.ts","sourceRoot":"","sources":["../../../../../src/commands/recipes/impl/commands/detach.ts"],"names":[],"mappings":"AAgBA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,MAAM,CAAC,CA+ElB"}