1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::path::PathBuf;
#[derive(clap::Args, Debug)]
pub struct PromptArgs {
/// Inline prompt text to store in the new worktree
#[arg(short = 'p', long, conflicts_with_all = ["prompt_file", "prompt_editor"])]
pub prompt: Option<String>,
/// Path to a file whose contents should be used as the prompt
#[arg(
short = 'P',
long = "prompt-file",
conflicts_with_all = ["prompt", "prompt_editor"],
value_hint = clap::ValueHint::FilePath
)]
pub prompt_file: Option<PathBuf>,
/// Open $EDITOR to write the prompt
#[arg(short = 'e', long = "prompt-editor", conflicts_with_all = ["prompt", "prompt_file"])]
pub prompt_editor: bool,
/// Write the prompt file without injecting it into agent commands.
/// The prompt is written to .workmux/PROMPT-<branch>.md in the worktree,
/// but no agent pane is required. Useful when your editor has an embedded
/// agent that reads the prompt file directly.
#[arg(long)]
pub prompt_file_only: bool,
}
impl PromptArgs {
pub fn has_any(&self) -> bool {
self.prompt.is_some() || self.prompt_file.is_some() || self.prompt_editor
}
}
#[derive(clap::Args, Debug)]
pub struct SetupFlags {
/// Skip running post-create hooks
#[arg(short = 'H', long)]
pub no_hooks: bool,
/// Skip file copy/symlink operations
#[arg(short = 'F', long)]
pub no_file_ops: bool,
/// Skip executing pane commands (panes open with plain shells)
#[arg(short = 'C', long)]
pub no_pane_cmds: bool,
/// Create tmux window in the background (do not switch to it)
#[arg(short = 'b', long = "background")]
pub background: bool,
/// Open existing worktree if it exists instead of failing (like tmux new -A)
#[arg(short = 'o', long, conflicts_with = "with_changes")]
pub open_if_exists: bool,
/// Enable sandbox mode even when disabled in config
#[arg(short = 'S', long)]
pub sandbox: bool,
}
#[derive(clap::Args, Debug)]
pub struct MultiArgs {
/// The agent(s) to use. Creates one worktree per agent if -n is not specified.
#[arg(short = 'a', long)]
pub agent: Vec<String>,
/// Number of worktree instances to create.
/// Can be used with zero or one --agent. Incompatible with --foreach.
#[arg(
short = 'n',
long,
value_parser = clap::value_parser!(u32).range(1..),
conflicts_with = "foreach"
)]
pub count: Option<u32>,
/// Generate multiple worktrees from a variable matrix.
/// Format: "var1:valA,valB;var2:valX,valY". Lists must have equal length.
/// Incompatible with --agent and --count.
#[arg(long, conflicts_with_all = ["agent", "count"])]
pub foreach: Option<String>,
/// Template for branch names in multi-worktree modes.
/// Variables: {{ base_name }}, {{ agent }}, {{ num }}, {{ foreach_vars }}.
#[arg(
long,
default_value = r#"{{ base_name }}{% if agent %}-{{ agent | slugify }}{% endif %}{% for key in foreach_vars %}-{{ foreach_vars[key] | slugify }}{% endfor %}{% if num %}-{{ num }}{% endif %}"#
)]
pub branch_template: String,
/// Maximum number of worktrees to run concurrently.
/// When set, waits for a slot to open before creating new worktrees.
#[arg(long, value_parser = clap::value_parser!(u32).range(1..))]
pub max_concurrent: Option<u32>,
}
#[derive(clap::Args, Debug)]
pub struct RescueArgs {
/// Move uncommitted changes from the current worktree to the new worktree
#[arg(short = 'w', long, conflicts_with_all = ["count", "foreach"])]
pub with_changes: bool,
/// Interactively select which changes to move (only applies with --with-changes)
#[arg(long, requires = "with_changes")]
pub patch: bool,
/// Also move untracked files (only applies with --with-changes)
#[arg(short = 'u', long, requires = "with_changes")]
pub include_untracked: bool,
}