Skip to content

Conversation

@katspaugh
Copy link
Member

Summary

This PR implements Part 2 of Phase 3, adding argument support and JSON output mode to the account deploy and account info commands for full automation support.

Changes

account deploy

  • Add --skip-confirmation option to bypass deployment confirmation prompt
  • Integrate password-handler for secure password input
    • Supports --password CLI flag
    • Supports --password-file for file-based passwords
    • Supports SAFE_WALLET_PASSWORD environment variable
  • Add JSON output mode with --json flag
  • Update error handling to use standardized exit codes
  • Support non-interactive deployment workflows

account info

  • Add JSON output mode with --json flag
  • Fetch and output comprehensive Safe information:
    • Basic details: name, address, EIP-3770 format, chain, deployment status
    • On-chain data: version, nonce, balance, owners, threshold
    • Advanced config: modules, guard, fallback handler, master copy
  • Maintain backward compatibility with interactive Ink rendering
  • Works with any Safe address (doesn't need to be in storage)

Both commands work seamlessly in interactive and non-interactive modes.

Examples

# Deploy Safe non-interactively with password file
safe account deploy eth:0x123... --skip-confirmation --password-file ./pw.txt --json

# Get Safe info in JSON format
safe account info eth:0x123... --json

# Full automation workflow
export SAFE_WALLET_PASSWORD="my-secure-password"
safe account deploy eth:0x123... --skip-confirmation --json
safe account info eth:0x123... --json

Test plan

  • Build passes
  • Type check passes
  • Lint passes
  • Manual testing of deploy command with and without options
  • Manual testing of info command in JSON mode
  • Test password input via CLI, file, and env var
  • Verify error handling with invalid arguments
  • Verify backward compatibility with interactive mode

Related

Part of Phase 3 (Account commands) of the non-interactive CLI enhancement plan. This completes the simpler deployment and info commands. The complex account create command will be addressed separately.

Related PRs:

🤖 Generated with Claude Code

Add CLI argument support and JSON output mode for deploy and info commands:

**account deploy**
- Add `--skip-confirmation` option to bypass deployment confirmation prompt
- Integrate password-handler for secure password input (supports --password, --password-file, env var)
- Add JSON output mode with `--json` flag
- Update error handling to use standardized exit codes

**account info**
- Add JSON output mode with `--json` flag
- Fetch and output Safe information including:
  - Basic details (name, address, chain, deployment status)
  - On-chain data (version, nonce, balance, owners, threshold)
  - Advanced config (modules, guard, fallback handler, master copy)
- Maintain backward compatibility with interactive Ink rendering

Both commands work seamlessly in interactive and non-interactive modes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings November 7, 2025 15:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request adds support for non-interactive/JSON output mode to the account info and account deploy commands, enabling better automation and CI/CD integration. The changes replace interactive UI elements with structured JSON output when in non-interactive mode.

Key changes:

  • Added JSON mode support to account info and account deploy commands with structured error handling
  • Replaced logError + p.cancel error handling with outputError that uses appropriate exit codes
  • Integrated password handling via environment variables/files for non-interactive deployments
  • Added --skip-confirmation flag to account deploy command

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/commands/account/info.ts Added JSON mode support for retrieving Safe info and standardized error handling with exit codes
src/commands/account/deploy.ts Added JSON mode support, password handler integration, and skip-confirmation option for automated deployments
src/cli.ts Added --skip-confirmation option to the deploy command definition

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 80 to 82
if (!safe.predictedConfig) {
logError('Safe does not have deployment configuration')
return
outputError('Safe does not have deployment configuration', ExitCode.ERROR)
}
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After outputError is called on line 81, the function exits via process.exit(), but TypeScript doesn't know this is a never return. On lines 124, 168-170, safe.predictedConfig is accessed without null checking, which could cause a type error. Add a return type annotation or explicit return/throw after the check to help TypeScript understand the control flow.

Copilot uses AI. Check for mistakes.
Comment on lines 76 to 78
if (!safe) {
logError(`Safe not found: ${address} on chain ${chainId}`)
p.cancel('Operation cancelled')
return
outputError(`Safe not found: ${address} on chain ${chainId}`, ExitCode.SAFE_NOT_FOUND)
}
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After outputError is called on line 77, the function exits, but TypeScript doesn't recognize this. Subsequent code accesses safe (lines 80, 85, 94-95, 101-102, 115, 120-124, 168-170, 176) without null checking, which could cause type errors. Add an explicit return type annotation or assertion to help TypeScript understand the control flow.

Copilot uses AI. Check for mistakes.
logError('No active wallet found. Please import a wallet first.')
p.cancel('Use "safe wallet import" to import a wallet')
return
outputError('No active wallet found. Please import a wallet first.', ExitCode.WALLET_ERROR)
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After outputError is called on line 112, the function exits, but TypeScript doesn't know this is a never return. On lines 127 and 163, activeWallet is accessed without null checking, which could cause type errors. Add an explicit return type annotation or assertion to help TypeScript understand the control flow.

Suggested change
outputError('No active wallet found. Please import a wallet first.', ExitCode.WALLET_ERROR)
outputError('No active wallet found. Please import a wallet first.', ExitCode.WALLET_ERROR)
return

Copilot uses AI. Check for mistakes.
Comment on lines 80 to 82
if (!chain) {
logError(`Chain not found: ${chainId}`)
p.cancel(
'Operation cancelled. Use "safe config chains" to add this chain or "safe config init" to load default chains'
)
return
outputError(`Chain not found: ${chainId}`, ExitCode.CONFIG_ERROR)
}
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After outputError is called on line 81, the function exits, but TypeScript doesn't recognize this. On lines 87, 91, and 98, chain is accessed without null checking, which could cause type errors. Add an explicit return type annotation or assertion to help TypeScript understand the control flow.

Copilot uses AI. Check for mistakes.
@katspaugh katspaugh merged commit d1c427d into main Nov 7, 2025
10 checks passed
@katspaugh katspaugh deleted the feat/account-arguments-part2 branch November 7, 2025 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants