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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(
name = "partiri",
version,
about = "Deploy and manage services on Partiri Cloud",
long_about = None,
)]
pub struct Cli {
/// Emit machine-readable JSON output to stdout (errors as JSON to stderr).
#[arg(long, short = 'j', global = true)]
pub json: bool,
/// Skip confirmation prompts on destructive operations.
#[arg(long, short = 'y', global = true)]
pub yes: bool,
/// Never prompt; error if a required value is missing. Auto-enabled when stdin is not a TTY.
#[arg(long = "no-input", global = true)]
pub no_input: bool,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
/// Configure your Partiri API key
Auth {
/// Set the API key directly (mutually exclusive with --key-stdin).
#[arg(long, value_name = "KEY", conflicts_with = "key_stdin")]
key: Option<String>,
/// Read the API key from stdin (single line, trimmed).
#[arg(long = "key-stdin")]
key_stdin: bool,
/// Overwrite an existing key without confirmation.
#[arg(long)]
force: bool,
},
/// Create .partiri.jsonc. Interactive wizard by default; pass --template for a non-interactive scaffold.
Init {
/// Skip the wizard and write a commented `.partiri.jsonc` template that the agent (or human) fills in by hand.
#[arg(long)]
template: bool,
},
/// Validate the local .partiri.jsonc config file
Validate {
/// Also run live API checks: UUIDs exist, region/pod pairing, repo/registry reachability,
/// and (when applicable) the health-check URL.
#[arg(long)]
remote: bool,
},
/// Service management
#[command(subcommand)]
Service(ServiceCommands),
/// Project management
#[command(subcommand)]
Projects(ProjectCommands),
/// Service discovery (list services in a project)
#[command(subcommand)]
Services(ServicesCommands),
/// Agent helpers — guide, schema, templates, capabilities, doctor, context, etc.
#[command(subcommand)]
Llm(LlmCommands),
/// Workspace management
#[command(subcommand)]
Workspaces(WorkspaceCommands),
/// Region discovery
#[command(subcommand)]
Regions(RegionCommands),
/// Compute pod discovery
#[command(subcommand)]
Pods(PodCommands),
/// Install or remove the Partiri MCP server in AI tools
#[command(subcommand)]
Mcp(McpCommands),
}
#[derive(Subcommand)]
pub enum RegionCommands {
/// List regions available in a workspace
List {
/// Workspace UUID.
#[arg(long, value_name = "UUID")]
workspace: String,
},
}
#[derive(Subcommand)]
pub enum PodCommands {
/// List compute pods available in a workspace
List {
/// Workspace UUID.
#[arg(long, value_name = "UUID")]
workspace: String,
},
}
#[derive(Subcommand)]
pub enum McpCommands {
/// Install the Partiri MCP server into an AI tool
Install {
/// Target client (claude-desktop, claude-code, cursor, vscode, copilot-cli, windsurf)
#[arg(long)]
client: Option<String>,
},
/// Remove the Partiri MCP server from an AI tool
Uninstall {
/// Target client (claude-desktop, claude-code, cursor, vscode, copilot-cli, windsurf)
#[arg(long)]
client: Option<String>,
},
}
#[derive(Subcommand)]
pub enum ServiceCommands {
/// Register the service on Partiri and update .partiri.jsonc
Create,
/// Pull an existing service and save it as .partiri.jsonc
Pull,
/// Push local config changes to the existing service
Push,
/// Show current service metrics and recent jobs
Metrics,
/// Show the last 35 log lines from the past hour
Logs,
/// List jobs for this service
Jobs,
/// Trigger a deploy job
Deploy,
/// Pause the service
Pause,
/// Resume a paused service
Unpause,
/// Kill the service (requires confirmation)
Kill,
/// Fill in workspace, project, region and pod UUIDs (interactive when no flags are passed)
Link {
/// New workspace UUID. Requires --project.
#[arg(long, value_name = "UUID")]
workspace: Option<String>,
/// New project UUID. Required when --workspace changes.
#[arg(long, value_name = "UUID")]
project: Option<String>,
/// New region UUID. Requires --pod.
#[arg(long, value_name = "UUID")]
region: Option<String>,
/// New compute pod UUID. Required when --region changes.
#[arg(long, value_name = "UUID")]
pod: Option<String>,
/// Set fk_service_secret to this token UUID.
#[arg(long, value_name = "UUID", conflicts_with = "clear_token")]
token: Option<String>,
/// Clear fk_service_secret.
#[arg(long)]
clear_token: bool,
},
/// Link an authentication token to this service (for private repositories or registries)
Token {
/// Set fk_service_secret to this token UUID.
#[arg(long, value_name = "UUID", conflicts_with = "clear")]
secret: Option<String>,
/// Clear fk_service_secret on this service.
#[arg(long)]
clear: bool,
},
}
#[derive(Subcommand)]
pub enum ProjectCommands {
/// List all projects in a workspace
List {
/// Workspace UUID to list projects for. Required when you belong to more than one workspace.
#[arg(long, value_name = "UUID")]
workspace: Option<String>,
},
/// Create a new project in a workspace
Create {
/// Workspace UUID. Required when you belong to more than one workspace.
#[arg(long, value_name = "UUID")]
workspace: Option<String>,
/// Project name.
#[arg(long, value_name = "NAME")]
name: Option<String>,
/// Environment (`dev`, `staging`, or `prod`).
#[arg(long, value_name = "ENV")]
environment: Option<String>,
},
}
#[derive(Subcommand)]
pub enum WorkspaceCommands {
/// List all workspaces
List,
}
#[derive(Subcommand)]
pub enum ServicesCommands {
/// List services in a project
List {
/// Project UUID.
#[arg(long, value_name = "UUID")]
project: String,
},
}
#[derive(Subcommand)]
pub enum LlmCommands {
/// Print the embedded agent guide (LLM.md).
Guide,
/// JSON schema of .partiri.jsonc.
Schema,
/// Print a pre-filled .partiri.jsonc template (does not write to disk).
Template {
/// `webservice` (default), `static`, or `private-service`.
#[arg(long)]
deploy_type: Option<String>,
/// `node` (default), `rust`, `python`, `go`, `ruby`, `elixir`, `php`, `jvm`, `dotnet`, `cpp`, `static`, `registry`.
#[arg(long)]
runtime: Option<String>,
/// `repo` (default) or `registry`.
#[arg(long)]
source: Option<String>,
},
/// Print worked examples for common deployment shapes.
Examples,
/// Emit the entire CLI tree as JSON.
Capabilities,
/// Catalog of every error code the CLI emits.
Errors,
/// Deep help for one command (e.g. `partiri llm explain validate`).
Explain {
/// The command path. Multi-word values like "service deploy" must be quoted.
command: String,
},
/// Auth state and identity (single API call to /workspaces).
Whoami,
/// Environment-level diagnostic.
Doctor,
/// Full nested workspace tree in one call.
Context {
/// Limit to one workspace (cheaper).
#[arg(long, value_name = "UUID")]
workspace: Option<String>,
},
/// Suggest the next command for the current `.partiri.jsonc` state.
Next,
}