agentplane 0.2.12 → 0.2.14

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 (55) hide show
  1. package/README.md +4 -0
  2. package/assets/AGENTS.md +17 -0
  3. package/dist/cli/command-guide.js +1 -1
  4. package/dist/cli/run-cli/command-catalog.js +4 -4
  5. package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
  6. package/dist/cli/run-cli/commands/config.js +17 -38
  7. package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
  8. package/dist/cli/run-cli/commands/core.js +100 -71
  9. package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
  10. package/dist/cli/run-cli/commands/ide.js +3 -9
  11. package/dist/cli/run-cli/commands/init/ui.d.ts +3 -0
  12. package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -0
  13. package/dist/cli/run-cli/commands/init/ui.js +38 -0
  14. package/dist/cli/run-cli/commands/init/write-config.d.ts +13 -0
  15. package/dist/cli/run-cli/commands/init/write-config.d.ts.map +1 -1
  16. package/dist/cli/run-cli/commands/init/write-config.js +1 -0
  17. package/dist/cli/run-cli/commands/init/write-gitignore.d.ts +2 -1
  18. package/dist/cli/run-cli/commands/init/write-gitignore.d.ts.map +1 -1
  19. package/dist/cli/run-cli/commands/init/write-gitignore.js +19 -6
  20. package/dist/cli/run-cli/commands/init.d.ts +3 -0
  21. package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
  22. package/dist/cli/run-cli/commands/init.js +114 -9
  23. package/dist/cli/run-cli/commands/wrap-command.d.ts +6 -0
  24. package/dist/cli/run-cli/commands/wrap-command.d.ts.map +1 -0
  25. package/dist/cli/run-cli/commands/wrap-command.js +17 -0
  26. package/dist/cli/run-cli.d.ts.map +1 -1
  27. package/dist/cli/run-cli.js +5 -3
  28. package/dist/commands/doctor.command.d.ts +2 -7
  29. package/dist/commands/doctor.command.d.ts.map +1 -1
  30. package/dist/commands/doctor.command.js +2 -137
  31. package/dist/commands/doctor.run.d.ts +4 -0
  32. package/dist/commands/doctor.run.d.ts.map +1 -0
  33. package/dist/commands/doctor.run.js +174 -0
  34. package/dist/commands/doctor.spec.d.ts +7 -0
  35. package/dist/commands/doctor.spec.d.ts.map +1 -0
  36. package/dist/commands/doctor.spec.js +20 -0
  37. package/dist/commands/recipes/install.command.d.ts +2 -11
  38. package/dist/commands/recipes/install.command.d.ts.map +1 -1
  39. package/dist/commands/recipes/install.command.js +2 -161
  40. package/dist/commands/recipes/install.run.d.ts +4 -0
  41. package/dist/commands/recipes/install.run.d.ts.map +1 -0
  42. package/dist/commands/recipes/install.run.js +23 -0
  43. package/dist/commands/recipes/install.spec.d.ts +11 -0
  44. package/dist/commands/recipes/install.spec.d.ts.map +1 -0
  45. package/dist/commands/recipes/install.spec.js +140 -0
  46. package/dist/commands/shared/git-context.d.ts +3 -0
  47. package/dist/commands/shared/git-context.d.ts.map +1 -1
  48. package/dist/commands/shared/git-context.js +10 -0
  49. package/dist/commands/task/finish.d.ts.map +1 -1
  50. package/dist/commands/task/finish.js +34 -2
  51. package/dist/commands/task/set-status.d.ts.map +1 -1
  52. package/dist/commands/task/set-status.js +10 -0
  53. package/dist/commands/upgrade.d.ts.map +1 -1
  54. package/dist/commands/upgrade.js +23 -2
  55. package/package.json +1 -1
package/README.md CHANGED
@@ -24,6 +24,9 @@ agentplane init
24
24
  agentplane quickstart
25
25
  ```
26
26
 
27
+ `agentplane init` is human-oriented: interactive onboarding includes workflow/backend selection,
28
+ execution profile selection (`conservative|balanced|aggressive`), approval toggles, and optional recipes.
29
+
27
30
  Create your first task and run the workflow:
28
31
 
29
32
  ```bash
@@ -45,6 +48,7 @@ npx agentplane quickstart
45
48
  - `AGENTS.md` is created if missing and defines the policy/guardrails.
46
49
  - Built-in agent definitions are copied into `.agentplane/agents/`.
47
50
  - Optional recipes can install additional agents when you run `agentplane recipes install ...`.
51
+ - `.agentplane/config.json` stores execution defaults under `execution` (profile, reasoning effort, tool budget, safety gates).
48
52
 
49
53
  ## Upgrade review reports
50
54
 
