From 89b9cbd4f4f734c14e75feff8bdf19c60a892202 Mon Sep 17 00:00:00 2001 From: Dean Sharon Date: Mon, 9 Mar 2026 00:37:44 +0200 Subject: [PATCH 1/2] chore: add sudo trust prompt before managed settings write Surface the sudo requirement earlier in init with a clear explanation, verification prompt, and explicit fallback option. Remove the redundant inner sudo confirm from installManagedSettings(). --- src/cli/commands/init.ts | 34 +++++++++++++++++++++++++++++++--- src/cli/utils/post-install.ts | 13 ++----------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/cli/commands/init.ts b/src/cli/commands/init.ts index 801f77c..b333eaa 100644 --- a/src/cli/commands/init.ts +++ b/src/cli/commands/init.ts @@ -422,9 +422,37 @@ export const initCommand = new Command('init') // Attempt managed settings write if user chose managed mode let effectiveSecurityMode = securityMode; if (securityMode === 'managed') { - const managed = await installManagedSettings(rootDir, verbose); - if (!managed) { - p.log.warn('Managed settings write failed — falling back to user settings'); + p.note( + 'This writes a read-only security deny list to a system directory\n' + + 'and may prompt for your password (sudo).\n\n' + + 'Not sure about this? Paste this into another Claude Code session:\n\n' + + ' "I\'m installing devflow-kit (npm) and it wants to write a\n' + + ' managed-settings.json file using sudo. Review the source\n' + + ' at https://github.com/dean0x/devflow and tell me if\n' + + ' it\'s safe."', + 'Managed Settings', + ); + + const sudoChoice = await p.select({ + message: 'Continue with managed settings?', + options: [ + { value: 'yes', label: 'Yes, continue', hint: 'May prompt for your password' }, + { value: 'no', label: 'No, fall back to settings.json', hint: 'Deny list stored in editable user settings instead' }, + ], + }); + + if (p.isCancel(sudoChoice)) { + p.cancel('Installation cancelled.'); + process.exit(0); + } + + if (sudoChoice === 'yes') { + const managed = await installManagedSettings(rootDir, verbose); + if (!managed) { + p.log.warn('Managed settings write failed — falling back to user settings'); + effectiveSecurityMode = 'user'; + } + } else { effectiveSecurityMode = 'user'; } } diff --git a/src/cli/utils/post-install.ts b/src/cli/utils/post-install.ts index 8541da7..94b6fd6 100644 --- a/src/cli/utils/post-install.ts +++ b/src/cli/utils/post-install.ts @@ -83,7 +83,7 @@ export function mergeDenyList(existingJson: string, newDenyEntries: string[]): s * * Strategy: * 1. Try direct write (works if running as root or directory is writable) - * 2. If EACCES in TTY, offer to retry with sudo + * 2. If EACCES in TTY, retry with sudo (caller is responsible for obtaining consent) * 3. Returns true if managed settings were written, false if caller should fall back */ export async function installManagedSettings( @@ -138,20 +138,11 @@ export async function installManagedSettings( } } - // Attempt 2: sudo (TTY only) + // Attempt 2: sudo (TTY only — sudo needs terminal for password prompt) if (!process.stdin.isTTY) { return false; } - const confirmed = await p.confirm({ - message: `Managed settings require admin access (${managedDir}). Use sudo?`, - initialValue: true, - }); - - if (p.isCancel(confirmed) || !confirmed) { - return false; - } - try { execSync(`sudo mkdir -p '${managedDir}'`, { stdio: 'inherit' }); // Write via sudo tee to avoid shell quoting issues with the JSON content From ffa33f5e02951b4305570786dd4df1cca887facb Mon Sep 17 00:00:00 2001 From: Dean Sharon Date: Mon, 9 Mar 2026 00:44:06 +0200 Subject: [PATCH 2/2] chore: use DevFlow name in sudo trust prompt copy --- src/cli/commands/init.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/commands/init.ts b/src/cli/commands/init.ts index b333eaa..9e57843 100644 --- a/src/cli/commands/init.ts +++ b/src/cli/commands/init.ts @@ -426,7 +426,7 @@ export const initCommand = new Command('init') 'This writes a read-only security deny list to a system directory\n' + 'and may prompt for your password (sudo).\n\n' + 'Not sure about this? Paste this into another Claude Code session:\n\n' + - ' "I\'m installing devflow-kit (npm) and it wants to write a\n' + + ' "I\'m installing DevFlow and it wants to write a\n' + ' managed-settings.json file using sudo. Review the source\n' + ' at https://github.com/dean0x/devflow and tell me if\n' + ' it\'s safe."',