@bli-cockpit/cli 0.2.54 → 0.2.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/attribution-core-fallbacks.js +247 -0
- package/dist/adapters/attribution-core-paths.js +182 -0
- package/dist/adapters/attribution-core-score.js +159 -0
- package/dist/adapters/attribution-core-types.js +13 -0
- package/dist/adapters/attribution-core.js +13 -565
- package/dist/adapters/claude-attribution-discovery.js +186 -0
- package/dist/adapters/claude-attribution-score.js +204 -0
- package/dist/adapters/claude-attribution-signals.js +180 -0
- package/dist/adapters/claude-attribution-types.js +25 -0
- package/dist/adapters/claude-attribution.js +14 -569
- package/dist/commands/doctor-access.js +129 -0
- package/dist/commands/doctor-pipeline.js +326 -0
- package/dist/commands/doctor-registration.js +105 -0
- package/dist/commands/doctor-report.js +111 -0
- package/dist/commands/doctor-update.js +120 -0
- package/dist/commands/doctor.js +8 -753
- package/dist/commands/heartbeat.js +8 -0
- package/dist/commands/jarvis-contracts.js +8 -0
- package/dist/commands/jarvis-render.js +413 -0
- package/dist/commands/jarvis-turn.js +305 -0
- package/dist/commands/jarvis.js +23 -698
- package/dist/commands/local-args-collector-setup.js +250 -0
- package/dist/commands/local-args-collector-status.js +227 -0
- package/dist/commands/local-args-collector-work.js +175 -0
- package/dist/commands/local-args-collector.js +19 -624
- package/dist/commands/local-args-tower-admin.js +456 -0
- package/dist/commands/local-args-tower-chat.js +194 -0
- package/dist/commands/local-args-tower-pages.js +314 -0
- package/dist/commands/local-args-tower.js +13 -880
- package/dist/commands/local-help.js +10 -2
- package/dist/commands/onboard-completion.js +136 -0
- package/dist/commands/onboard-flows.js +165 -0
- package/dist/commands/onboard-setup.js +102 -0
- package/dist/commands/onboard.js +5 -392
- package/dist/commands/public-root.js +1 -1
- package/dist/commands/session-sync-counters.js +55 -0
- package/dist/commands/session-sync-health.js +8 -1
- package/dist/commands/session-sync-plan.js +47 -7
- package/dist/commands/session-sync-scan.js +4 -4
- package/dist/commands/session-sync.js +6 -0
- package/dist/commands/settings-render.js +27 -0
- package/dist/commands/sync-followups.js +5 -1
- package/dist/commands/sync.js +5 -1
- package/dist/commands/team-device-reasons.js +16 -0
- package/dist/commands/team.js +87 -7
- package/dist/evidence-upload-client.js +14 -763
- package/dist/evidence-upload-object.js +181 -0
- package/dist/evidence-upload-plan.js +233 -0
- package/dist/evidence-upload-terminal.js +309 -0
- package/dist/evidence-upload-transport.js +104 -0
- package/dist/spool/local-spool-io.js +122 -0
- package/dist/spool/local-spool-mutations.js +174 -0
- package/dist/spool/local-spool-parse.js +143 -0
- package/dist/spool/local-spool-types.js +22 -0
- package/dist/spool/local-spool.js +20 -426
- package/dist/upload-evidence-delivery-offer.js +144 -0
- package/dist/upload-evidence-delivery-reconcile.js +134 -0
- package/dist/upload-evidence-delivery-summary.js +205 -0
- package/dist/upload-evidence-delivery.js +12 -482
- package/package.json +3 -3
|
@@ -6,629 +6,24 @@
|
|
|
6
6
|
* maintainer's `release`.
|
|
7
7
|
*
|
|
8
8
|
* Split out of commands/local-args.ts (BLI-3578) alongside its sibling
|
|
9
|
-
* local-args-tower.ts, which parses the commands that talk to Tower.
|
|
10
|
-
*
|
|
11
|
-
* same
|
|
9
|
+
* local-args-tower.ts, which parses the commands that talk to Tower. This file
|
|
10
|
+
* itself became a table of contents in BLI-3636, split by COMMAND FAMILY into
|
|
11
|
+
* three siblings, each moved verbatim (same allowed flags, same value flags,
|
|
12
|
+
* same defaults, same refusal sentences):
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"--home",
|
|
26
|
-
"--repo",
|
|
27
|
-
"--workspace",
|
|
28
|
-
"--dashboard-url",
|
|
29
|
-
"--email",
|
|
30
|
-
"--device-name",
|
|
31
|
-
"--ticket",
|
|
32
|
-
"--branch",
|
|
33
|
-
"--json",
|
|
34
|
-
"--no-auth",
|
|
35
|
-
"--poll-interval-ms",
|
|
36
|
-
"--timeout-ms",
|
|
37
|
-
"--max-depth",
|
|
38
|
-
"--max-repos",
|
|
39
|
-
"--allow-home-root",
|
|
40
|
-
],
|
|
41
|
-
valueFlags: [
|
|
42
|
-
"--home",
|
|
43
|
-
"--repo",
|
|
44
|
-
"--workspace",
|
|
45
|
-
"--dashboard-url",
|
|
46
|
-
"--email",
|
|
47
|
-
"--device-name",
|
|
48
|
-
"--ticket",
|
|
49
|
-
"--branch",
|
|
50
|
-
"--poll-interval-ms",
|
|
51
|
-
"--timeout-ms",
|
|
52
|
-
"--max-depth",
|
|
53
|
-
"--max-repos",
|
|
54
|
-
],
|
|
55
|
-
});
|
|
56
|
-
assertNoPositionals(values.positionals, command);
|
|
57
|
-
return {
|
|
58
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
59
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
60
|
-
collectionRoots: optionalNonEmptyList(workRootFlagValues(values)),
|
|
61
|
-
dashboardUrl: normalizeUrl(values.flags.get("--dashboard-url") ?? DEFAULT_DASHBOARD_URL),
|
|
62
|
-
dashboardUrlExplicit: values.flags.has("--dashboard-url"),
|
|
63
|
-
claimedOwnerEmail: optionalEmail(values.flags.get("--email")),
|
|
64
|
-
deviceName: optionalNonEmpty(values.flags.get("--device-name")),
|
|
65
|
-
activeTicketId: optionalNonEmpty(values.flags.get("--ticket")),
|
|
66
|
-
branch: optionalNonEmpty(values.flags.get("--branch")),
|
|
67
|
-
noAuth: values.booleans.has("--no-auth"),
|
|
68
|
-
json: values.booleans.has("--json"),
|
|
69
|
-
pollIntervalMs: optionalPositiveInteger(values.flags.get("--poll-interval-ms"), "--poll-interval-ms"),
|
|
70
|
-
timeoutMs: optionalPositiveInteger(values.flags.get("--timeout-ms"), "--timeout-ms"),
|
|
71
|
-
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
72
|
-
maxRepos: optionalPositiveInteger(values.flags.get("--max-repos"), "--max-repos"),
|
|
73
|
-
allowHomeRoot: values.booleans.has("--allow-home-root"),
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
export function parseOnboardArgs(args) {
|
|
77
|
-
return { kind: "onboard", ...parseOnboardLikeArgs(args, "onboard") };
|
|
78
|
-
}
|
|
79
|
-
export function parseUpdateArgs(alias, args) {
|
|
80
|
-
return {
|
|
81
|
-
kind: "update",
|
|
82
|
-
alias,
|
|
83
|
-
...parseOnboardLikeArgs(args, alias),
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
export function parseDoctorArgs(alias, args) {
|
|
87
|
-
// The allowed set is the UNION of what the six setup doors used to accept.
|
|
88
|
-
// An alias that silently rejected a flag its own docs told people to pass
|
|
89
|
-
// would be a worse dead end than the one we are removing.
|
|
90
|
-
const values = parseNamedArgs(args, {
|
|
91
|
-
allowedFlags: [
|
|
92
|
-
"--home",
|
|
93
|
-
"--repo",
|
|
94
|
-
"--workspace",
|
|
95
|
-
"--dashboard-url",
|
|
96
|
-
"--update-tag",
|
|
97
|
-
"--dry-run",
|
|
98
|
-
"--json",
|
|
99
|
-
"--allow-home-root",
|
|
100
|
-
"--max-depth",
|
|
101
|
-
"--max-repos",
|
|
102
|
-
// Accepted and ignored: the convergence run works these out itself.
|
|
103
|
-
// Rejecting them would break existing DMs and runbooks for no gain.
|
|
104
|
-
"--email",
|
|
105
|
-
"--device-name",
|
|
106
|
-
"--ticket",
|
|
107
|
-
"--branch",
|
|
108
|
-
"--no-auth",
|
|
109
|
-
"--poll-interval-ms",
|
|
110
|
-
"--timeout-ms",
|
|
111
|
-
],
|
|
112
|
-
valueFlags: [
|
|
113
|
-
"--home",
|
|
114
|
-
"--repo",
|
|
115
|
-
"--workspace",
|
|
116
|
-
"--dashboard-url",
|
|
117
|
-
"--update-tag",
|
|
118
|
-
"--max-depth",
|
|
119
|
-
"--max-repos",
|
|
120
|
-
"--email",
|
|
121
|
-
"--device-name",
|
|
122
|
-
"--ticket",
|
|
123
|
-
"--branch",
|
|
124
|
-
"--poll-interval-ms",
|
|
125
|
-
"--timeout-ms",
|
|
126
|
-
],
|
|
127
|
-
});
|
|
128
|
-
assertNoPositionals(values.positionals, alias);
|
|
129
|
-
const updateTag = optionalNonEmpty(values.flags.get("--update-tag"));
|
|
130
|
-
if (updateTag && !/^[a-z0-9][a-z0-9._-]*$/u.test(updateTag)) {
|
|
131
|
-
throw new Error("--update-tag must be a lowercase npm dist-tag such as 'next' or 'latest'.");
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
kind: "doctor",
|
|
135
|
-
alias,
|
|
136
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
137
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
138
|
-
collectionRoots: optionalNonEmptyList(workRootFlagValues(values)),
|
|
139
|
-
dashboardUrl: normalizeUrl(values.flags.get("--dashboard-url") ?? DEFAULT_DASHBOARD_URL),
|
|
140
|
-
updateTag,
|
|
141
|
-
dryRun: values.booleans.has("--dry-run"),
|
|
142
|
-
json: values.booleans.has("--json"),
|
|
143
|
-
allowHomeRoot: values.booleans.has("--allow-home-root"),
|
|
144
|
-
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
145
|
-
maxRepos: optionalPositiveInteger(values.flags.get("--max-repos"), "--max-repos"),
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
export function parseInstallArgs(args) {
|
|
149
|
-
const values = parseNamedArgs(args, {
|
|
150
|
-
allowedFlags: [
|
|
151
|
-
"--home",
|
|
152
|
-
"--repo",
|
|
153
|
-
"--workspace",
|
|
154
|
-
"--dashboard-url",
|
|
155
|
-
"--supabase-url",
|
|
156
|
-
"--json",
|
|
157
|
-
"--allow-home-root",
|
|
158
|
-
],
|
|
159
|
-
valueFlags: [
|
|
160
|
-
"--home",
|
|
161
|
-
"--repo",
|
|
162
|
-
"--workspace",
|
|
163
|
-
"--dashboard-url",
|
|
164
|
-
"--supabase-url",
|
|
165
|
-
],
|
|
166
|
-
});
|
|
167
|
-
assertNoPositionals(values.positionals, "install");
|
|
168
|
-
return {
|
|
169
|
-
kind: "install",
|
|
170
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
171
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
172
|
-
dashboardUrl: normalizeUrl(values.flags.get("--dashboard-url") ?? DEFAULT_DASHBOARD_URL),
|
|
173
|
-
supabaseUrl: optionalNonEmpty(values.flags.get("--supabase-url")),
|
|
174
|
-
json: values.booleans.has("--json"),
|
|
175
|
-
allowHomeRoot: values.booleans.has("--allow-home-root"),
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
export function parseReleaseArgs(args) {
|
|
179
|
-
const values = parseNamedArgs(args, {
|
|
180
|
-
allowedFlags: [
|
|
181
|
-
"--dry-run",
|
|
182
|
-
"--tag",
|
|
183
|
-
"--access",
|
|
184
|
-
"--otp",
|
|
185
|
-
"--skip-checks",
|
|
186
|
-
// BLI-3557: publish without raising the fleet forced-update floor. The
|
|
187
|
-
// maintainer path must be able to say that, or the staged rollout only
|
|
188
|
-
// exists for whoever runs the npm script directly.
|
|
189
|
-
"--no-floor",
|
|
190
|
-
],
|
|
191
|
-
valueFlags: ["--tag", "--access", "--otp"],
|
|
192
|
-
});
|
|
193
|
-
assertNoPositionals(values.positionals, "release");
|
|
194
|
-
const releaseArgs = [];
|
|
195
|
-
if (values.booleans.has("--dry-run"))
|
|
196
|
-
releaseArgs.push("--dry-run");
|
|
197
|
-
if (values.booleans.has("--skip-checks"))
|
|
198
|
-
releaseArgs.push("--skip-checks");
|
|
199
|
-
if (values.booleans.has("--no-floor"))
|
|
200
|
-
releaseArgs.push("--no-floor");
|
|
201
|
-
for (const flag of ["--tag", "--access", "--otp"]) {
|
|
202
|
-
const value = values.flags.get(flag);
|
|
203
|
-
if (value !== undefined)
|
|
204
|
-
releaseArgs.push(flag, value);
|
|
205
|
-
}
|
|
206
|
-
return { kind: "release", args: releaseArgs };
|
|
207
|
-
}
|
|
208
|
-
export function parseLoginArgs(args) {
|
|
209
|
-
const values = parseNamedArgs(args, {
|
|
210
|
-
allowedFlags: [
|
|
211
|
-
"--home",
|
|
212
|
-
"--dashboard-url",
|
|
213
|
-
"--email",
|
|
214
|
-
"--device-name",
|
|
215
|
-
"--json",
|
|
216
|
-
"--no-auth",
|
|
217
|
-
"--poll-interval-ms",
|
|
218
|
-
"--timeout-ms",
|
|
219
|
-
],
|
|
220
|
-
valueFlags: [
|
|
221
|
-
"--home",
|
|
222
|
-
"--dashboard-url",
|
|
223
|
-
"--email",
|
|
224
|
-
"--device-name",
|
|
225
|
-
"--poll-interval-ms",
|
|
226
|
-
"--timeout-ms",
|
|
227
|
-
],
|
|
228
|
-
});
|
|
229
|
-
assertNoPositionals(values.positionals, "login");
|
|
230
|
-
return {
|
|
231
|
-
kind: "login",
|
|
232
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
233
|
-
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
234
|
-
claimedOwnerEmail: optionalEmail(values.flags.get("--email")),
|
|
235
|
-
deviceName: optionalNonEmpty(values.flags.get("--device-name")),
|
|
236
|
-
json: values.booleans.has("--json"),
|
|
237
|
-
noAuth: values.booleans.has("--no-auth"),
|
|
238
|
-
pollIntervalMs: optionalPositiveInteger(values.flags.get("--poll-interval-ms"), "--poll-interval-ms"),
|
|
239
|
-
timeoutMs: optionalPositiveInteger(values.flags.get("--timeout-ms"), "--timeout-ms"),
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
export function parseLogoutArgs(args) {
|
|
243
|
-
const values = parseNamedArgs(args, {
|
|
244
|
-
allowedFlags: ["--home", "--json", "--revoke", "--dashboard-url", "--yes"],
|
|
245
|
-
valueFlags: ["--home", "--dashboard-url"],
|
|
246
|
-
});
|
|
247
|
-
assertNoPositionals(values.positionals, "logout");
|
|
248
|
-
return {
|
|
249
|
-
kind: "logout",
|
|
250
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
251
|
-
json: values.booleans.has("--json"),
|
|
252
|
-
revoke: values.booleans.has("--revoke"),
|
|
253
|
-
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
254
|
-
yes: values.booleans.has("--yes"),
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
export function parseStartArgs(args) {
|
|
258
|
-
const values = parseNamedArgs(args, {
|
|
259
|
-
allowedFlags: [
|
|
260
|
-
"--home",
|
|
261
|
-
"--repo",
|
|
262
|
-
"--workspace",
|
|
263
|
-
"--branch",
|
|
264
|
-
"--ticket",
|
|
265
|
-
"--clear-ticket",
|
|
266
|
-
"--topic",
|
|
267
|
-
"--topic-summary",
|
|
268
|
-
"--intent",
|
|
269
|
-
"--phase",
|
|
270
|
-
"--intent-source",
|
|
271
|
-
"--intent-confidence",
|
|
272
|
-
"--operator-id",
|
|
273
|
-
"--session-id",
|
|
274
|
-
"--json",
|
|
275
|
-
"--max-depth",
|
|
276
|
-
"--max-repos",
|
|
277
|
-
],
|
|
278
|
-
valueFlags: [
|
|
279
|
-
"--home",
|
|
280
|
-
"--repo",
|
|
281
|
-
"--workspace",
|
|
282
|
-
"--branch",
|
|
283
|
-
"--ticket",
|
|
284
|
-
"--topic",
|
|
285
|
-
"--topic-summary",
|
|
286
|
-
"--intent",
|
|
287
|
-
"--phase",
|
|
288
|
-
"--intent-source",
|
|
289
|
-
"--intent-confidence",
|
|
290
|
-
"--operator-id",
|
|
291
|
-
"--session-id",
|
|
292
|
-
"--max-depth",
|
|
293
|
-
"--max-repos",
|
|
294
|
-
],
|
|
295
|
-
});
|
|
296
|
-
assertNoPositionals(values.positionals, "start");
|
|
297
|
-
const activeTicketId = optionalNonEmpty(values.flags.get("--ticket"));
|
|
298
|
-
const clearTicket = values.booleans.has("--clear-ticket");
|
|
299
|
-
if (activeTicketId && clearTicket) {
|
|
300
|
-
throw new Error("--ticket and --clear-ticket cannot be combined.");
|
|
301
|
-
}
|
|
302
|
-
const topicLabel = optionalNonEmpty(values.flags.get("--topic"));
|
|
303
|
-
const topicSummaryRedacted = optionalNonEmpty(values.flags.get("--topic-summary"));
|
|
304
|
-
const workIntent = optionalSchemaValue(WorkIntentSchema, values.flags.get("--intent"), "--intent");
|
|
305
|
-
const workPhase = optionalSchemaValue(WorkPhaseSchema, values.flags.get("--phase"), "--phase");
|
|
306
|
-
const intentConfidence = optionalConfidence(values.flags.get("--intent-confidence"), "--intent-confidence");
|
|
307
|
-
const explicitIntentMetadata = Boolean(topicLabel ||
|
|
308
|
-
topicSummaryRedacted ||
|
|
309
|
-
workIntent ||
|
|
310
|
-
workPhase ||
|
|
311
|
-
intentConfidence !== undefined);
|
|
312
|
-
return {
|
|
313
|
-
kind: "start",
|
|
314
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
315
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
316
|
-
branch: optionalNonEmpty(values.flags.get("--branch")),
|
|
317
|
-
activeTicketId,
|
|
318
|
-
clearTicket,
|
|
319
|
-
topicLabel,
|
|
320
|
-
topicSummaryRedacted,
|
|
321
|
-
workIntent,
|
|
322
|
-
workPhase,
|
|
323
|
-
intentSource: optionalSchemaValue(IntentSourceSchema, values.flags.get("--intent-source"), "--intent-source") ?? (explicitIntentMetadata ? "explicit_user" : undefined),
|
|
324
|
-
intentConfidence,
|
|
325
|
-
operatorId: optionalNonEmpty(values.flags.get("--operator-id")),
|
|
326
|
-
sessionId: optionalNonEmpty(values.flags.get("--session-id")),
|
|
327
|
-
json: values.booleans.has("--json"),
|
|
328
|
-
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
329
|
-
maxRepos: optionalPositiveInteger(values.flags.get("--max-repos"), "--max-repos"),
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
export function parseSyncArgs(args) {
|
|
333
|
-
return parseSyncLikeArgs(args, "sync");
|
|
334
|
-
}
|
|
335
|
-
export function parseAnalyzeArgs(args) {
|
|
336
|
-
return parseSyncLikeArgs(args, "analyze");
|
|
337
|
-
}
|
|
338
|
-
function parseSyncLikeArgs(args, command) {
|
|
339
|
-
const values = parseNamedArgs(args, {
|
|
340
|
-
allowedFlags: [
|
|
341
|
-
"--home",
|
|
342
|
-
"--repo",
|
|
343
|
-
"--workspace",
|
|
344
|
-
"--dashboard-url",
|
|
345
|
-
"--json",
|
|
346
|
-
"--max-depth",
|
|
347
|
-
"--max-repos",
|
|
348
|
-
],
|
|
349
|
-
valueFlags: [
|
|
350
|
-
"--home",
|
|
351
|
-
"--repo",
|
|
352
|
-
"--workspace",
|
|
353
|
-
"--dashboard-url",
|
|
354
|
-
"--max-depth",
|
|
355
|
-
"--max-repos",
|
|
356
|
-
],
|
|
357
|
-
});
|
|
358
|
-
assertNoPositionals(values.positionals, command);
|
|
359
|
-
return {
|
|
360
|
-
kind: command,
|
|
361
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
362
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
363
|
-
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
364
|
-
json: values.booleans.has("--json"),
|
|
365
|
-
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
366
|
-
maxRepos: optionalPositiveInteger(values.flags.get("--max-repos"), "--max-repos"),
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
export function parseBackfillArgs(args) {
|
|
370
|
-
const values = parseNamedArgs(args, {
|
|
371
|
-
allowedFlags: [
|
|
372
|
-
"--home",
|
|
373
|
-
"--repo",
|
|
374
|
-
"--workspace",
|
|
375
|
-
"--since-days",
|
|
376
|
-
"--all",
|
|
377
|
-
"--source",
|
|
378
|
-
"--dry-run",
|
|
379
|
-
"--max-files",
|
|
380
|
-
"--max-depth",
|
|
381
|
-
"--max-repos",
|
|
382
|
-
"--yes",
|
|
383
|
-
"--json",
|
|
384
|
-
],
|
|
385
|
-
valueFlags: [
|
|
386
|
-
"--home",
|
|
387
|
-
"--repo",
|
|
388
|
-
"--workspace",
|
|
389
|
-
"--since-days",
|
|
390
|
-
"--source",
|
|
391
|
-
"--max-files",
|
|
392
|
-
"--max-depth",
|
|
393
|
-
"--max-repos",
|
|
394
|
-
],
|
|
395
|
-
});
|
|
396
|
-
assertNoPositionals(values.positionals, "backfill");
|
|
397
|
-
const source = values.flags.get("--source");
|
|
398
|
-
if (source !== undefined && source !== "codex" && source !== "claude") {
|
|
399
|
-
throw new Error("--source must be 'codex' or 'claude'. Omit it to scan both.");
|
|
400
|
-
}
|
|
401
|
-
const sinceDays = optionalPositiveInteger(values.flags.get("--since-days"), "--since-days");
|
|
402
|
-
const all = values.booleans.has("--all");
|
|
403
|
-
if (all && sinceDays !== undefined) {
|
|
404
|
-
throw new Error("--since-days and --all cannot be combined.");
|
|
405
|
-
}
|
|
406
|
-
return {
|
|
407
|
-
kind: "backfill",
|
|
408
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
409
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
410
|
-
source,
|
|
411
|
-
sinceDays,
|
|
412
|
-
all,
|
|
413
|
-
dryRun: values.booleans.has("--dry-run"),
|
|
414
|
-
maxFiles: optionalPositiveInteger(values.flags.get("--max-files"), "--max-files"),
|
|
415
|
-
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
416
|
-
maxRepos: optionalPositiveInteger(values.flags.get("--max-repos"), "--max-repos"),
|
|
417
|
-
yes: values.booleans.has("--yes"),
|
|
418
|
-
json: values.booleans.has("--json"),
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
export function parseStatusArgs(args) {
|
|
422
|
-
const values = parseNamedArgs(args, {
|
|
423
|
-
allowedFlags: [
|
|
424
|
-
"--home",
|
|
425
|
-
"--repo",
|
|
426
|
-
"--workspace",
|
|
427
|
-
"--json",
|
|
428
|
-
"--max-depth",
|
|
429
|
-
"--max-repos",
|
|
430
|
-
],
|
|
431
|
-
valueFlags: [
|
|
432
|
-
"--home",
|
|
433
|
-
"--repo",
|
|
434
|
-
"--workspace",
|
|
435
|
-
"--max-depth",
|
|
436
|
-
"--max-repos",
|
|
437
|
-
],
|
|
438
|
-
});
|
|
439
|
-
assertNoPositionals(values.positionals, "status");
|
|
440
|
-
return {
|
|
441
|
-
kind: "status",
|
|
442
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
443
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
444
|
-
json: values.booleans.has("--json"),
|
|
445
|
-
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
446
|
-
maxRepos: optionalPositiveInteger(values.flags.get("--max-repos"), "--max-repos"),
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
export function parseSessionsArgs(args) {
|
|
450
|
-
const values = parseNamedArgs(args, {
|
|
451
|
-
allowedFlags: [
|
|
452
|
-
"--home",
|
|
453
|
-
"--repo",
|
|
454
|
-
"--workspace",
|
|
455
|
-
"--source",
|
|
456
|
-
"--since-days",
|
|
457
|
-
"--all",
|
|
458
|
-
"--json",
|
|
459
|
-
"--max-depth",
|
|
460
|
-
"--max-repos",
|
|
461
|
-
],
|
|
462
|
-
valueFlags: [
|
|
463
|
-
"--home",
|
|
464
|
-
"--repo",
|
|
465
|
-
"--workspace",
|
|
466
|
-
"--source",
|
|
467
|
-
"--since-days",
|
|
468
|
-
"--max-depth",
|
|
469
|
-
"--max-repos",
|
|
470
|
-
],
|
|
471
|
-
});
|
|
472
|
-
assertNoPositionals(values.positionals, "sessions");
|
|
473
|
-
const source = values.flags.get("--source");
|
|
474
|
-
if (source !== undefined && source !== "codex" && source !== "claude") {
|
|
475
|
-
throw new Error("--source must be 'codex' or 'claude'. Omit it to scan both.");
|
|
476
|
-
}
|
|
477
|
-
const sinceDays = optionalPositiveInteger(values.flags.get("--since-days"), "--since-days");
|
|
478
|
-
const all = values.booleans.has("--all");
|
|
479
|
-
if (all && sinceDays !== undefined) {
|
|
480
|
-
throw new Error("--since-days and --all cannot be combined.");
|
|
481
|
-
}
|
|
482
|
-
return {
|
|
483
|
-
kind: "sessions",
|
|
484
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
485
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
486
|
-
source,
|
|
487
|
-
sinceDays,
|
|
488
|
-
all,
|
|
489
|
-
json: values.booleans.has("--json"),
|
|
490
|
-
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
491
|
-
maxRepos: optionalPositiveInteger(values.flags.get("--max-repos"), "--max-repos"),
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
export function parseServeArgs(args) {
|
|
495
|
-
const values = parseNamedArgs(args, {
|
|
496
|
-
allowedFlags: ["--home", "--repo", "--workspace", "--port"],
|
|
497
|
-
valueFlags: ["--home", "--repo", "--workspace", "--port"],
|
|
498
|
-
});
|
|
499
|
-
assertNoPositionals(values.positionals, "serve");
|
|
500
|
-
const port = Number(values.flags.get("--port") ?? "4174");
|
|
501
|
-
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
502
|
-
throw new Error("--port must be a TCP port between 1 and 65535.");
|
|
503
|
-
}
|
|
504
|
-
return {
|
|
505
|
-
kind: "serve",
|
|
506
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
507
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
508
|
-
port,
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
export function parseAutostartArgs(args) {
|
|
512
|
-
const values = parseNamedArgs(args, {
|
|
513
|
-
allowedFlags: [
|
|
514
|
-
"--home",
|
|
515
|
-
"--repo",
|
|
516
|
-
"--workspace",
|
|
517
|
-
"--dashboard-url",
|
|
518
|
-
"--interval-seconds",
|
|
519
|
-
"--parent-pid",
|
|
520
|
-
"--json",
|
|
521
|
-
],
|
|
522
|
-
valueFlags: [
|
|
523
|
-
"--home",
|
|
524
|
-
"--repo",
|
|
525
|
-
"--workspace",
|
|
526
|
-
"--dashboard-url",
|
|
527
|
-
"--interval-seconds",
|
|
528
|
-
"--parent-pid",
|
|
529
|
-
],
|
|
530
|
-
});
|
|
531
|
-
if (values.positionals.length > 1) {
|
|
532
|
-
throw new Error("autostart accepts at most one action (install|uninstall|status).");
|
|
533
|
-
}
|
|
534
|
-
const action = values.positionals[0] ?? "install";
|
|
535
|
-
if (action !== "install" &&
|
|
536
|
-
action !== "uninstall" &&
|
|
537
|
-
action !== "status" &&
|
|
538
|
-
action !== "heal-detached") {
|
|
539
|
-
throw new Error("autostart action must be install, uninstall, or status.");
|
|
540
|
-
}
|
|
541
|
-
return {
|
|
542
|
-
kind: "autostart",
|
|
543
|
-
action,
|
|
544
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
545
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
546
|
-
dashboardUrl: normalizeUrl(values.flags.get("--dashboard-url") ?? DEFAULT_DASHBOARD_URL),
|
|
547
|
-
intervalSeconds: optionalPositiveInteger(values.flags.get("--interval-seconds"), "--interval-seconds") ?? DEFAULT_AUTOSTART_INTERVAL_SECONDS,
|
|
548
|
-
parentPid: optionalPositiveInteger(values.flags.get("--parent-pid"), "--parent-pid"),
|
|
549
|
-
json: values.booleans.has("--json"),
|
|
550
|
-
};
|
|
551
|
-
}
|
|
552
|
-
export function parseAgentRulesArgs(args) {
|
|
553
|
-
const values = parseNamedArgs(args, {
|
|
554
|
-
allowedFlags: ["--home", "--host", "--repo", "--workspace", "--json"],
|
|
555
|
-
valueFlags: ["--home", "--host", "--repo", "--workspace"],
|
|
556
|
-
});
|
|
557
|
-
if (values.positionals.length > 1) {
|
|
558
|
-
throw new Error("agent-rules accepts at most one action (install|uninstall|status).");
|
|
559
|
-
}
|
|
560
|
-
const action = values.positionals[0] ?? "install";
|
|
561
|
-
if (action !== "install" && action !== "uninstall" && action !== "status") {
|
|
562
|
-
throw new Error("agent-rules action must be install, uninstall, or status.");
|
|
563
|
-
}
|
|
564
|
-
return {
|
|
565
|
-
kind: "agent-rules",
|
|
566
|
-
action,
|
|
567
|
-
host: parseAgentRulesHost(values.flags.get("--host")),
|
|
568
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
569
|
-
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
570
|
-
json: values.booleans.has("--json"),
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
/**
|
|
574
|
-
* BLI-3580. `install` is the default action on purpose: this command exists to
|
|
575
|
-
* be run unasked (by `do-everything` and by the sync tick), and a bare
|
|
576
|
-
* `cockpit memory` should do the thing rather than print usage.
|
|
577
|
-
*/
|
|
578
|
-
export function parseMemoryArgs(args) {
|
|
579
|
-
const values = parseNamedArgs(args, {
|
|
580
|
-
allowedFlags: ["--home", "--dashboard-url", "--dry-run", "--json"],
|
|
581
|
-
valueFlags: ["--home", "--dashboard-url"],
|
|
582
|
-
});
|
|
583
|
-
if (values.positionals.length > 1) {
|
|
584
|
-
throw new Error("memory accepts at most one action (install|status).");
|
|
585
|
-
}
|
|
586
|
-
const action = values.positionals[0] ?? "install";
|
|
587
|
-
if (action !== "install" && action !== "status") {
|
|
588
|
-
throw new Error("memory action must be install or status.");
|
|
589
|
-
}
|
|
590
|
-
return {
|
|
591
|
-
kind: "memory",
|
|
592
|
-
action,
|
|
593
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
594
|
-
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
595
|
-
dryRun: values.booleans.has("--dry-run"),
|
|
596
|
-
json: values.booleans.has("--json"),
|
|
597
|
-
};
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* BLI-3619. Deliberately takes no positional: `clean` is one verb, and the two
|
|
601
|
-
* flags say how far it goes. A path is never accepted — the only directory this
|
|
602
|
-
* command may touch is the collector's own state directory.
|
|
14
|
+
* local-args-collector-setup.ts install, onboard, login, pair, update,
|
|
15
|
+
* upgrade, do-everything, fix, logout,
|
|
16
|
+
* release — getting a machine collecting
|
|
17
|
+
* local-args-collector-work.ts start, sync, analyze, backfill — the
|
|
18
|
+
* ongoing collection work an already-set-up
|
|
19
|
+
* machine does
|
|
20
|
+
* local-args-collector-status.ts status, sessions, serve, autostart,
|
|
21
|
+
* agent-rules, memory, clean — reading or
|
|
22
|
+
* maintaining a machine that already
|
|
23
|
+
* collects
|
|
24
|
+
*
|
|
25
|
+
* Every name this module has ever exported is still importable from here.
|
|
603
26
|
*/
|
|
604
|
-
export
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
"--home",
|
|
608
|
-
"--dashboard-url",
|
|
609
|
-
"--dry-run",
|
|
610
|
-
"--all-committed",
|
|
611
|
-
"--reconcile",
|
|
612
|
-
"--json",
|
|
613
|
-
],
|
|
614
|
-
valueFlags: ["--home", "--dashboard-url"],
|
|
615
|
-
});
|
|
616
|
-
if (values.positionals.length > 0) {
|
|
617
|
-
throw new Error("clean takes no arguments; use --dry-run, --all-committed, or --reconcile.");
|
|
618
|
-
}
|
|
619
|
-
return {
|
|
620
|
-
kind: "clean",
|
|
621
|
-
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
622
|
-
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
623
|
-
dryRun: values.booleans.has("--dry-run"),
|
|
624
|
-
allCommitted: values.booleans.has("--all-committed"),
|
|
625
|
-
reconcile: values.booleans.has("--reconcile"),
|
|
626
|
-
json: values.booleans.has("--json"),
|
|
627
|
-
};
|
|
628
|
-
}
|
|
629
|
-
function parseAgentRulesHost(value) {
|
|
630
|
-
const host = value?.trim().toLowerCase() || "all";
|
|
631
|
-
if (host === "codex" || host === "claude" || host === "all")
|
|
632
|
-
return host;
|
|
633
|
-
throw new Error("agent-rules --host must be codex, claude, or all.");
|
|
634
|
-
}
|
|
27
|
+
export { parseOnboardArgs, parseUpdateArgs, parseDoctorArgs, parseInstallArgs, parseReleaseArgs, parseLoginArgs, parseLogoutArgs, } from "./local-args-collector-setup.js";
|
|
28
|
+
export { parseStartArgs, parseSyncArgs, parseAnalyzeArgs, parseBackfillArgs, } from "./local-args-collector-work.js";
|
|
29
|
+
export { parseStatusArgs, parseSessionsArgs, parseServeArgs, parseAutostartArgs, parseAgentRulesArgs, parseMemoryArgs, parseCleanArgs, } from "./local-args-collector-status.js";
|