package/assets/AGENTS.md CHANGED
@@ -107,6 +107,23 @@ Outside-repo includes (non-exhaustive):
107
107
  - modifying keychains, ssh keys, credential stores
108
108
  - any tool that mutates outside-repo state
109
109
 
110
+ ## Execution Profile
111
+
112
+ `execution` settings in `.agentplane/config.json` define operational behavior defaults for agents:
113
+
114
+ - `profile`: `conservative` / `balanced` / `aggressive`
115
+ - `reasoning_effort`: `low` / `medium` / `high`
116
+ - `tool_budget`: `{ discovery, implementation, verification }`
117
+ - `stop_conditions`: conditions that force a stop/re-plan/escalation
118
+ - `handoff_conditions`: conditions that trigger handoff to another role
119
+ - `unsafe_actions_requiring_explicit_user_ok`: actions that require explicit user confirmation
120
+
121
+ Scope and precedence:
122
+
123
+ - These settings tune execution style only (autonomy, effort, budget, stop/handoff heuristics).
124
+ - They MUST NOT override role authority boundaries, source-of-truth order, approval gates, or hard invariants defined in this `AGENTS.md`.
125
+ - If `execution` config conflicts with policy, `AGENTS.md` policy wins.
126
+
110
127
  ## Framework Upgrade / Prompt Merge
111
128
 
112
129
  `agentplane upgrade` is responsible for mechanical upgrades and safe merges. When an upgrade run indicates a potential semantic conflict (for example, both local and incoming changes exist relative to a baseline, or a baseline is missing but files differ), treat the result as requiring a meaning-level review.
@@ -244,7 +244,7 @@ export function renderQuickstart() {
244
244
  "## Global flags",
245
245
  "",
246
246
  "- `--root <path>`: treat <path> as project root",
247
- "- `--json`: emit JSON-formatted errors",
247
+ "- `--json-errors`: emit JSON-formatted errors",
248
248
  "- `--help` / `-h`: show help",
249
249
  "- `--version`: show version",
250
250
  "- `--no-update-check`: skip checking npm for a newer CLI version",
@@ -34,7 +34,7 @@ import { workStartSpec } from "../../commands/branch/work-start.command.js";
34
34
  import { branchBaseClearSpec, branchBaseExplainSpec, branchBaseGetSpec, branchBaseSetSpec, branchBaseSpec, } from "../../commands/branch/base.command.js";
35
35
  import { branchStatusSpec } from "../../commands/branch/status.command.js";
36
36
  import { branchRemoveSpec } from "../../commands/branch/remove.command.js";
37
- import { recipesInstallSpec } from "../../commands/recipes/install.command.js";
37
+ import { recipesInstallSpec } from "../../commands/recipes/install.spec.js";
38
38
  import { recipesListSpec } from "../../commands/recipes/list.command.js";
39
39
  import { recipesListRemoteSpec } from "../../commands/recipes/list-remote.command.js";
40
40
  import { recipesInfoSpec } from "../../commands/recipes/info.command.js";
@@ -58,7 +58,7 @@ import { blockSpec } from "../../commands/block.spec.js";
58
58
  import { verifySpec } from "../../commands/verify.spec.js";
59
59
  import { finishSpec } from "../../commands/finish.spec.js";
60
60
  import { readySpec } from "../../commands/ready.command.js";
61
- import { doctorSpec } from "../../commands/doctor.command.js";
61
+ import { doctorSpec } from "../../commands/doctor.spec.js";
62
62
  import { docsCliSpec } from "../../commands/docs/cli.command.js";
63
63
  import { hooksSpec } from "../../commands/hooks/hooks.command.js";
64
64
  import { hooksInstallSpec } from "../../commands/hooks/install.command.js";
@@ -147,7 +147,7 @@ export const COMMANDS = [
147
147
  needsConfig: true,
148
148
  needsTaskContext: false,
149
149
  }),
