@bli-cockpit/cli 0.1.16 → 0.1.17
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/README.md +6 -5
- package/dist/autostart.js +2 -2
- package/dist/commands/local-args.js +90 -18
- package/dist/commands/local.js +26 -18
- package/dist/commands/public-root.js +1 -1
- package/dist/upload.js +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ npm install -g @bli-cockpit/cli@latest
|
|
|
19
19
|
cockpit onboard \
|
|
20
20
|
--email <APPROVED_EMAIL> \
|
|
21
21
|
--device-name "$COCKPIT_DEVICE_NAME" \
|
|
22
|
-
--
|
|
22
|
+
--workspace "$PWD"
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
If a work folder contains multiple repos, run the same command from the parent:
|
|
@@ -31,7 +31,7 @@ npm install -g @bli-cockpit/cli@latest
|
|
|
31
31
|
cockpit onboard \
|
|
32
32
|
--email <APPROVED_EMAIL> \
|
|
33
33
|
--device-name "$COCKPIT_DEVICE_NAME" \
|
|
34
|
-
--
|
|
34
|
+
--workspace "$PWD"
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
The CLI defaults to the production dashboard. Normal intern/operator setup,
|
|
@@ -39,7 +39,8 @@ updates, and syncs omit `--dashboard-url`. Pass `--dashboard-url` only for
|
|
|
39
39
|
staging, a custom dashboard, or deliberately forcing a different dashboard
|
|
40
40
|
pairing. Already-onboarded users update with
|
|
41
41
|
`npm install -g @bli-cockpit/cli@latest`, then run
|
|
42
|
-
`cockpit sync --
|
|
42
|
+
`cockpit sync --workspace "$PWD" --json`. `--repo <path>` remains supported
|
|
43
|
+
for older prompts and the Codex ticket-binding guardrail.
|
|
43
44
|
|
|
44
45
|
On machines where Codex agents will do ticketed work, install the user-scope
|
|
45
46
|
agent rule once:
|
|
@@ -97,7 +98,7 @@ cockpit start \
|
|
|
97
98
|
--repo "$PWD"
|
|
98
99
|
|
|
99
100
|
cockpit sync \
|
|
100
|
-
--
|
|
101
|
+
--workspace "$PWD" \
|
|
101
102
|
--json
|
|
102
103
|
```
|
|
103
104
|
|
|
@@ -149,7 +150,7 @@ repo, ticket, and raw JSONL object, see
|
|
|
149
150
|
Local attribution preview:
|
|
150
151
|
|
|
151
152
|
```bash
|
|
152
|
-
cockpit sessions --
|
|
153
|
+
cockpit sessions --workspace "$PWD" --json
|
|
153
154
|
```
|
|
154
155
|
|
|
155
156
|
Remote metadata path:
|
package/dist/autostart.js
CHANGED
|
@@ -126,12 +126,12 @@ async function existingWatchPaths(homeDir) {
|
|
|
126
126
|
return candidates.filter((_, i) => present[i]);
|
|
127
127
|
}
|
|
128
128
|
function renderPlist(options) {
|
|
129
|
-
// The
|
|
129
|
+
// The work path is shell-quoted because it lands inside a `/bin/zsh -lc "…"`
|
|
130
130
|
// command string; the whole command is then XML-escaped for the <string>.
|
|
131
131
|
const dashboardArg = options.dashboardUrl === DEFAULT_DASHBOARD_URL
|
|
132
132
|
? ""
|
|
133
133
|
: ` --dashboard-url ${shellQuote(options.dashboardUrl)}`;
|
|
134
|
-
const command = `cockpit sync --
|
|
134
|
+
const command = `cockpit sync --workspace ${shellQuote(options.workDir)}${dashboardArg} --json`;
|
|
135
135
|
return [
|
|
136
136
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
137
137
|
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// Behavior-preserving extraction: functions moved verbatim, no logic change.
|
|
6
6
|
import { DEFAULT_DASHBOARD_URL } from "../local-state.js";
|
|
7
7
|
import { DEFAULT_AUTOSTART_INTERVAL_SECONDS } from "../autostart.js";
|
|
8
|
+
const WORK_ROOT_FLAGS = ["--repo", "--workspace"];
|
|
8
9
|
export function parseLocalArgs(argv) {
|
|
9
10
|
const command = argv[0];
|
|
10
11
|
switch (command) {
|
|
@@ -40,6 +41,7 @@ function parseOnboardArgs(args) {
|
|
|
40
41
|
allowedFlags: [
|
|
41
42
|
"--home",
|
|
42
43
|
"--repo",
|
|
44
|
+
"--workspace",
|
|
43
45
|
"--dashboard-url",
|
|
44
46
|
"--email",
|
|
45
47
|
"--device-name",
|
|
@@ -54,6 +56,7 @@ function parseOnboardArgs(args) {
|
|
|
54
56
|
valueFlags: [
|
|
55
57
|
"--home",
|
|
56
58
|
"--repo",
|
|
59
|
+
"--workspace",
|
|
57
60
|
"--dashboard-url",
|
|
58
61
|
"--email",
|
|
59
62
|
"--device-name",
|
|
@@ -69,7 +72,7 @@ function parseOnboardArgs(args) {
|
|
|
69
72
|
return {
|
|
70
73
|
kind: "onboard",
|
|
71
74
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
72
|
-
repoRoot: optionalNonEmpty(values
|
|
75
|
+
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
73
76
|
dashboardUrl: normalizeUrl(values.flags.get("--dashboard-url") ?? DEFAULT_DASHBOARD_URL),
|
|
74
77
|
claimedOwnerEmail: optionalEmail(values.flags.get("--email")),
|
|
75
78
|
deviceName: optionalNonEmpty(values.flags.get("--device-name")),
|
|
@@ -87,17 +90,24 @@ function parseInstallArgs(args) {
|
|
|
87
90
|
allowedFlags: [
|
|
88
91
|
"--home",
|
|
89
92
|
"--repo",
|
|
93
|
+
"--workspace",
|
|
90
94
|
"--dashboard-url",
|
|
91
95
|
"--supabase-url",
|
|
92
96
|
"--json",
|
|
93
97
|
],
|
|
94
|
-
valueFlags: [
|
|
98
|
+
valueFlags: [
|
|
99
|
+
"--home",
|
|
100
|
+
"--repo",
|
|
101
|
+
"--workspace",
|
|
102
|
+
"--dashboard-url",
|
|
103
|
+
"--supabase-url",
|
|
104
|
+
],
|
|
95
105
|
});
|
|
96
106
|
assertNoPositionals(values.positionals, "install");
|
|
97
107
|
return {
|
|
98
108
|
kind: "install",
|
|
99
109
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
100
|
-
repoRoot: optionalNonEmpty(values
|
|
110
|
+
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
101
111
|
dashboardUrl: normalizeUrl(values.flags.get("--dashboard-url") ?? DEFAULT_DASHBOARD_URL),
|
|
102
112
|
supabaseUrl: optionalNonEmpty(values.flags.get("--supabase-url")),
|
|
103
113
|
json: values.booleans.has("--json"),
|
|
@@ -152,6 +162,7 @@ function parseStartArgs(args) {
|
|
|
152
162
|
allowedFlags: [
|
|
153
163
|
"--home",
|
|
154
164
|
"--repo",
|
|
165
|
+
"--workspace",
|
|
155
166
|
"--branch",
|
|
156
167
|
"--ticket",
|
|
157
168
|
"--operator-id",
|
|
@@ -163,6 +174,7 @@ function parseStartArgs(args) {
|
|
|
163
174
|
valueFlags: [
|
|
164
175
|
"--home",
|
|
165
176
|
"--repo",
|
|
177
|
+
"--workspace",
|
|
166
178
|
"--branch",
|
|
167
179
|
"--ticket",
|
|
168
180
|
"--operator-id",
|
|
@@ -175,7 +187,7 @@ function parseStartArgs(args) {
|
|
|
175
187
|
return {
|
|
176
188
|
kind: "start",
|
|
177
189
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
178
|
-
repoRoot: optionalNonEmpty(values
|
|
190
|
+
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
179
191
|
branch: optionalNonEmpty(values.flags.get("--branch")),
|
|
180
192
|
activeTicketId: optionalNonEmpty(values.flags.get("--ticket")),
|
|
181
193
|
operatorId: optionalNonEmpty(values.flags.get("--operator-id")),
|
|
@@ -187,14 +199,29 @@ function parseStartArgs(args) {
|
|
|
187
199
|
}
|
|
188
200
|
function parseSyncArgs(args) {
|
|
189
201
|
const values = parseNamedArgs(args, {
|
|
190
|
-
allowedFlags: [
|
|
191
|
-
|
|
202
|
+
allowedFlags: [
|
|
203
|
+
"--home",
|
|
204
|
+
"--repo",
|
|
205
|
+
"--workspace",
|
|
206
|
+
"--dashboard-url",
|
|
207
|
+
"--json",
|
|
208
|
+
"--max-depth",
|
|
209
|
+
"--max-repos",
|
|
210
|
+
],
|
|
211
|
+
valueFlags: [
|
|
212
|
+
"--home",
|
|
213
|
+
"--repo",
|
|
214
|
+
"--workspace",
|
|
215
|
+
"--dashboard-url",
|
|
216
|
+
"--max-depth",
|
|
217
|
+
"--max-repos",
|
|
218
|
+
],
|
|
192
219
|
});
|
|
193
220
|
assertNoPositionals(values.positionals, "sync");
|
|
194
221
|
return {
|
|
195
222
|
kind: "sync",
|
|
196
223
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
197
|
-
repoRoot: optionalNonEmpty(values
|
|
224
|
+
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
198
225
|
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
199
226
|
json: values.booleans.has("--json"),
|
|
200
227
|
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
@@ -203,14 +230,27 @@ function parseSyncArgs(args) {
|
|
|
203
230
|
}
|
|
204
231
|
function parseStatusArgs(args) {
|
|
205
232
|
const values = parseNamedArgs(args, {
|
|
206
|
-
allowedFlags: [
|
|
207
|
-
|
|
233
|
+
allowedFlags: [
|
|
234
|
+
"--home",
|
|
235
|
+
"--repo",
|
|
236
|
+
"--workspace",
|
|
237
|
+
"--json",
|
|
238
|
+
"--max-depth",
|
|
239
|
+
"--max-repos",
|
|
240
|
+
],
|
|
241
|
+
valueFlags: [
|
|
242
|
+
"--home",
|
|
243
|
+
"--repo",
|
|
244
|
+
"--workspace",
|
|
245
|
+
"--max-depth",
|
|
246
|
+
"--max-repos",
|
|
247
|
+
],
|
|
208
248
|
});
|
|
209
249
|
assertNoPositionals(values.positionals, "status");
|
|
210
250
|
return {
|
|
211
251
|
kind: "status",
|
|
212
252
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
213
|
-
repoRoot: optionalNonEmpty(values
|
|
253
|
+
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
214
254
|
json: values.booleans.has("--json"),
|
|
215
255
|
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
216
256
|
maxRepos: optionalPositiveInteger(values.flags.get("--max-repos"), "--max-repos"),
|
|
@@ -218,8 +258,23 @@ function parseStatusArgs(args) {
|
|
|
218
258
|
}
|
|
219
259
|
function parseSessionsArgs(args) {
|
|
220
260
|
const values = parseNamedArgs(args, {
|
|
221
|
-
allowedFlags: [
|
|
222
|
-
|
|
261
|
+
allowedFlags: [
|
|
262
|
+
"--home",
|
|
263
|
+
"--repo",
|
|
264
|
+
"--workspace",
|
|
265
|
+
"--source",
|
|
266
|
+
"--json",
|
|
267
|
+
"--max-depth",
|
|
268
|
+
"--max-repos",
|
|
269
|
+
],
|
|
270
|
+
valueFlags: [
|
|
271
|
+
"--home",
|
|
272
|
+
"--repo",
|
|
273
|
+
"--workspace",
|
|
274
|
+
"--source",
|
|
275
|
+
"--max-depth",
|
|
276
|
+
"--max-repos",
|
|
277
|
+
],
|
|
223
278
|
});
|
|
224
279
|
assertNoPositionals(values.positionals, "sessions");
|
|
225
280
|
const source = values.flags.get("--source");
|
|
@@ -229,7 +284,7 @@ function parseSessionsArgs(args) {
|
|
|
229
284
|
return {
|
|
230
285
|
kind: "sessions",
|
|
231
286
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
232
|
-
repoRoot: optionalNonEmpty(values
|
|
287
|
+
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
233
288
|
source,
|
|
234
289
|
json: values.booleans.has("--json"),
|
|
235
290
|
maxDepth: optionalPositiveInteger(values.flags.get("--max-depth"), "--max-depth"),
|
|
@@ -238,8 +293,8 @@ function parseSessionsArgs(args) {
|
|
|
238
293
|
}
|
|
239
294
|
function parseServeArgs(args) {
|
|
240
295
|
const values = parseNamedArgs(args, {
|
|
241
|
-
allowedFlags: ["--home", "--repo", "--port"],
|
|
242
|
-
valueFlags: ["--home", "--repo", "--port"],
|
|
296
|
+
allowedFlags: ["--home", "--repo", "--workspace", "--port"],
|
|
297
|
+
valueFlags: ["--home", "--repo", "--workspace", "--port"],
|
|
243
298
|
});
|
|
244
299
|
assertNoPositionals(values.positionals, "serve");
|
|
245
300
|
const port = Number(values.flags.get("--port") ?? "4174");
|
|
@@ -249,7 +304,7 @@ function parseServeArgs(args) {
|
|
|
249
304
|
return {
|
|
250
305
|
kind: "serve",
|
|
251
306
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
252
|
-
repoRoot: optionalNonEmpty(values
|
|
307
|
+
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
253
308
|
port,
|
|
254
309
|
};
|
|
255
310
|
}
|
|
@@ -258,11 +313,18 @@ function parseAutostartArgs(args) {
|
|
|
258
313
|
allowedFlags: [
|
|
259
314
|
"--home",
|
|
260
315
|
"--repo",
|
|
316
|
+
"--workspace",
|
|
261
317
|
"--dashboard-url",
|
|
262
318
|
"--interval-seconds",
|
|
263
319
|
"--json",
|
|
264
320
|
],
|
|
265
|
-
valueFlags: [
|
|
321
|
+
valueFlags: [
|
|
322
|
+
"--home",
|
|
323
|
+
"--repo",
|
|
324
|
+
"--workspace",
|
|
325
|
+
"--dashboard-url",
|
|
326
|
+
"--interval-seconds",
|
|
327
|
+
],
|
|
266
328
|
});
|
|
267
329
|
if (values.positionals.length > 1) {
|
|
268
330
|
throw new Error("autostart accepts at most one action (install|uninstall|status).");
|
|
@@ -275,7 +337,7 @@ function parseAutostartArgs(args) {
|
|
|
275
337
|
kind: "autostart",
|
|
276
338
|
action,
|
|
277
339
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
278
|
-
repoRoot: optionalNonEmpty(values
|
|
340
|
+
repoRoot: optionalNonEmpty(workRootFlagValue(values)),
|
|
279
341
|
dashboardUrl: normalizeUrl(values.flags.get("--dashboard-url") ?? DEFAULT_DASHBOARD_URL),
|
|
280
342
|
intervalSeconds: optionalPositiveInteger(values.flags.get("--interval-seconds"), "--interval-seconds") ?? DEFAULT_AUTOSTART_INTERVAL_SECONDS,
|
|
281
343
|
json: values.booleans.has("--json"),
|
|
@@ -334,6 +396,16 @@ function parseNamedArgs(args, options) {
|
|
|
334
396
|
}
|
|
335
397
|
return { flags, booleans, positionals };
|
|
336
398
|
}
|
|
399
|
+
function workRootFlagValue(values) {
|
|
400
|
+
const provided = WORK_ROOT_FLAGS.filter((flag) => values.flags.has(flag));
|
|
401
|
+
if (provided.length === 0)
|
|
402
|
+
return undefined;
|
|
403
|
+
const uniqueValues = new Set(provided.map((flag) => values.flags.get(flag)).filter(Boolean));
|
|
404
|
+
if (uniqueValues.size > 1) {
|
|
405
|
+
throw new Error("--repo and --workspace must point to the same path.");
|
|
406
|
+
}
|
|
407
|
+
return values.flags.get("--workspace") ?? values.flags.get("--repo");
|
|
408
|
+
}
|
|
337
409
|
function assertNoPositionals(positionals, command) {
|
|
338
410
|
if (positionals.length > 0) {
|
|
339
411
|
throw new Error(`${command} does not accept positional arguments.`);
|
package/dist/commands/local.js
CHANGED
|
@@ -75,17 +75,17 @@ export function localCommandHelp(command) {
|
|
|
75
75
|
if (command)
|
|
76
76
|
return localSubcommandHelp(command);
|
|
77
77
|
return [
|
|
78
|
-
" cockpit onboard [--ticket <id>] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--
|
|
79
|
-
" cockpit install [--dashboard-url <url>] [--
|
|
78
|
+
" cockpit onboard [--ticket <id>] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--workspace <path>] [--branch <name>] [--max-depth <n>] [--max-repos <n>] [--json]",
|
|
79
|
+
" cockpit install [--dashboard-url <url>] [--workspace <path>] [--json]",
|
|
80
80
|
" cockpit login [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--json]",
|
|
81
81
|
" cockpit pair [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--json]",
|
|
82
82
|
" cockpit logout",
|
|
83
|
-
" cockpit start [--ticket <id>] [--
|
|
84
|
-
" cockpit sync [--
|
|
85
|
-
" cockpit status [--
|
|
86
|
-
" cockpit sessions [--source codex|claude] [--
|
|
87
|
-
" cockpit serve [--port <port>] [--
|
|
88
|
-
" cockpit autostart [install|uninstall|status] [--
|
|
83
|
+
" cockpit start [--ticket <id>] [--workspace <path>] [--branch <name>] [--max-depth <n>] [--max-repos <n>] [--json]",
|
|
84
|
+
" cockpit sync [--workspace <path>] [--dashboard-url <url>] [--max-depth <n>] [--max-repos <n>] [--json]",
|
|
85
|
+
" cockpit status [--workspace <path>] [--max-depth <n>] [--max-repos <n>] [--json]",
|
|
86
|
+
" cockpit sessions [--source codex|claude] [--workspace <path>] [--max-depth <n>] [--max-repos <n>] [--json]",
|
|
87
|
+
" cockpit serve [--port <port>] [--workspace <path>]",
|
|
88
|
+
" cockpit autostart [install|uninstall|status] [--workspace <path>] [--dashboard-url <url>] [--interval-seconds <n>] [--json]",
|
|
89
89
|
" cockpit agent-rules [install|uninstall|status] [--json]",
|
|
90
90
|
"",
|
|
91
91
|
`Default dashboard: ${DEFAULT_DASHBOARD_URL}. Omit --dashboard-url for normal production use; pass it only for staging/custom dashboards or to force a different pairing.`,
|
|
@@ -96,10 +96,11 @@ function localSubcommandHelp(command) {
|
|
|
96
96
|
[
|
|
97
97
|
"onboard",
|
|
98
98
|
[
|
|
99
|
-
"Usage: cockpit onboard [--ticket <id>] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--
|
|
99
|
+
"Usage: cockpit onboard [--ticket <id>] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--workspace <path>] [--branch <name>] [--json]",
|
|
100
100
|
"",
|
|
101
101
|
"Installs, pairs, starts work context(s), syncs once, and prints readiness proof.",
|
|
102
|
-
"If --
|
|
102
|
+
"If --workspace is a parent folder, scans child git repos/worktrees and rolls them up by repo.",
|
|
103
|
+
"`--repo <path>` remains supported as a backward-compatible alias.",
|
|
103
104
|
`Omit --dashboard-url for normal production setup (${DEFAULT_DASHBOARD_URL}).`,
|
|
104
105
|
"Pass --dashboard-url only for staging/custom dashboards or to force a different pairing.",
|
|
105
106
|
"Run with no flags in a terminal and it prompts for the dashboard email; pass --email to skip the prompt (and on shared/reused machines, where mismatched sessions are re-paired).",
|
|
@@ -108,9 +109,10 @@ function localSubcommandHelp(command) {
|
|
|
108
109
|
[
|
|
109
110
|
"install",
|
|
110
111
|
[
|
|
111
|
-
"Usage: cockpit install [--dashboard-url <url>] [--
|
|
112
|
+
"Usage: cockpit install [--dashboard-url <url>] [--workspace <path>] [--json]",
|
|
112
113
|
"",
|
|
113
114
|
"Writes local collector config. Pair with `cockpit login`, then run `cockpit start` when work begins.",
|
|
115
|
+
"`--repo <path>` remains supported as a backward-compatible alias.",
|
|
114
116
|
"Omit --dashboard-url for the production dashboard; pass it only for staging/custom dashboards.",
|
|
115
117
|
],
|
|
116
118
|
],
|
|
@@ -135,19 +137,21 @@ function localSubcommandHelp(command) {
|
|
|
135
137
|
[
|
|
136
138
|
"start",
|
|
137
139
|
[
|
|
138
|
-
"Usage: cockpit start [--ticket <id>] [--
|
|
140
|
+
"Usage: cockpit start [--ticket <id>] [--workspace <path>] [--branch <name>] [--json]",
|
|
139
141
|
"",
|
|
140
142
|
"Starts local ambient capture. Parent folders start each child git worktree.",
|
|
141
143
|
"Add --ticket only when the work already has a visible ticket.",
|
|
144
|
+
"`--repo <path>` remains supported and is still the canonical agent-rule spelling.",
|
|
142
145
|
],
|
|
143
146
|
],
|
|
144
147
|
[
|
|
145
148
|
"sync",
|
|
146
149
|
[
|
|
147
|
-
"Usage: cockpit sync [--
|
|
150
|
+
"Usage: cockpit sync [--workspace <path>] [--dashboard-url <url>] [--json]",
|
|
148
151
|
"",
|
|
149
152
|
"Uploads latest local ambient envelope(s), or spools safe retries if blocked.",
|
|
150
153
|
"Omit --dashboard-url for normal production sync; pass it only for staging/custom dashboards or forced re-pairing.",
|
|
154
|
+
"`--repo <path>` remains supported as a backward-compatible alias.",
|
|
151
155
|
"Parent folders sync each child git worktree; Codex AND Claude Code JSONL",
|
|
152
156
|
"transcripts (and Claude subagent sidecars) are attributed to repos",
|
|
153
157
|
"deterministically and ambiguous transcripts are retained as unattributed",
|
|
@@ -161,38 +165,42 @@ function localSubcommandHelp(command) {
|
|
|
161
165
|
[
|
|
162
166
|
"status",
|
|
163
167
|
[
|
|
164
|
-
"Usage: cockpit status [--
|
|
168
|
+
"Usage: cockpit status [--workspace <path>] [--json]",
|
|
165
169
|
"",
|
|
166
170
|
"Prints install, pairing, active work, upload, and retry state.",
|
|
171
|
+
"`--repo <path>` remains supported as a backward-compatible alias.",
|
|
167
172
|
],
|
|
168
173
|
],
|
|
169
174
|
[
|
|
170
175
|
"sessions",
|
|
171
176
|
[
|
|
172
|
-
"Usage: cockpit sessions [--source codex|claude] [--
|
|
177
|
+
"Usage: cockpit sessions [--source codex|claude] [--workspace <path>] [--json]",
|
|
173
178
|
"",
|
|
174
179
|
"Read-only: re-runs Codex + Claude session attribution and prints each",
|
|
175
180
|
"session's id, source, state, reason, scores, signals, and per-sidecar",
|
|
176
181
|
"skip reasons. No upload, no cursor writes. Answers \"why is session X",
|
|
177
182
|
"missing?\" locally — counts and labels only, never paths or content.",
|
|
183
|
+
"`--repo <path>` remains supported as a backward-compatible alias.",
|
|
178
184
|
],
|
|
179
185
|
],
|
|
180
186
|
[
|
|
181
187
|
"serve",
|
|
182
188
|
[
|
|
183
|
-
"Usage: cockpit serve [--port <port>] [--
|
|
189
|
+
"Usage: cockpit serve [--port <port>] [--workspace <path>]",
|
|
184
190
|
"",
|
|
185
191
|
"Starts the local collector HTTP status server.",
|
|
192
|
+
"`--repo <path>` remains supported as a backward-compatible alias.",
|
|
186
193
|
],
|
|
187
194
|
],
|
|
188
195
|
[
|
|
189
196
|
"autostart",
|
|
190
197
|
[
|
|
191
|
-
"Usage: cockpit autostart [install|uninstall|status] [--
|
|
198
|
+
"Usage: cockpit autostart [install|uninstall|status] [--workspace <path>] [--dashboard-url <url>] [--interval-seconds <n>] [--json]",
|
|
192
199
|
"",
|
|
193
200
|
"Installs a macOS launchd LaunchAgent that runs `cockpit sync` at login and",
|
|
194
201
|
"every 15 min (default), surviving reboots — so machines never drift to Stale.",
|
|
195
|
-
"Action defaults to `install`. `--
|
|
202
|
+
"Action defaults to `install`. `--workspace` is the parent work folder to sync.",
|
|
203
|
+
"`--repo <path>` remains supported as a backward-compatible alias.",
|
|
196
204
|
"Omit --dashboard-url for production; pass it only for staging/custom dashboards.",
|
|
197
205
|
"macOS-only for now; see docs/runbooks/cockpit-launchd-sync.md.",
|
|
198
206
|
],
|
|
@@ -24,7 +24,7 @@ function cockpitHelp() {
|
|
|
24
24
|
"",
|
|
25
25
|
"Install/update: `npm install -g @bli-cockpit/cli@latest`.",
|
|
26
26
|
"Intern path: run `cockpit onboard` from the repo root; add `--ticket <id>` only when work already has a ticket.",
|
|
27
|
-
"Already onboarded: run `cockpit sync --
|
|
27
|
+
"Already onboarded: run `cockpit sync --workspace \"$PWD\" --json`.",
|
|
28
28
|
"Agent setup: run `cockpit agent-rules install` so Codex asks for or binds Linear tickets before edits.",
|
|
29
29
|
"Dashboard URL is optional for normal production use; pass `--dashboard-url` only for staging/custom dashboards or forced re-pairing.",
|
|
30
30
|
"Manual collector path: `install`, `login`, `start [--ticket <id>]`, `sync`, `status`, `agent-rules`.",
|
package/dist/upload.js
CHANGED
|
@@ -19,7 +19,7 @@ export async function buildLocalAmbientEnvelope(options = {}) {
|
|
|
19
19
|
const now = options.now ?? new Date();
|
|
20
20
|
const paths = getCollectorRuntimePaths(options.homeDir);
|
|
21
21
|
const config = await readLocalCollectorConfig(paths).catch(() => {
|
|
22
|
-
throw new LocalUploadBlockedError("not_installed", "Local collector config missing. Install/update the CLI, then run `cockpit onboard` before `cockpit sync`.", "npm install -g @bli-cockpit/cli@latest && cockpit onboard --email <email> --
|
|
22
|
+
throw new LocalUploadBlockedError("not_installed", "Local collector config missing. Install/update the CLI, then run `cockpit onboard` before `cockpit sync`.", "npm install -g @bli-cockpit/cli@latest && cockpit onboard --email <email> --workspace \"$PWD\"");
|
|
23
23
|
});
|
|
24
24
|
const sessionFile = await readLocalCollectorSessionFile(paths).catch(() => {
|
|
25
25
|
throw new LocalUploadBlockedError("unpaired", "No paired collector session found. Run `cockpit login` or `cockpit pair` before `cockpit sync`.", "cockpit login");
|
|
@@ -32,7 +32,7 @@ export async function buildLocalAmbientEnvelope(options = {}) {
|
|
|
32
32
|
}
|
|
33
33
|
const repoRoot = path.resolve(options.repoRoot ?? process.cwd());
|
|
34
34
|
const activeContext = await readLocalWorkContextForRepo(paths, repoRoot).catch(() => {
|
|
35
|
-
throw new LocalUploadBlockedError("missing_context", "Active work context missing. Run `cockpit start --
|
|
35
|
+
throw new LocalUploadBlockedError("missing_context", "Active work context missing. Run `cockpit start --workspace \"$PWD\"` before `cockpit sync`.", "cockpit start --workspace \"$PWD\"");
|
|
36
36
|
});
|
|
37
37
|
const repoLabel = safeRepoLabel(activeContext.repo_label ?? repoRoot);
|
|
38
38
|
const uploadContext = makeUploadWorkContext({
|