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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use std::path::PathBuf;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(
name = "nex",
about = "Package manager for nix-darwin, NixOS, and homebrew"
)]
#[command(version)]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
/// Path to the nix-darwin repo (overrides auto-discovery)
#[arg(long, global = true, env = "NEX_REPO")]
pub repo: Option<PathBuf>,
/// Hostname for system rebuild (overrides auto-detect)
#[arg(long, global = true, env = "NEX_HOSTNAME")]
pub hostname: Option<String>,
/// Show what would change without editing or switching
#[arg(long, global = true)]
pub dry_run: bool,
}
#[derive(Subcommand)]
pub enum Command {
/// Set up nix-darwin + homebrew (macOS) or NixOS (Linux) on this machine
Init {
/// Clone an existing nix-darwin repo instead of scaffolding
#[arg(long)]
from: Option<String>,
},
/// Capture all installed brew packages into the nex config
Adopt,
/// Install packages
Install {
/// Force install as a Nix package (skip auto-resolution)
#[arg(long)]
nix: bool,
/// Install as a Homebrew cask (GUI app)
#[arg(long)]
cask: bool,
/// Install as a Homebrew formula
#[arg(long)]
brew: bool,
/// Package names
packages: Vec<String>,
},
/// Remove packages
Remove {
/// Remove a Homebrew cask
#[arg(long)]
cask: bool,
/// Remove a Homebrew formula
#[arg(long)]
brew: bool,
/// Package names
packages: Vec<String>,
},
/// Search nixpkgs for a package
Search {
/// Search query
query: String,
},
/// List all declared packages
List,
/// Update flake inputs and switch
Update,
/// Rebuild and activate
Switch,
/// Rollback to previous generation
Rollback,
/// Try a package in an ephemeral nix shell
Try {
/// Package to try
package: String,
},
/// Identify brew packages that can migrate to nix
Migrate,
/// Apply a profile from a GitHub repo
Profile {
/// GitHub repo (user/repo) or URL
#[arg(value_name = "SOURCE")]
source: String,
},
/// Build a bootable NixOS installer USB, optionally with a baked-in profile
Forge {
/// Nex profile (GitHub user/repo) to bake in. Omit for generic styx installer.
#[arg(value_name = "PROFILE")]
profile: Option<String>,
/// Hostname default for the target system (user can override at install time)
#[arg(long)]
hostname: Option<String>,
/// Target USB device to flash (e.g. /dev/sdb, /dev/disk4). If omitted, builds bundle only.
#[arg(long)]
disk: Option<String>,
/// Output directory for the bundle (default: /tmp/nex-forge)
#[arg(long, short)]
output: Option<PathBuf>,
},
/// Interactive NixOS installer (runs on target machine after booting from USB)
Polymerize {
/// Path to the bundled defaults (written by nex forge). Auto-detected from USB.
#[arg(long)]
bundle: Option<PathBuf>,
},
/// Build an OCI container image from a profile
BuildImage {
/// Nex profile (GitHub user/repo) or local path to profile.toml
#[arg(value_name = "PROFILE")]
profile: String,
/// Image name (default: derived from profile name)
#[arg(long)]
name: Option<String>,
/// Image tag (default: "latest")
#[arg(long, default_value = "latest")]
tag: String,
},
/// Enter a dev shell from a flake (wraps nix develop)
Develop {
/// Flake reference (e.g. github:styrene-lab/nex, ., ./path/to/flake)
#[arg(value_name = "FLAKE")]
flake: String,
},
/// Open a project with omegon AI coding agent (requires omegon)
Dev {
/// Project flake reference or bare name (e.g. styrene-lab/nex, omegon, .)
#[arg(value_name = "PROJECT")]
project: String,
},
/// Check and fix common configuration issues
Doctor,
/// Update nex itself to the latest release
SelfUpdate,
/// Preview what would change
Diff,
/// Garbage collect nix store
Gc,
}