150
- entry(doctorSpec, () => import("../../commands/doctor.command.js").then((m) => m.runDoctor), {
150
+ entry(doctorSpec, () => import("../../commands/doctor.run.js").then((m) => m.runDoctor), {
151
151
  needsProject: true,
152
152
  needsConfig: false,
153
153
  needsTaskContext: false,
@@ -189,7 +189,7 @@ export const COMMANDS = [
189
189
  entry(recipesExplainSpec, () => import("../../commands/recipes/explain.command.js").then((m) => m.runRecipesExplain)),
190
190
  entry(recipesRemoveSpec, () => import("../../commands/recipes/remove.command.js").then((m) => m.runRecipesRemove)),
191
191
  entry(recipesCachePruneSpec, () => import("../../commands/recipes/cache-prune.command.js").then((m) => m.runRecipesCachePrune)),
192
- entry(recipesInstallSpec, () => import("../../commands/recipes/install.command.js").then((m) => m.runRecipesInstall)),
192
+ entry(recipesInstallSpec, () => import("../../commands/recipes/install.run.js").then((m) => m.runRecipesInstall)),
193
193
  entry(scenarioSpec, () => import("../../commands/scenario/scenario.command.js").then((m) => m.runScenario)),
194
194
  entry(scenarioListSpec, () => import("../../commands/scenario/list.command.js").then((m) => m.runScenarioList)),
195
195
  entry(scenarioInfoSpec, () => import("../../commands/scenario/info.command.js").then((m) => m.runScenarioInfo)),
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9C,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAMxD,CAAC;AAiBF,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,gBAAgB,CAAC,CAExF;AAED,KAAK,eAAe,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,eAAe,CAgBtD,CAAC;AA6BF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,eAAe,CAAC,CAStF;AAED,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE3C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAMlD,CAAC;AAiBF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAElF;AAED,KAAK,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAgBlD,CAAC;AA0BF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAQlF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9C,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAMxD,CAAC;AAcF,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,gBAAgB,CAAC,CAExF;AAED,KAAK,eAAe,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,eAAe,CAgBtD,CAAC;AA6BF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,eAAe,CAAC,CAStF;AAED,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE3C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAMlD,CAAC;AAcF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAElF;AAED,KAAK,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAgBlD,CAAC;AA0BF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAQlF"}
@@ -1,8 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { saveConfig, setByDottedKey } from "@agentplaneorg/core";
3
- import { mapCoreError } from "../../error-map.js";
4
3
  import { usageError } from "../../spec/errors.js";
5
- import { CliError } from "../../../shared/errors.js";
4
+ import { wrapCommand } from "./wrap-command.js";
6
5
  export const configShowSpec = {
7
6
  id: ["config", "show"],
8
7
  group: "Config",
@@ -11,16 +10,11 @@ export const configShowSpec = {
11
10
  parse: () => ({}),
12
11
  };
13
12
  async function cmdConfigShow(opts) {
14
- try {
13
+ return wrapCommand({ command: "config show", rootOverride: opts.rootOverride }, async () => {
15
14
  const loaded = await opts.deps.getLoadedConfig("config show");
16
15
  process.stdout.write(`${JSON.stringify(loaded.raw, null, 2)}\n`);
17
16
  return 0;
18
- }
19
- catch (err) {
20
- if (err instanceof CliError)
21
- throw err;
22
- throw mapCoreError(err, { command: "config show", root: opts.rootOverride ?? null });
23
- }
17
+ });
24
18
  }
25
19
  export function makeRunConfigShowHandler(deps) {
26
20
  return (ctx) => cmdConfigShow({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, deps });
@@ -43,7 +37,11 @@ export const configSetSpec = {
43
37
  parse: (raw) => ({ key: String(raw.args.key ?? ""), value: String(raw.args.value ?? "") }),
44
38
  };
45
39
  async function cmdConfigSet(opts) {
46
- try {
40
+ return wrapCommand({
41
+ command: "config set",
42
+ rootOverride: opts.rootOverride,
43
+ context: { key: opts.key },
44
+ }, async () => {
47
45
  const resolved = await opts.deps.getResolvedProject("config set");
48
46
  const loaded = await opts.deps.getLoadedConfig("config set");
49
47
  const raw = { ...loaded.raw };
@@ -51,16 +49,7 @@ async function cmdConfigSet(opts) {
51
49
  await saveConfig(resolved.agentplaneDir, raw);
52
50
  process.stdout.write(`${path.relative(resolved.gitRoot, path.join(resolved.agentplaneDir, "config.json"))}\n`);
53
51
  return 0;
54
- }
55
- catch (err) {
56
- if (err instanceof CliError)
57
- throw err;
58
- throw mapCoreError(err, {
59
- command: "config set",
60
- key: opts.key,
61
- root: opts.rootOverride ?? null,
62
- });
63
- }
52
+ });
64
53
  }
65
54
  export function makeRunConfigSetHandler(deps) {
66
55
  return (ctx, p) => cmdConfigSet({
@@ -79,16 +68,11 @@ export const modeGetSpec = {
79
68
  parse: () => ({}),
80
69
  };
81
70
  async function cmdModeGet(opts) {
82
- try {
71
+ return wrapCommand({ command: "mode get", rootOverride: opts.rootOverride }, async () => {
83
72
  const loaded = await opts.deps.getLoadedConfig("mode get");
84
73
  process.stdout.write(`${loaded.config.workflow_mode}\n`);
85
74
  return 0;
86
- }
87
- catch (err) {
88
- if (err instanceof CliError)
89
- throw err;
90
- throw mapCoreError(err, { command: "mode get", root: opts.rootOverride ?? null });
91
- }
75
+ });
92
76
  }
93
77
  export function makeRunModeGetHandler(deps) {
94
78
  return (ctx) => cmdModeGet({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, deps });
@@ -111,7 +95,11 @@ export const modeSetSpec = {
111
95
  },
112
96
  };
113
97
  async function cmdModeSet(opts) {
114
- try {
98
+ return wrapCommand({
99
+ command: "mode set",
100
+ rootOverride: opts.rootOverride,
101
+ context: { mode: opts.mode },
102
+ }, async () => {
115
103
  const resolved = await opts.deps.getResolvedProject("mode set");
116
104
  const loaded = await opts.deps.getLoadedConfig("mode set");
117
105
  const raw = { ...loaded.raw };
@@ -119,16 +107,7 @@ async function cmdModeSet(opts) {
119
107
  await saveConfig(resolved.agentplaneDir, raw);
120
108
  process.stdout.write(`${opts.mode}\n`);
121
109
  return 0;
122
- }
123
- catch (err) {
124
- if (err instanceof CliError)
125
- throw err;
126
- throw mapCoreError(err, {
127
- command: "mode set",
128
- root: opts.rootOverride ?? null,
129
- mode: opts.mode,
130
- });
131
- }
110
+ });
132
111
  }
133
112
  export function makeRunModeSetHandler(deps) {
134
113
  return (ctx, p) => cmdModeSet({
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/core.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9C,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAOxD,CAAC;AAYF,eAAO,MAAM,aAAa,EAAE,cAAc,CAAC,gBAAgB,CAG1D,CAAC;AAEF,KAAK,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC,eAAO,MAAM,QAAQ,EAAE,WAAW,CAAC,UAAU,CAO5C,CAAC;AAgLF,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,UAAU,CAE9C,CAAC;AAEF,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE1C,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAMhD,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,CA+DhF"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/core.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAIrD,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9C,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAOxD,CAAC;AASF,eAAO,MAAM,aAAa,EAAE,cAAc,CAAC,gBAAgB,CAE1D,CAAC;AAEF,KAAK,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC,eAAO,MAAM,QAAQ,EAAE,WAAW,CAAC,UAAU,CAO5C,CAAC;AAkMF,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,UAAU,CAE9C,CAAC;AAEF,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE1C,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAMhD,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,CA0FhF"}
@@ -1,13 +1,13 @@
1
1
  import { readdir, readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { resolveProject } from "@agentplaneorg/core";
4
- import { mapCoreError } from "../../error-map.js";
5
4
  import { fileExists } from "../../fs-utils.js";
6
5
  import { CliError } from "../../../shared/errors.js";
7
6
  import { dedupeStrings } from "../../../shared/strings.js";
8
7
  import { usageError } from "../../spec/errors.js";
9
8
  import { listRoles, renderQuickstart, renderRole } from "../../command-guide.js";
10
9
  import { toStringList } from "../../spec/parse-utils.js";
10
+ import { wrapCommand } from "./wrap-command.js";
11
11
  export const quickstartSpec = {
12
12
  id: ["quickstart"],
13
13
  group: "Core",
@@ -16,20 +16,14 @@ export const quickstartSpec = {
16
16
  examples: [{ cmd: "agentplane quickstart", why: "Show quickstart." }],
17
17
  parse: () => ({}),
18
18
  };
19
- function cmdQuickstart(opts) {
20
- try {
19
+ async function cmdQuickstart(opts) {
20
+ return wrapCommand({ command: "quickstart", rootOverride: opts.rootOverride }, () => {
21
21
  process.stdout.write(`${renderQuickstart()}\n`);
22
22
  return 0;
23
- }
24
- catch (err) {
25
- if (err instanceof CliError)
26
- throw err;
27
- throw mapCoreError(err, { command: "quickstart", root: opts.rootOverride ?? null });
28
- }
23
+ });
29
24
  }
30
25
  export const runQuickstart = (ctx) => {
31
- cmdQuickstart({ cwd: ctx.cwd, rootOverride: ctx.rootOverride });
32
- return Promise.resolve(0);
26
+ return cmdQuickstart({ cwd: ctx.cwd, rootOverride: ctx.rootOverride });
33
27
  };
34
28
  export const roleSpec = {
35
29
  id: ["role"],
@@ -39,6 +33,27 @@ export const roleSpec = {
39
33
  examples: [{ cmd: "agentplane role ORCHESTRATOR", why: "Show ORCHESTRATOR guide." }],
40
34
  parse: (raw) => ({ role: String(raw.args.role ?? "") }),
41
35
  };
36
+ function parseAgentProfileJson(filePath, text) {
37
+ let parsed;
38
+ try {
39
+ parsed = JSON.parse(text);
40
+ }
41
+ catch {
42
+ throw new CliError({
43
+ exitCode: 3,
44
+ code: "E_VALIDATION",
45
+ message: `Invalid agent profile JSON: ${filePath} (malformed JSON)`,
46
+ });
47
+ }
48
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
49
+ throw new CliError({
50
+ exitCode: 3,
51
+ code: "E_VALIDATION",
52
+ message: `Invalid agent profile JSON: ${filePath} (expected object)`,
53
+ });
54
+ }
55
+ return parsed;
56
+ }
42
57
  function normalizeRoleId(roleRaw) {
43
58
  return roleRaw.trim().toUpperCase();
44
59
  }
@@ -87,7 +102,7 @@ async function readAgentProfile(opts) {
87
102
  return null;
88
103
  const filename = `${foundId}.json`;
89
104
  const filePath = path.join(listing.agentplaneDir, "agents", filename);
90
- const raw = JSON.parse(await readFile(filePath, "utf8"));
105
+ const raw = parseAgentProfileJson(filePath, await readFile(filePath, "utf8"));
91
106
  return { agentplaneDir: listing.agentplaneDir, filename, profile: raw };
92
107
  }
93
108
  function renderAgentProfileBlock(opts) {
@@ -112,7 +127,7 @@ function renderAgentProfileBlock(opts) {
112
127
  return lines.join("\n").trimEnd();
113
128
  }
114
129
  async function cmdRole(opts) {
115
- try {
130
+ return wrapCommand({ command: "role", rootOverride: opts.rootOverride }, async () => {
116
131
  const roleRaw = opts.role.trim();
117
132
  if (!roleRaw) {
118
133
  throw usageError({
@@ -170,12 +185,7 @@ async function cmdRole(opts) {
170
185
  });
171
186
  process.stdout.write(`${block}\n`);
172
187
  return 0;
173
- }
174
- catch (err) {
175
- if (err instanceof CliError)
176
- throw err;
177
- throw mapCoreError(err, { command: "role", root: opts.rootOverride ?? null });
178
- }
188
+ });
179
189
  }
180
190
  export const runRole = (ctx, p) => {
181
191
  return cmdRole({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, role: p.role });
@@ -188,64 +198,83 @@ export const agentsSpec = {
188
198
  parse: () => ({}),
189
199
  };
190
200
  export function makeRunAgentsHandler(deps) {
191
- return async (ctx) => {
192
- try {
193
- const resolved = await deps.getResolvedProject("agents");
194
- const agentsDir = path.join(resolved.agentplaneDir, "agents");
195
- if (!(await fileExists(agentsDir))) {
196
- throw new CliError({
197
- exitCode: 2,
198
- code: "E_USAGE",
199
- message: `Agents directory not found: ${agentsDir} (run \`agentplane init\`)`,
200
- });
201
+ return async (ctx) => wrapCommand({ command: "agents", rootOverride: ctx.rootOverride }, async () => {
202
+ const resolved = await deps.getResolvedProject("agents");
203
+ const agentsDir = path.join(resolved.agentplaneDir, "agents");
204
+ if (!(await fileExists(agentsDir))) {
205
+ throw new CliError({
206
+ exitCode: 2,
207
+ code: "E_USAGE",
208
+ message: `Agents directory not found: ${agentsDir} (run \`agentplane init\`)`,
209
+ });
210
+ }
211
+ const entriesRaw = await readdir(agentsDir);
212
+ const entries = entriesRaw.filter((name) => name.endsWith(".json")).toSorted();
213
+ if (entries.length === 0) {
214
+ throw new CliError({
215
+ exitCode: 2,
216
+ code: "E_USAGE",
217
+ message: `No agent definitions found under ${agentsDir} (expected *.json)`,
218
+ });
219
+ }
220
+ const rows = [];
221
+ const seen = new Set();
222
+ const duplicates = [];
223
+ const mismatches = [];
224
+ for (const entry of entries) {
225
+ const canonicalId = entry.replace(/\.json$/i, "");
226
+ const filePath = path.join(agentsDir, entry);
227
+ const raw = parseAgentProfileJson(filePath, await readFile(filePath, "utf8"));
228
+ const rawId = typeof raw.id === "string" ? raw.id : "";
229
+ const rawRole = typeof raw.role === "string" ? raw.role : "";
230
+ const normalizedRawId = rawId.trim();
231
+ const role = rawRole.trim() || "-";
232
+ if (seen.has(canonicalId)) {
233
+ duplicates.push(canonicalId);
201
234
  }
202
- const entriesRaw = await readdir(agentsDir);
203
- const entries = entriesRaw.filter((name) => name.endsWith(".json")).toSorted();
204
- if (entries.length === 0) {
205
- throw new CliError({
206
- exitCode: 2,
207
- code: "E_USAGE",
208
- message: `No agent definitions found under ${agentsDir} (expected *.json)`,
209
- });
235
+ else {
236
+ seen.add(canonicalId);
210
237
  }
211
- const rows = [];
212
- const seen = new Set();
213
- const duplicates = [];
214
- for (const entry of entries) {
215
- const filePath = path.join(agentsDir, entry);
216
- const raw = JSON.parse(await readFile(filePath, "utf8"));
217
- const rawId = typeof raw.id === "string" ? raw.id : "";
218
- const rawRole = typeof raw.role === "string" ? raw.role : "";
219
- const agentId = rawId.trim() || "<missing-id>";
220
- const role = rawRole.trim() || "-";
221
- if (seen.has(agentId)) {
222
- duplicates.push(agentId);
223
- }
224
- else {
225
- seen.add(agentId);
226
- }
227
- rows.push([agentId, role, entry]);
238
+ if (normalizedRawId.length > 0 && normalizedRawId !== canonicalId) {
239
+ mismatches.push({ filename: entry, canonicalId, rawId: normalizedRawId });
240
+ }
241
+ rows.push({ canonicalId, role, filename: entry, rawId: normalizedRawId });
242
+ }
243
+ const showRawIdColumn = mismatches.length > 0;
244
+ const widthId = Math.max(...rows.map((row) => row.canonicalId.length), "ID".length);
245
+ const widthFile = Math.max(...rows.map((row) => row.filename.length), "FILE".length);
246
+ if (showRawIdColumn) {
247
+ const widthRawId = Math.max(...rows.map((row) => row.rawId.length), "RAW_ID".length);
248
+ process.stdout.write(`${"ID".padEnd(widthId)} ${"FILE".padEnd(widthFile)} ${"RAW_ID".padEnd(widthRawId)} ROLE\n`);
249
+ process.stdout.write(`${"-".repeat(widthId)} ${"-".repeat(widthFile)} ${"-".repeat(widthRawId)} ----\n`);
250
+ for (const row of rows) {
251
+ process.stdout.write(`${row.canonicalId.padEnd(widthId)} ${row.filename.padEnd(widthFile)} ${row.rawId.padEnd(widthRawId)} ${row.role}\n`);
228
252
  }
229
- const widthId = Math.max(...rows.map((row) => row[0].length), "ID".length);
230
- const widthFile = Math.max(...rows.map((row) => row[2].length), "FILE".length);
253
+ }
254
+ else {
231
255
  process.stdout.write(`${"ID".padEnd(widthId)} ${"FILE".padEnd(widthFile)} ROLE\n`);
232
256
  process.stdout.write(`${"-".repeat(widthId)} ${"-".repeat(widthFile)} ----\n`);
233
- for (const [agentId, role, filename] of rows) {
234
- process.stdout.write(`${agentId.padEnd(widthId)} ${filename.padEnd(widthFile)} ${role}\n`);
235
- }
236
- if (duplicates.length > 0) {
237
- throw new CliError({
238
- exitCode: 2,
239
- code: "E_USAGE",
240
- message: `Duplicate agent ids: ${dedupeStrings(duplicates).toSorted().join(", ")}`,
241
- });
257
+ for (const row of rows) {
258
+ process.stdout.write(`${row.canonicalId.padEnd(widthId)} ${row.filename.padEnd(widthFile)} ${row.role}\n`);
242
259
  }
243
- return 0;
244
260
  }
245
- catch (err) {
246
- if (err instanceof CliError)
247
- throw err;
248
- throw mapCoreError(err, { command: "agents", root: ctx.rootOverride ?? null });
261
+ if (duplicates.length > 0) {
262
+ throw new CliError({
263
+ exitCode: 2,
264
+ code: "E_USAGE",
265
+ message: `Duplicate canonical agent ids: ${dedupeStrings(duplicates).toSorted().join(", ")}`,
266
+ });
267
+ }
268
+ if (mismatches.length > 0) {
269
+ const details = mismatches
270
+ .map((m) => `${m.filename}: raw id "${m.rawId}" != canonical "${m.canonicalId}"`)
271
+ .join("; ");
272
+ throw new CliError({
273
+ exitCode: 2,
274
+ code: "E_USAGE",
275
+ message: `Agent profile id mismatch: ${details}`,
276
+ });
249
277
  }
250
- };
278
+ return 0;
279
+ });
251
280
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ide.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/ide.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,KAAK,aAAa,GAAG;IAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;CAAE,CAAC;AAErD,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAkBlD,CAAC;AAEF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CA2ClB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAElF"}
1
+ {"version":3,"file":"ide.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/ide.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,KAAK,aAAa,GAAG;IAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;CAAE,CAAC;AAErD,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,aAAa,CAkBlD,CAAC;AAEF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAwClB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAElF"}
@@ -1,8 +1,7 @@
1
1
  import { mkdir, readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { mapCoreError } from "../../error-map.js";
4
3
  import { writeTextIfChanged } from "../../../shared/write-if-changed.js";
5
- import { CliError } from "../../../shared/errors.js";
4
+ import { wrapCommand } from "./wrap-command.js";
6
5
  export const ideSyncSpec = {
7
6
  id: ["ide", "sync"],
8
7
  group: "IDE",
@@ -23,7 +22,7 @@ export const ideSyncSpec = {
23
22
  parse: (raw) => ({ ide: raw.opts.ide }),
24
23
  };
25
24
  export async function cmdIdeSync(opts) {
26
- try {
25
+ return wrapCommand({ command: "ide sync", rootOverride: opts.rootOverride }, async () => {
27
26
  const resolved = await opts.deps.getResolvedProject("ide sync");
28
27
  const agentsPath = path.join(resolved.gitRoot, "AGENTS.md");
29
28
  const agentsText = await readFile(agentsPath, "utf8");
@@ -56,12 +55,7 @@ export async function cmdIdeSync(opts) {
56
55
  process.stdout.write(`${path.relative(resolved.gitRoot, windsurfPath)}\n`);
57
56
  }
58
57
  return 0;
59
- }
60
- catch (err) {
61
- if (err instanceof CliError)
62
- throw err;
63
- throw mapCoreError(err, { command: "ide sync", root: opts.rootOverride ?? null });
64
- }
58
+ });
65
59
  }
66
60
  export function makeRunIdeSyncHandler(deps) {
67
61
  return (ctx, p) => cmdIdeSync({ cwd: ctx.cwd, rootOverride: ctx.rootOverride, ide: p.ide, deps });
@@ -0,0 +1,3 @@
1
+ export declare function renderInitWelcome(): string;
2
+ export declare function renderInitSection(title: string, description: string): string;
3
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/ui.ts"],"names":[],"mappings":"AAsBA,wBAAgB,iBAAiB,IAAI,MAAM,CAa1C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAG5E"}
@@ -0,0 +1,38 @@
1
+ function useColor() {
2
+ return process.stdout.isTTY === true && (process.env.TERM ?? "dumb") !== "dumb";
3
+ }
4
+ function color(text, code) {
5
+ if (!useColor())
6
+ return text;
7
+ return `\u001B[${code}m${text}\u001B[0m`;
8
+ }
9
+ function padLine(line, width) {
10
+ if (line.length >= width)
11
+ return line;
12
+ return `${line}${" ".repeat(width - line.length)}`;
13
+ }
14
+ function box(lines) {
15
+ const width = Math.max(...lines.map((line) => line.length), 0);
16
+ const top = `┌${"─".repeat(width + 2)}┐`;
17
+ const body = lines.map((line) => `│ ${padLine(line, width)} │`);
18
+ const bottom = `└${"─".repeat(width + 2)}┘`;
19
+ return [top, ...body, bottom].join("\n");
20
+ }
21
+ export function renderInitWelcome() {
22
+ const logo = [
23
+ " ___ ____ ____ _ _ _____ ",
24
+ " / _ | / __// __// | / / ___/ ",
25
+ " / __ |/ _/ / _/ / |/ / /__ ",
26
+ String.raw `/_/ |_|\__/ /___//_/|_/\___/ `,
27
+ " agent/plane ",
28
+ ].map((line) => color(line, "36"));
29
+ const intro = [
30
+ color("Bootstrap an agent-first workflow in this repository.", "1"),
31
+ "This interactive setup runs once; daily work is executed by agents.",
32
+ ];
33
+ return `${logo.join("\n")}\n\n${box(intro)}\n`;
34
+ }
35
+ export function renderInitSection(title, description) {
36
+ const header = color(`[${title}]`, "33");
37
+ return `${header}\n${description}\n`;
38
+ }
@@ -1,3 +1,15 @@
1
+ export type InitExecutionConfig = {
2
+ profile: "conservative" | "balanced" | "aggressive";
3
+ reasoning_effort: "low" | "medium" | "high";
4
+ tool_budget: {
5
+ discovery: number;
6
+ implementation: number;
7
+ verification: number;
8
+ };
9
+ stop_conditions: string[];
10
+ handoff_conditions: string[];
11
+ unsafe_actions_requiring_explicit_user_ok: string[];
12
+ };
1
13
  export declare function ensureAgentplaneDirs(agentplaneDir: string): Promise<void>;
2
14
  export declare function writeInitConfig(opts: {
3
15
  agentplaneDir: string;
@@ -7,6 +19,7 @@ export declare function writeInitConfig(opts: {
7
19
  requirePlanApproval: boolean;
8
20
  requireNetworkApproval: boolean;
9
21
  requireVerifyApproval: boolean;
22
+ execution: InitExecutionConfig;
10
23
  }): Promise<void>;
11
24
  export declare function writeBackendStubs(opts: {
12
25
  localBackendPath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"write-config.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-config.ts"],"names":[],"mappings":"AAOA,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO/E;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,qBAAqB,EAAE,OAAO,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhB"}
1
+ {"version":3,"file":"write-config.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-config.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;IACpD,gBAAgB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5C,WAAW,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,yCAAyC,EAAE,MAAM,EAAE,CAAC;CACrD,CAAC;AAEF,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO/E;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,SAAS,EAAE,mBAAmB,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhB"}
@@ -17,6 +17,7 @@ export async function writeInitConfig(opts) {
17
17
  setByDottedKey(rawConfig, "agents.approvals.require_plan", String(opts.requirePlanApproval));
18
18
  setByDottedKey(rawConfig, "agents.approvals.require_network", String(opts.requireNetworkApproval));
19
19
  setByDottedKey(rawConfig, "agents.approvals.require_verify", String(opts.requireVerifyApproval));
20
+ setByDottedKey(rawConfig, "execution", JSON.stringify(opts.execution));
20
21
  await saveConfig(opts.agentplaneDir, rawConfig);
21
22
  }
22
23
  export async function writeBackendStubs(opts) {
@@ -1,4 +1,5 @@
1
- export declare function ensureGitignoreAgents(opts: {
1
+ export declare function ensureInitGitignore(opts: {
2
2
  gitRoot: string;
3
+ includeAgentPromptFiles: boolean;
3
4
  }): Promise<void>;
4
5
  //# sourceMappingURL=write-gitignore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"write-gitignore.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-gitignore.ts"],"names":[],"mappings":"AAeA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBpF"}
1
+ {"version":3,"file":"write-gitignore.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-gitignore.ts"],"names":[],"mappings":"AAgCA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBhB"}
@@ -12,14 +12,27 @@ async function readTextIfExists(filePath) {
12
12
  throw err;
13
13
  }
14
14
  }
15
- export async function ensureGitignoreAgents(opts) {
15
+ const RUNTIME_IGNORE_LINES = [
16
+ "# agentplane: ignore runtime/transient workspace artifacts",
17
+ ".agentplane/worktrees",
18
+ ".agentplane/cache",
19
+ ".agentplane/recipes-cache",
20
+ ".agentplane/.upgrade",
21
+ ".agentplane/.release",
22
+ ".agentplane/upgrade",
23
+ ".agentplane/tasks.json",
24
+ ];
25
+ const AGENT_PROMPT_IGNORE_LINES = [
26
+ "# agentplane: ignore local agent prompts/templates",
27
+ "AGENTS.md",
28
+ ".agentplane/agents/",
29
+ ];
30
+ export async function ensureInitGitignore(opts) {
16
31
  const gitignorePath = path.join(opts.gitRoot, ".gitignore");
17
32
  const existing = (await readTextIfExists(gitignorePath)) ?? "";
18
- const ensuredLines = [
19
- "# agentplane: ignore local agent prompts/templates",
20
- "AGENTS.md",
21
- ".agentplane/agents/",
22
- ];
33
+ const ensuredLines = opts.includeAgentPromptFiles
34
+ ? [...RUNTIME_IGNORE_LINES, ...AGENT_PROMPT_IGNORE_LINES]
35
+ : [...RUNTIME_IGNORE_LINES];
23
36
  const existingLines = existing.split(/\r?\n/);
24
37
  const existingSet = new Set(existingLines.map((line) => line.trimEnd()));
25
38
  const missing = ensuredLines.filter((line) => !existingSet.has(line));
@@ -1,4 +1,5 @@
1
1
  import type { CommandHandler, CommandSpec } from "../../spec/spec.js";
2
+ type ExecutionProfile = "conservative" | "balanced" | "aggressive";
2
3
  type InitFlags = {
3
4
  ide?: "codex" | "cursor" | "windsurf";
4
5
  workflow?: "direct" | "branch_pr";
@@ -8,6 +9,8 @@ type InitFlags = {
8
9
  requirePlanApproval?: boolean;
9
10
  requireNetworkApproval?: boolean;
10
11
  requireVerifyApproval?: boolean;
12
+ executionProfile?: ExecutionProfile;
13
+ strictUnsafeConfirm?: boolean;
11
14
  recipes?: string[];
12
15
  force?: boolean;
13
16
  backup?: boolean;