diff --git a/docs/user/setup.mdx b/docs/user/setup.mdx index 575e0319..cea555a9 100644 --- a/docs/user/setup.mdx +++ b/docs/user/setup.mdx @@ -41,9 +41,11 @@ If `.git` does not exist in that folder, `init` creates a new git repository the `agentplane init` now starts with a setup profile: - `prod` (default): compact flow with essential prompts only (typically setup profile + backend). +- `prod-strict`: compact flow with stricter defaults (hooks on, strict unsafe confirmations). - `dev`: full questionnaire (workflow, hooks, approvals, execution profile, recipes). +- `dev-safe`: full questionnaire with stricter unsafe-action confirmations by default. -Use `--setup-profile dev` to force full prompts. +Use `--setup-profile dev` (or `dev-safe`) to force full prompts. Non-interactive setup is available through flags: diff --git a/packages/agentplane/src/cli/run-cli.core.init-upgrade-backend.test.ts b/packages/agentplane/src/cli/run-cli.core.init-upgrade-backend.test.ts index 41f3e19f..7d643ee9 100644 --- a/packages/agentplane/src/cli/run-cli.core.init-upgrade-backend.test.ts +++ b/packages/agentplane/src/cli/run-cli.core.init-upgrade-backend.test.ts @@ -898,6 +898,18 @@ describe("runCli", () => { } }); + it("init accepts setup-profile strict variants", async () => { + const root1 = await mkGitRepoRoot(); + await configureGitUser(root1); + let code = await runCli(["init", "--yes", "--setup-profile", "prod-strict", "--root", root1]); + expect(code).toBe(0); + + const root2 = await mkGitRepoRoot(); + await configureGitUser(root2); + code = await runCli(["init", "--yes", "--setup-profile", "dev-safe", "--root", root2]); + expect(code).toBe(0); + }); + it("init rejects invalid --workflow values", async () => { const root = await mkGitRepoRoot(); const io = captureStdIO(); diff --git a/packages/agentplane/src/cli/run-cli/commands/init.ts b/packages/agentplane/src/cli/run-cli/commands/init.ts index a48c1bff..ec4caf87 100644 --- a/packages/agentplane/src/cli/run-cli/commands/init.ts +++ b/packages/agentplane/src/cli/run-cli/commands/init.ts @@ -31,7 +31,7 @@ import { ensureInitRedmineEnvTemplate } from "./init/write-env.js"; import { renderInitSection, renderInitWelcome } from "./init/ui.js"; type InitFlags = { - setupProfile?: "prod" | "dev"; + setupProfile?: SetupProfilePreset; ide?: "codex" | "cursor" | "windsurf"; workflow?: "direct" | "branch_pr"; backend?: "local" | "redmine"; @@ -119,10 +119,10 @@ export const initSpec: CommandSpec = { { kind: "string", name: "setup-profile", - valueHint: "", - choices: ["prod", "dev"], + valueHint: "", + choices: ["prod", "prod-strict", "dev", "dev-safe"], description: - "Interactive preset. prod is the default and asks only essential questions; dev asks the full setup questionnaire.", + "Interactive preset. prod is default; prod-strict enables stricter defaults, dev asks the full questionnaire, and dev-safe adds stricter unsafe-action confirmations.", }, { kind: "string", @@ -334,7 +334,7 @@ async function cmdInit(opts: { let requireVerifyApproval = flags.requireVerifyApproval ?? defaults.requireVerifyApproval; let executionProfile = flags.executionProfile ?? defaults.executionProfile; let strictUnsafeConfirm = flags.strictUnsafeConfirm ?? defaults.strictUnsafeConfirm; - let setupProfile: "prod" | "dev" = flags.setupProfile ?? "prod"; + let setupProfile: "prod" | "dev" = setupProfilePresets[flags.setupProfile ?? "prod"].mode; let setupProfilePreset: SetupProfilePreset = flags.setupProfile ?? "prod"; const isInteractive = process.stdin.isTTY && !flags.yes;