-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add argument support to account commands (Phase 3 - Part 1) #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add CLI argument support for add-owner, remove-owner, change-threshold, and open commands to enable non-interactive automation: - add-owner: Add --threshold option for new threshold value - remove-owner: Add --threshold option for new threshold value - change-threshold: Add --threshold option to specify new threshold - open: Add --name option to set Safe name non-interactively These commands maintain backward compatibility with interactive mode. Also added placeholder interface for account create command (to be implemented in follow-up). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this 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 PR adds support for command-line arguments to Safe account management commands, enabling non-interactive usage. The changes introduce optional parameters for operations like creating, opening, and managing Safe accounts through CLI flags rather than interactive prompts.
- Adds options interfaces to account commands (create, open, add-owner, remove-owner, change-threshold)
- Implements conditional logic to use CLI arguments when provided or fall back to interactive prompts
- Updates CLI command definitions with corresponding option flags
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/commands/account/create.ts | Adds SafeCreateOptions interface and options parameter (marked as TODO for future implementation) |
| src/commands/account/open.ts | Adds SafeOpenOptions interface with --name flag support for naming Safes non-interactively |
| src/commands/account/add-owner.ts | Adds AddOwnerOptions interface with --threshold flag to specify threshold when adding owners |
| src/commands/account/remove-owner.ts | Adds RemoveOwnerOptions interface with --threshold flag to specify threshold when removing owners |
| src/commands/account/change-threshold.ts | Adds ChangeThresholdOptions interface with --threshold flag for non-interactive threshold changes |
| src/cli.ts | Registers CLI options and wires them to command handlers for all account management commands |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Get name | ||
| let safeName: string | ||
|
|
||
| if (options.name) { |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a name is provided via the --name option, it should be validated to ensure it's not empty. The interactive prompt validates that "Name is required" (line 155), but when passed via options, an empty string could be accepted. Consider adding validation:
if (options.name) {
if (!options.name.trim()) {
p.log.error('Name is required')
p.outro('Failed')
return
}
safeName = options.name
}| if (options.name) { | |
| if (options.name) { | |
| if (!options.name.trim()) { | |
| p.log.error('Name is required') | |
| p.outro('Failed') | |
| return | |
| } |
| if (options.threshold) { | ||
| // Use provided threshold | ||
| const num = parseInt(options.threshold, 10) | ||
| if (isNaN(num) || num < 1) { | ||
| p.log.error('Threshold must be at least 1') | ||
| p.outro('Failed') | ||
| return | ||
| } | ||
| if (num > owners.length) { | ||
| p.log.error(`Threshold cannot exceed ${owners.length} (current owners)`) | ||
| p.outro('Failed') | ||
| return | ||
| } | ||
| if (num === currentThreshold) { | ||
| p.log.error('New threshold must be different from current threshold') | ||
| p.outro('Failed') | ||
| return | ||
| } | ||
| thresholdNum = num |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The threshold validation logic (lines 80-98) is duplicated across multiple files (add-owner.ts, remove-owner.ts, and change-threshold.ts). Consider extracting this into a reusable utility function to improve maintainability and ensure consistency.
Example:
// In utils/threshold-helpers.ts
export function validateThreshold(value: string, min: number, max: number): { valid: boolean; num?: number; error?: string } {
const num = parseInt(value, 10)
if (isNaN(num) || num < min) {
return { valid: false, error: `Threshold must be at least ${min}` }
}
if (num > max) {
return { valid: false, error: `Threshold cannot exceed ${max}` }
}
return { valid: true, num }
}| if (options.threshold) { | ||
| // Use provided threshold | ||
| const num = parseInt(options.threshold, 10) | ||
| if (isNaN(num) || num < 1) { | ||
| p.log.error('Threshold must be at least 1') | ||
| p.outro('Failed') | ||
| return | ||
| } | ||
| if (num > currentOwners.length + 1) { | ||
| p.log.error(`Threshold cannot exceed ${currentOwners.length + 1} owners`) | ||
| p.outro('Failed') | ||
| return | ||
| } | ||
| thresholdNum = num |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The threshold validation logic (lines 161-174) is duplicated across multiple files (add-owner.ts, remove-owner.ts, and change-threshold.ts). Consider extracting this into a reusable utility function to improve maintainability and ensure consistency.
Example:
// In utils/threshold-helpers.ts
export function validateThreshold(value: string, min: number, max: number): { valid: boolean; num?: number; error?: string } {
const num = parseInt(value, 10)
if (isNaN(num) || num < min) {
return { valid: false, error: `Threshold must be at least ${min}` }
}
if (num > max) {
return { valid: false, error: `Threshold cannot exceed ${max}` }
}
return { valid: true, num }
}| if (options.threshold) { | ||
| // Use provided threshold | ||
| const num = parseInt(options.threshold, 10) | ||
| if (isNaN(num) || num < 1) { | ||
| p.log.error('Threshold must be at least 1') | ||
| p.outro('Failed') | ||
| return | ||
| } | ||
| if (num > maxThreshold) { | ||
| p.log.error(`Threshold cannot exceed ${maxThreshold} (remaining owners)`) | ||
| p.outro('Failed') | ||
| return | ||
| } | ||
| thresholdNum = num |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The threshold validation logic (lines 133-146) is duplicated across multiple files (add-owner.ts, remove-owner.ts, and change-threshold.ts). Consider extracting this into a reusable utility function to improve maintainability and ensure consistency.
Example:
// In utils/threshold-helpers.ts
export function validateThreshold(value: string, min: number, max: number): { valid: boolean; num?: number; error?: string } {
const num = parseInt(value, 10)
if (isNaN(num) || num < min) {
return { valid: false, error: `Threshold must be at least ${min}` }
}
if (num > max) {
return { valid: false, error: `Threshold cannot exceed ${max}` }
}
return { valid: true, num }
}Resolved conflict in src/commands/account/create.ts by keeping the full implementation over the placeholder from PR #30.
Summary
This PR implements Part 1 of Phase 3, adding argument support to account management commands for non-interactive automation scenarios.
Changes
account add-owner
--threshold <number>option to set new threshold after adding owneraccount remove-owner
--threshold <number>option to set new threshold after removing owneraccount change-threshold
--threshold <number>option to specify new threshold directlyaccount open
--name <name>option to set Safe name non-interactivelyaccount create
--chain-id,--owners,--threshold,--name,--no-deployAll commands work both interactively (when no options provided) and non-interactively (with full options).
Examples
Test plan
Related
Part of Phase 3 (Account commands) of the non-interactive CLI enhancement plan. This covers the simpler account commands. Commands like
create,deploy, andinfowill be addressed in a follow-up PR.🤖 Generated with Claude Code