@bli-cockpit/cli 0.2.237 → 0.2.239

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.
Files changed (148) hide show
  1. package/dist/adapters/attribution-core-fallbacks.js +15 -11
  2. package/dist/adapters/attribution-core-score.js +111 -87
  3. package/dist/adapters/car-state.js +38 -35
  4. package/dist/adapters/claude-attribution-discovery.js +81 -56
  5. package/dist/adapters/claude-attribution-score.js +108 -94
  6. package/dist/adapters/claude-attribution-signals.js +52 -42
  7. package/dist/adapters/codex-attribution.js +42 -33
  8. package/dist/adapters/codex-session-signals.js +11 -9
  9. package/dist/adapters/git-state.js +56 -50
  10. package/dist/adapters/local-sources.js +52 -43
  11. package/dist/adapters/raw-evidence-git-diff.js +4 -2
  12. package/dist/adapters/raw-evidence-sanitize.js +15 -12
  13. package/dist/adapters/raw-evidence-transcript-file.js +32 -31
  14. package/dist/autostart-self-heal.js +18 -2
  15. package/dist/commands/agent-session-report.js +51 -59
  16. package/dist/commands/agent-setup-observed.js +30 -23
  17. package/dist/commands/agent-setup.js +96 -45
  18. package/dist/commands/autostart-heal.js +8 -2
  19. package/dist/commands/autostart-reading.js +3 -0
  20. package/dist/commands/backfill-evidence-outcomes.js +9 -6
  21. package/dist/commands/backfill-issues.js +3 -0
  22. package/dist/commands/backfill-scan.js +27 -22
  23. package/dist/commands/backfill-upload.js +69 -60
  24. package/dist/commands/backfill.js +26 -21
  25. package/dist/commands/brief-done.js +4 -1
  26. package/dist/commands/brief-edit.js +71 -46
  27. package/dist/commands/cal-detail.js +35 -0
  28. package/dist/commands/cal-direct.js +119 -0
  29. package/dist/commands/cal-overlay.js +73 -30
  30. package/dist/commands/cal.js +62 -25
  31. package/dist/commands/clean.js +4 -1
  32. package/dist/commands/docs-read.js +5 -2
  33. package/dist/commands/docs.js +38 -6
  34. package/dist/commands/doctor-backfill.js +88 -71
  35. package/dist/commands/doctor-pipeline.js +59 -46
  36. package/dist/commands/heartbeat-post.js +116 -0
  37. package/dist/commands/heartbeat-token-lock.js +46 -33
  38. package/dist/commands/heartbeat.js +43 -125
  39. package/dist/commands/install-update.js +17 -15
  40. package/dist/commands/issue-show.js +27 -28
  41. package/dist/commands/issue-versions.js +93 -0
  42. package/dist/commands/issue-write.js +70 -23
  43. package/dist/commands/issue.js +73 -37
  44. package/dist/commands/jarvis-live-answer.js +99 -0
  45. package/dist/commands/jarvis-render.js +1 -94
  46. package/dist/commands/jarvis-trace.js +30 -22
  47. package/dist/commands/jarvis-turn-report.js +124 -0
  48. package/dist/commands/jarvis-turn.js +108 -182
  49. package/dist/commands/jarvis.js +26 -17
  50. package/dist/commands/local-args-collector-setup.js +82 -84
  51. package/dist/commands/local-args-collector-work.js +37 -38
  52. package/dist/commands/local-args-tower-admin.js +155 -142
  53. package/dist/commands/local-args-tower-cal.js +69 -54
  54. package/dist/commands/local-args-tower-careers.js +73 -54
  55. package/dist/commands/local-args-tower-docs-msg.js +79 -51
  56. package/dist/commands/local-args-tower-github.js +26 -20
  57. package/dist/commands/local-args-tower-hits.js +32 -20
  58. package/dist/commands/local-args-tower-manager.js +85 -4
  59. package/dist/commands/local-args-tower-memory.js +139 -117
  60. package/dist/commands/local-args-tower-msg.js +24 -6
  61. package/dist/commands/local-args-tower-notes.js +346 -0
  62. package/dist/commands/local-args-tower-pages.js +100 -378
  63. package/dist/commands/local-args-tower-settings.js +28 -29
  64. package/dist/commands/local-args-tower-setup.js +11 -4
  65. package/dist/commands/local-args-tower-work.js +74 -37
  66. package/dist/commands/local-args.js +80 -129
  67. package/dist/commands/local-help-commands-tower-ops.js +15 -4
  68. package/dist/commands/local-help-commands-tower.js +20 -7
  69. package/dist/commands/local-help-commands.js +342 -341
  70. package/dist/commands/local-help.js +87 -83
  71. package/dist/commands/local-run-guards.js +100 -0
  72. package/dist/commands/local.js +137 -206
  73. package/dist/commands/login.js +13 -9
  74. package/dist/commands/logs.js +55 -38
  75. package/dist/commands/mail-attachments.js +44 -26
  76. package/dist/commands/manager-render-home.js +208 -0
  77. package/dist/commands/manager-render.js +7 -3
  78. package/dist/commands/manager-requests.js +33 -0
  79. package/dist/commands/manager.js +39 -5
  80. package/dist/commands/memory-consolidation.js +18 -9
  81. package/dist/commands/memory-daemon-probe.js +37 -28
  82. package/dist/commands/memory-install-config.js +64 -60
  83. package/dist/commands/memory-install.js +21 -41
  84. package/dist/commands/memory-requeue.js +26 -19
  85. package/dist/commands/memory-rules.js +26 -18
  86. package/dist/commands/memory-search-print.js +26 -0
  87. package/dist/commands/memory-store.js +14 -30
  88. package/dist/commands/memory-verb-list.js +49 -48
  89. package/dist/commands/msg-read-line.js +32 -0
  90. package/dist/commands/msg.js +45 -3
  91. package/dist/commands/notes-accounts.js +49 -32
  92. package/dist/commands/notes-sync-loop.js +115 -89
  93. package/dist/commands/notes-wisprflow-login.js +44 -23
  94. package/dist/commands/notes-writes.js +115 -100
  95. package/dist/commands/notes.js +33 -55
  96. package/dist/commands/onboard-flows.js +69 -51
  97. package/dist/commands/onboard.js +11 -9
  98. package/dist/commands/ops-render-memory.js +10 -7
  99. package/dist/commands/ops-render.js +33 -30
  100. package/dist/commands/ops.js +3 -0
  101. package/dist/commands/public-root.js +1 -1
  102. package/dist/commands/session-sync-outside-roots.js +40 -36
  103. package/dist/commands/session-sync-plan.js +14 -10
  104. package/dist/commands/session-sync-upload.js +24 -22
  105. package/dist/commands/session-sync.js +19 -8
  106. package/dist/commands/setup.js +13 -0
  107. package/dist/commands/slack.js +25 -16
  108. package/dist/commands/sources-check.js +13 -7
  109. package/dist/commands/sources-discovery.js +25 -17
  110. package/dist/commands/sources-verdict.js +19 -18
  111. package/dist/commands/speed.js +23 -19
  112. package/dist/commands/start.js +20 -16
  113. package/dist/commands/sync-doctor.js +52 -48
  114. package/dist/commands/sync.js +22 -16
  115. package/dist/commands/usage-telemetry-toml.js +71 -45
  116. package/dist/commands/usage.js +94 -68
  117. package/dist/commands/workbook-render.js +10 -7
  118. package/dist/evidence-reconcile-client.js +75 -64
  119. package/dist/evidence-redelivery-plan.js +37 -34
  120. package/dist/evidence-redelivery.js +32 -29
  121. package/dist/evidence-transcripts-client.js +20 -20
  122. package/dist/evidence-upload-object.js +86 -89
  123. package/dist/evidence-upload-plan.js +94 -83
  124. package/dist/evidence-upload-terminal.js +45 -50
  125. package/dist/image-description-session.js +156 -159
  126. package/dist/local-state-pairing-code.js +39 -31
  127. package/dist/local-state-status.js +9 -2
  128. package/dist/onboarding-roots.js +5 -8
  129. package/dist/process-runner.js +8 -8
  130. package/dist/raw-evidence-gc.js +33 -38
  131. package/dist/raw-evidence-stuck-summary.js +7 -14
  132. package/dist/repo-identity.js +26 -23
  133. package/dist/scheduled-self-update.js +11 -15
  134. package/dist/second-install.js +3 -0
  135. package/dist/slim/codex-rules.js +23 -36
  136. package/dist/spool/local-spool-parse.js +13 -12
  137. package/dist/sync-lock.js +5 -15
  138. package/dist/tower-client.js +36 -53
  139. package/dist/tower-stream.js +7 -24
  140. package/dist/upload-agent-artifacts.js +58 -64
  141. package/dist/upload-envelope-build.js +60 -59
  142. package/dist/upload-evidence-delivery-reconcile.js +58 -56
  143. package/dist/upload-evidence-delivery-summary.js +32 -34
  144. package/dist/upload-ingest-receipt.js +20 -23
  145. package/dist/upload-session-reports-queue.js +4 -1
  146. package/dist/upload-session-reports-wire.js +64 -68
  147. package/dist/upload-sync.js +171 -157
  148. package/package.json +4 -4
@@ -20,397 +20,398 @@ import { DEFAULT_DASHBOARD_URL } from "../local-state.js";
20
20
  import { localCommandHelp, SURFACE_ALIASES } from "./local-help.js";
21
21
  import { TOWER_COMMAND_HELP } from "./local-help-commands-tower.js";
22
22
  import { TOWER_OPS_COMMAND_HELP } from "./local-help-commands-tower-ops.js";
23
- export function localSubcommandHelp(command) {
24
- const helpByCommand = new Map([
25
- ["glossary", ["Usage: cockpit glossary list|add <wrong> --to <name>|remove <wrong> [--json]", "Quote phrases. Removing a form prevents future corrections of it."]],
26
- ["spend", ["Usage: cockpit spend memory [--days 1|7|30] [--dashboard-url <url>] [--json]", "Spend by memory operation (write, recall, dream, update_forget, backfill, label, exam, predictor, people, who, intentions, salience, chat, other), ranked top first with list and real dollars, share, trend against the previous window, and how much of the real OpenAI bill the ledger explains. What it does not explain is shown as untagged. A super_admin reads it."]],
27
- ["roots", ["Usage: cockpit roots add <dir> [--allow-home-root] [--json]", "Approves a work directory, saves an approval receipt, and adds it to collection. Run cockpit doctor afterward."]],
28
- // BLI-3709: the Tower nouns live next door, split along the same seam the
29
- // argument parsers already use — see `local-help-commands-tower.ts`.
30
- ...TOWER_COMMAND_HELP,
31
- ["setup", ["Usage: cockpit setup [--since <7d|30d|date>] [--details] [--person <name|email>] [--compare <name,name>] [--json]", "Read agent setups beside windowed outcomes (default 30 days), or compare two people by first name or email."]],
23
+ /** One manual per collector command; the Tower nouns are spread in from their own file. */
24
+ const COMMAND_HELP = new Map([
25
+ ["glossary", ["Usage: cockpit glossary list|add <wrong> --to <name>|remove <wrong> [--json]", "Quote phrases. Removing a form prevents future corrections of it."]],
26
+ ["spend", ["Usage: cockpit spend memory [--days 1|7|30] [--dashboard-url <url>] [--json]", "Spend by memory operation (write, recall, dream, update_forget, backfill, label, exam, predictor, people, who, intentions, salience, chat, other), ranked top first with list and real dollars, share, trend against the previous window, and how much of the real OpenAI bill the ledger explains. What it does not explain is shown as untagged. A super_admin reads it."]],
27
+ ["roots", ["Usage: cockpit roots add <dir> [--allow-home-root] [--json]", "Approves a work directory, saves an approval receipt, and adds it to collection. Run cockpit doctor afterward."]],
28
+ // BLI-3709: the Tower nouns live next door, split along the same seam the
29
+ // argument parsers already use — see `local-help-commands-tower.ts`.
30
+ ...TOWER_COMMAND_HELP,
31
+ ["setup", ["Usage: cockpit setup [--since <duration|date>] [--until <date>] [--machines] [--details] [--person <name|email>] [--compare <name,name>] [--json]", "Read agent setups beside windowed outcomes (default 30 days), or compare two people by first name or email."]],
32
+ [
33
+ "onboard",
32
34
  [
33
- "onboard",
34
- [
35
- "Usage: cockpit onboard [--ticket <id>] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--workspace <path>] [--allow-home-root] [--branch <name>] [--no-auth] [--max-depth <n>] [--max-repos <n>] [--json]",
36
- "",
37
- "Installs, pairs, starts work context(s), syncs once, completes all-history",
38
- "Codex and Claude backfill for the saved roots, and then tells you it is working.",
39
- "If --workspace is a parent folder, scans child git repos/worktrees and rolls them up by repo.",
40
- "`--repo <path>` remains supported as a backward-compatible alias.",
41
- `Omit --dashboard-url for normal production setup (${DEFAULT_DASHBOARD_URL}).`,
42
- "Pass --dashboard-url only for staging/custom dashboards or to force a different pairing.",
43
- "Run with no flags in a terminal and it prompts for the dashboard email and OTP code; pass --email to skip the email prompt. Use --no-auth to force the manual approval fallback.",
44
- "Interactive runs also offer to add Tower ticket-binding rules to AGENTS.md and CLAUDE.md after readiness proof.",
45
- ],
35
+ "Usage: cockpit onboard [--ticket <id>] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--workspace <path>] [--allow-home-root] [--branch <name>] [--no-auth] [--max-depth <n>] [--max-repos <n>] [--json]",
36
+ "",
37
+ "Installs, pairs, starts work context(s), syncs once, completes all-history",
38
+ "Codex and Claude backfill for the saved roots, and then tells you it is working.",
39
+ "If --workspace is a parent folder, scans child git repos/worktrees and rolls them up by repo.",
40
+ "`--repo <path>` remains supported as a backward-compatible alias.",
41
+ `Omit --dashboard-url for normal production setup (${DEFAULT_DASHBOARD_URL}).`,
42
+ "Pass --dashboard-url only for staging/custom dashboards or to force a different pairing.",
43
+ "Run with no flags in a terminal and it prompts for the dashboard email and OTP code; pass --email to skip the email prompt. Use --no-auth to force the manual approval fallback.",
44
+ "Interactive runs also offer to add Tower ticket-binding rules to AGENTS.md and CLAUDE.md after readiness proof.",
46
45
  ],
46
+ ],
47
+ [
48
+ "install",
47
49
  [
48
- "install",
49
- [
50
- "Usage: cockpit install [--dashboard-url <url>] [--workspace <path>] [--allow-home-root] [--json]",
51
- "",
52
- "Writes local collector config. Pair with `cockpit login`, then run `cockpit start` when work begins.",
53
- "`--repo <path>` remains supported as a backward-compatible alias.",
54
- "Omit --dashboard-url for the production dashboard; pass it only for staging/custom dashboards.",
55
- ],
50
+ "Usage: cockpit install [--dashboard-url <url>] [--workspace <path>] [--allow-home-root] [--json]",
51
+ "",
52
+ "Writes local collector config. Pair with `cockpit login`, then run `cockpit start` when work begins.",
53
+ "`--repo <path>` remains supported as a backward-compatible alias.",
54
+ "Omit --dashboard-url for the production dashboard; pass it only for staging/custom dashboards.",
56
55
  ],
56
+ ],
57
+ [
58
+ "update",
57
59
  [
58
- "update",
59
- [
60
- "Usage: cockpit update [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--workspace <path>] [--allow-home-root] [--no-auth] [--json]",
61
- "",
62
- "Updates the global public CLI from npm, then reruns `cockpit onboard`",
63
- "with the same setup flags so pairing, saved roots, all-history backfill,",
64
- "agent rules, autostart, and the initial sync are refreshed in one command.",
65
- "`cockpit upgrade` is an alias.",
66
- ],
60
+ "Usage: cockpit update [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--workspace <path>] [--allow-home-root] [--no-auth] [--json]",
61
+ "",
62
+ "Updates the global public CLI from npm, then reruns `cockpit onboard`",
63
+ "with the same setup flags so pairing, saved roots, all-history backfill,",
64
+ "agent rules, autostart, and the initial sync are refreshed in one command.",
65
+ "`cockpit upgrade` is an alias.",
67
66
  ],
67
+ ],
68
+ [
69
+ "upgrade",
68
70
  [
69
- "upgrade",
70
- [
71
- "Usage: cockpit upgrade [same flags as cockpit update]",
72
- "",
73
- "Alias for `cockpit update`.",
74
- ],
71
+ "Usage: cockpit upgrade [same flags as cockpit update]",
72
+ "",
73
+ "Alias for `cockpit update`.",
75
74
  ],
75
+ ],
76
+ [
77
+ "do-everything",
76
78
  [
77
- "do-everything",
78
- [
79
- "Usage: cockpit do-everything [same flags as cockpit doctor]",
80
- "Same command as `cockpit doctor`.",
81
- ],
79
+ "Usage: cockpit do-everything [same flags as cockpit doctor]",
80
+ "Same command as `cockpit doctor`.",
82
81
  ],
82
+ ],
83
+ [
84
+ "fix",
83
85
  [
84
- "fix",
85
- [
86
- "Usage: cockpit fix [same flags as cockpit doctor]",
87
- "Same command as `cockpit doctor`.",
88
- ],
86
+ "Usage: cockpit fix [same flags as cockpit doctor]",
87
+ "Same command as `cockpit doctor`.",
89
88
  ],
89
+ ],
90
+ [
91
+ "doctor",
90
92
  [
91
- "doctor",
92
- [
93
- "Usage: cockpit doctor [--workspace <path>] [--check | --no-repair] [--no-usage-telemetry] [--lock-wait <seconds>] [--backfill-budget <seconds>] [--json]",
94
- "",
95
- "Diagnose, repair, and verify this machine.",
96
- "Repairs CLI, background sync, sign-in, roots, memory and hooks, agent rules, catch-up, uploads, and cleanup.",
97
- "roots-cover-work is informational: it names how many sessions are inside vs. outside saved roots (all already uploaded, outside ones labelled) and gives cockpit roots add commands for attributing a folder's sessions to a repo (outside-root transcripts upload either way). It never needs a fix.",
98
- "--no-usage-telemetry switches off Claude Code and Codex usage export, including later doctor runs.",
99
- "--check or --no-repair diagnoses without repairs. --dry-run previews repairs.",
100
- "--backfill-budget defaults to 900 seconds; catch-up repeats chunks until complete, with progress every 30 seconds.",
101
- "Doctor never waits for the background sync: a running sync is reported as running (with how long ago it started) and doctor finishes; a sync that stopped responding or made no progress for 15 minutes is ended and doctor carries on. --lock-wait is accepted and changes nothing. Progress prints at most every 30 seconds and says what changed.",
102
- "--json without either flag answers within 45 seconds; a repair that does not fit reads doctor_budget_spent.",
103
- "--json includes steps, repairs, and needs_person. Exit 0 means nothing needs you.",
104
- "Maintainers: --update-tag next keeps self-update on the prerelease candidate.",
105
- ],
93
+ "Usage: cockpit doctor [--workspace <path>] [--check | --no-repair] [--no-usage-telemetry] [--lock-wait <seconds>] [--backfill-budget <seconds>] [--json]",
94
+ "",
95
+ "Diagnose, repair, and verify this machine.",
96
+ "Repairs CLI, background sync, sign-in, roots, memory and hooks, agent rules, catch-up, uploads, and cleanup.",
97
+ "roots-cover-work is informational: it names how many sessions are inside vs. outside saved roots (all already uploaded, outside ones labelled) and gives cockpit roots add commands for attributing a folder's sessions to a repo (outside-root transcripts upload either way). It never needs a fix.",
98
+ "--no-usage-telemetry switches off Claude Code and Codex usage export, including later doctor runs.",
99
+ "--check or --no-repair diagnoses without repairs. --dry-run previews repairs.",
100
+ "--backfill-budget defaults to 900 seconds; catch-up repeats chunks until complete, with progress every 30 seconds.",
101
+ "Doctor never waits for the background sync: a running sync is reported as running (with how long ago it started) and doctor finishes; a sync that stopped responding or made no progress for 15 minutes is ended and doctor carries on. --lock-wait is accepted and changes nothing. Progress prints at most every 30 seconds and says what changed.",
102
+ "--json without either flag answers within 45 seconds; a repair that does not fit reads doctor_budget_spent.",
103
+ "--json includes steps, repairs, and needs_person. Exit 0 means nothing needs you.",
104
+ "Maintainers: --update-tag next keeps self-update on the prerelease candidate.",
106
105
  ],
106
+ ],
107
+ [
108
+ "login",
107
109
  [
108
- "login",
109
- [
110
- "Usage: cockpit login [--pair <code>] [--no-browser] [--legacy-pair] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--no-auth] [--json]",
111
- "",
112
- "One sign-in. Prints and opens a Tower link; signing in there once both signs the browser in",
113
- "and connects this machine. Then stores the approved local session.",
114
- "",
115
- "--pair <code> Redeem a code from Tower Settings -> Devices. No email at all.",
116
- "--no-browser Print the link, do not open a window (SSH, locked-down hosts).",
117
- "--legacy-pair Use the older two-sign-in flow: email code here, then approve in the browser.",
118
- " It also runs automatically if the link flow cannot finish.",
119
- "Omit --dashboard-url for the production dashboard; pass it only for staging/custom dashboards.",
120
- ],
110
+ "Usage: cockpit login [--pair <code>] [--no-browser] [--legacy-pair] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--no-auth] [--json]",
111
+ "",
112
+ "One sign-in. Prints and opens a Tower link; signing in there once both signs the browser in",
113
+ "and connects this machine. Then stores the approved local session.",
114
+ "",
115
+ "--pair <code> Redeem a code from Tower Settings -> Devices. No email at all.",
116
+ "--no-browser Print the link, do not open a window (SSH, locked-down hosts).",
117
+ "--legacy-pair Use the older two-sign-in flow: email code here, then approve in the browser.",
118
+ " It also runs automatically if the link flow cannot finish.",
119
+ "Omit --dashboard-url for the production dashboard; pass it only for staging/custom dashboards.",
121
120
  ],
121
+ ],
122
+ [
123
+ "pair",
122
124
  [
123
- "pair",
124
- [
125
- "Usage: cockpit pair [--pair <code>] [--no-browser] [--legacy-pair] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--no-auth] [--json]",
126
- "",
127
- "Alias for `cockpit login`.",
128
- ],
125
+ "Usage: cockpit pair [--pair <code>] [--no-browser] [--legacy-pair] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--no-auth] [--json]",
126
+ "",
127
+ "Alias for `cockpit login`.",
129
128
  ],
129
+ ],
130
+ [
131
+ "logout",
130
132
  [
131
- "logout",
132
- [
133
- "Usage: cockpit logout [--revoke] [--yes] [--dashboard-url <url>] [--json]",
134
- "",
135
- "Removes the local device session.",
136
- "--revoke also asks Tower to end this device's token, which is what you want",
137
- "when the machine is being handed back: without it this laptop stops collecting",
138
- "but the token it held is still one the server would honour.",
139
- "A device can only revoke ITSELF; revoking someone else's machine stays in the browser.",
140
- "The local session is removed either way, and the two outcomes are reported separately.",
141
- ],
133
+ "Usage: cockpit logout [--revoke] [--yes] [--dashboard-url <url>] [--json]",
134
+ "",
135
+ "Removes the local device session.",
136
+ "--revoke also asks Tower to end this device's token, which is what you want",
137
+ "when the machine is being handed back: without it this laptop stops collecting",
138
+ "but the token it held is still one the server would honour.",
139
+ "A device can only revoke ITSELF; revoking someone else's machine stays in the browser.",
140
+ "The local session is removed either way, and the two outcomes are reported separately.",
142
141
  ],
142
+ ],
143
+ [
144
+ "model",
143
145
  [
144
- "model",
145
- [
146
- "Usage: cockpit model [show|set <provider:model>] [--json]",
147
- "",
148
- "Shows or changes YOUR chat model — the short way to say",
149
- "`cockpit settings personal --chat-model`. Affects your account, not the org.",
150
- "An unrecognised key is refused by the dashboard, not by this command.",
151
- ],
146
+ "Usage: cockpit model [show|set <provider:model>] [--json]",
147
+ "",
148
+ "Shows or changes YOUR chat model — the short way to say",
149
+ "`cockpit settings personal --chat-model`. Affects your account, not the org.",
150
+ "An unrecognised key is refused by the dashboard, not by this command.",
152
151
  ],
152
+ ],
153
+ [
154
+ "settings",
153
155
  [
154
- "settings",
155
- [
156
- "Usage: cockpit settings [section] [verb] [flags] [--json]",
157
- "",
158
- "With no section it shows everything you can see; a section you cannot see reads",
159
- "`admin only` rather than failing, because that is the system working.",
160
- "",
161
- " cockpit settings personal [--chat-model <key>] [--brief-model <key>]",
162
- " Your teams and your two model choices. No flags = show.",
163
- " cockpit settings switches [set <key> <value>]",
164
- " Access and feature switches. Everyone may look; only an admin may set.",
165
- " cockpit settings models [set --chat <key>] [--memory <id>] [--note-reader <id>]",
166
- " The ORG-WIDE model map. Admin only, in both directions.",
167
- " cockpit settings cli-floor [<version>]",
168
- " The fleet forced-update floor: every collector below it updates on its",
169
- " next sync tick. Everyone may look; only an admin may raise it, and it",
170
- " only ever goes UP — lowering it is a rollback a human makes deliberately.",
171
- " A `--tag latest` publish raises it for you (scripts/publish-public-packages.mjs).",
172
- " cockpit settings env list",
173
- " Stored env files: project, name, when, id. Never a value — the server",
174
- " cannot return one and this command has no flag that prints one.",
175
- " cockpit settings env set --project <project> --file <name> --content-stdin",
176
- " Pipe the file in; there is no --content flag, because a secret on a",
177
- " command line lands in shell history and in every process listing.",
178
- " macOS: cat <path> | cockpit settings env set --project <project> --file <name> --content-stdin",
179
- " PowerShell: Get-Content <path> -Raw | cockpit settings env set --project <project> --file <name> --content-stdin",
180
- " Run `cockpit settings env list` to see which file names this project accepts.",
181
- " cockpit settings env delete --id <uuid> [--yes]",
182
- " Asks first unless --yes; a headless run without --yes is refused, not assumed.",
183
- ],
156
+ "Usage: cockpit settings [section] [verb] [flags] [--json]",
157
+ "",
158
+ "With no section it shows everything you can see; a section you cannot see reads",
159
+ "`admin only` rather than failing, because that is the system working.",
160
+ "",
161
+ " cockpit settings personal [--chat-model <key>] [--brief-model <key>]",
162
+ " Your teams and your two model choices. No flags = show.",
163
+ " cockpit settings switches [set <key> <value>]",
164
+ " Access and feature switches. Everyone may look; only an admin may set.",
165
+ " cockpit settings models [set --chat <key>] [--memory <id>] [--note-reader <id>]",
166
+ " The ORG-WIDE model map. Admin only, in both directions.",
167
+ " cockpit settings cli-floor [<version>]",
168
+ " The fleet forced-update floor: every collector below it updates on its",
169
+ " next sync tick. Everyone may look; only an admin may raise it, and it",
170
+ " only ever goes UP — lowering it is a rollback a human makes deliberately.",
171
+ " A `--tag latest` publish raises it for you (scripts/publish-public-packages.mjs).",
172
+ " cockpit settings env list",
173
+ " Stored env files: project, name, when, id. Never a value — the server",
174
+ " cannot return one and this command has no flag that prints one.",
175
+ " cockpit settings env set --project <project> --file <name> --content-stdin",
176
+ " Pipe the file in; there is no --content flag, because a secret on a",
177
+ " command line lands in shell history and in every process listing.",
178
+ " macOS: cat <path> | cockpit settings env set --project <project> --file <name> --content-stdin",
179
+ " PowerShell: Get-Content <path> -Raw | cockpit settings env set --project <project> --file <name> --content-stdin",
180
+ " Run `cockpit settings env list` to see which file names this project accepts.",
181
+ " cockpit settings env delete --id <uuid> [--yes]",
182
+ " Asks first unless --yes; a headless run without --yes is refused, not assumed.",
184
183
  ],
184
+ ],
185
+ [
186
+ "team",
185
187
  [
186
- "team",
187
- [
188
- "Usage: cockpit team [members | invite <email> --role <role> | role <userId> --role <role> | grant|revoke <person> careers [see|act] | device [list] | device revoke <id|name> --reason <label>] [--json]",
189
- "",
190
- " cockpit team [members]",
191
- " Everyone on your team — roster and accounts together, with each person's id.",
192
- " Open to every role; it says so when the view is read-only for you.",
193
- " cockpit team github-login add|remove <person> <login> [--json] — exact roster UUID, name or email; super admin or a member managing their own extra logins. History stays.",
194
- " cockpit team github-login list <person> [--json] — primary and extra GitHub logins.",
195
- " cockpit team timezone set <person> <iana-zone> [--json] — super admin only. Sets the zone a person lives their day in, e.g. Asia/Ho_Chi_Minh or America/Vancouver; the person is an exact roster name, email or roster UUID. The word `unknown` clears it. EST, +07:00 and other non-IANA names are refused.",
196
- " cockpit team timezone list [--json] — super admin only. Everyone on the roster with their zone; `unknown` means nobody set one (readers then use UTC and say so).",
197
- " cockpit team invite <email> --role <role> [--team-id <uuid>]",
198
- " Admin only. Defaults to your own team; Tower emails them a sign-in link.",
199
- " cockpit team role <userId> --role <role> [--yes]",
200
- " Admin only. Asks first unless --yes. You cannot change your own role.",
201
- " cockpit team grant <person-uuid> careers [see|act] [--json]",
202
- " cockpit team revoke <person-uuid> careers [see|act] [--json]",
203
- " Super admins manage separate See and Act grants. Default level: see.",
204
- " Find the account uuid with cockpit team members --json. Revocation retains history.",
205
- " cockpit team device [list] [--json]",
206
- " cockpit team device doctor <id|name> [--json]",
207
- " Every paired collector device: name, id, trust state, owner, and why",
208
- " (revoked reason, or when it was approved, or that it's still waiting).",
209
- " Admin only.",
210
- " cockpit team device scope <id|name> notetaker_bot|none [--json]",
211
- " Super admin only. Gives the meeting bot's device the scope Tower's claim door requires,",
212
- " or takes it away. Without it the bot is refused every meeting (bot_scope_required).",
213
- " cockpit team device revoke <id|name> --reason <label> [--note \"<text>\"] [--yes]",
214
- " Admin only. Names the device, asks first unless --yes, then revokes it —",
215
- " this cannot be undone. --reason must be one of: stale_test_pairing,",
216
- " machine_retired, person_left, re_pairing, other.",
217
- ],
188
+ "Usage: cockpit team [members | invite <email> --role <role> | role <userId> --role <role> | grant|revoke <person> careers [see|act] | device [list] | device revoke <id|name> --reason <label>] [--json]",
189
+ "",
190
+ " cockpit team [members]",
191
+ " Everyone on your team — roster and accounts together, with each person's id.",
192
+ " Open to every role; it says so when the view is read-only for you.",
193
+ " cockpit team github-login add|remove <person> <login> [--json] — exact roster UUID, name or email; super admin or a member managing their own extra logins. History stays.",
194
+ " cockpit team github-login list <person> [--json] — primary and extra GitHub logins.",
195
+ " cockpit team timezone set <person> <iana-zone> [--json] — super admin only. Sets the zone a person lives their day in, e.g. Asia/Ho_Chi_Minh or America/Vancouver; the person is an exact roster name, email or roster UUID. The word `unknown` clears it. EST, +07:00 and other non-IANA names are refused.",
196
+ " cockpit team timezone list [--json] — super admin only. Everyone on the roster with their zone; `unknown` means nobody set one (readers then use UTC and say so).",
197
+ " cockpit team invite <email> --role <role> [--team-id <uuid>]",
198
+ " Admin only. Defaults to your own team; Tower emails them a sign-in link.",
199
+ " cockpit team role <userId> --role <role> [--yes]",
200
+ " Admin only. Asks first unless --yes. You cannot change your own role.",
201
+ " cockpit team grant <person-uuid> careers [see|act] [--json]",
202
+ " cockpit team revoke <person-uuid> careers [see|act] [--json]",
203
+ " Super admins manage separate See and Act grants. Default level: see.",
204
+ " Find the account uuid with cockpit team members --json. Revocation retains history.",
205
+ " cockpit team device [list] [--json]",
206
+ " cockpit team device doctor <id|name> [--json]",
207
+ " Every paired collector device: name, id, trust state, owner, and why",
208
+ " (revoked reason, or when it was approved, or that it's still waiting).",
209
+ " Admin only.",
210
+ " cockpit team device scope <id|name> notetaker_bot|none [--json]",
211
+ " Super admin only. Gives the meeting bot's device the scope Tower's claim door requires,",
212
+ " or takes it away. Without it the bot is refused every meeting (bot_scope_required).",
213
+ " cockpit team device revoke <id|name> --reason <label> [--note \"<text>\"] [--yes]",
214
+ " Admin only. Names the device, asks first unless --yes, then revokes it —",
215
+ " this cannot be undone. --reason must be one of: stale_test_pairing,",
216
+ " machine_retired, person_left, re_pairing, other.",
218
217
  ],
218
+ ],
219
+ [
220
+ "start",
219
221
  [
220
- "start",
221
- [
222
- "Usage: cockpit start [--ticket <id>|--clear-ticket] [--topic <label>] [--topic-summary <summary>] [--intent <intent>] [--phase <phase>] [--intent-confidence <0..1>] [--workspace <path>] [--branch <name>] [--json]",
223
- "",
224
- "Starts collecting your work in the background. If you point it at a parent folder it covers every repo inside.",
225
- "Add --ticket only when the work already has a visible ticket; omit it to preserve an existing binding.",
226
- "--ticket takes EITHER tracker's id while both are running: a Tower issue (BLI-10000 and up, `cockpit issue list`)",
227
- "or a Linear ticket. Tower is asked which row the id names, and the context records both ids when a row proves the pair —",
228
- "a Tower-native issue whose title ends in `[BLI-3779]` mirrors that Linear ticket. An id Tower cannot place still binds:",
229
- "the reason is printed, and the session is never held up by a tracker lookup.",
230
- "Use --clear-ticket to go back to collecting general work with no ticket attached.",
231
- "Use --topic/--intent/--phase for planning, discovery, and learning work that has no ticket yet.",
232
- "Supported intents: implementation, bug_fix, root_cause_analysis, planning, discovery, review, testing, documentation, release, learning, coordination, maintenance, analysis, unknown, other.",
233
- "Supported phases: planning, discovery, implementation, debugging, review, testing, documentation, release, handoff, analysis, unknown, other.",
234
- "`--repo <path>` remains supported as a backward-compatible alias; use --workspace in agent guidance.",
235
- ],
222
+ "Usage: cockpit start [--ticket <id>|--clear-ticket] [--topic <label>] [--topic-summary <summary>] [--intent <intent>] [--phase <phase>] [--intent-confidence <0..1>] [--workspace <path>] [--branch <name>] [--json]",
223
+ "",
224
+ "Starts collecting your work in the background. If you point it at a parent folder it covers every repo inside.",
225
+ "Add --ticket only when the work already has a visible ticket; omit it to preserve an existing binding.",
226
+ "--ticket takes EITHER tracker's id while both are running: a Tower issue (BLI-10000 and up, `cockpit issue list`)",
227
+ "or a Linear ticket. Tower is asked which row the id names, and the context records both ids when a row proves the pair —",
228
+ "a Tower-native issue whose title ends in `[BLI-3779]` mirrors that Linear ticket. An id Tower cannot place still binds:",
229
+ "the reason is printed, and the session is never held up by a tracker lookup.",
230
+ "Use --clear-ticket to go back to collecting general work with no ticket attached.",
231
+ "Use --topic/--intent/--phase for planning, discovery, and learning work that has no ticket yet.",
232
+ "Supported intents: implementation, bug_fix, root_cause_analysis, planning, discovery, review, testing, documentation, release, learning, coordination, maintenance, analysis, unknown, other.",
233
+ "Supported phases: planning, discovery, implementation, debugging, review, testing, documentation, release, handoff, analysis, unknown, other.",
234
+ "`--repo <path>` remains supported as a backward-compatible alias; use --workspace in agent guidance.",
236
235
  ],
236
+ ],
237
+ [
238
+ "sync",
237
239
  [
238
- "sync",
239
- [
240
- "Usage: cockpit sync [--workspace <path>] [--dashboard-url <url>] [--json]",
241
- "",
242
- "Uploads your latest collected work. If it cannot reach Tower it saves a retry and tries again later.",
243
- "Omit --dashboard-url for normal production sync; pass it only for staging/custom dashboards or forced re-pairing.",
244
- "`--repo <path>` remains supported as a backward-compatible alias.",
245
- "Parent folders sync each child git worktree; Codex AND Claude Code JSONL",
246
- "transcripts (and Claude subagent sidecars) are attributed to repos",
247
- "deterministically and ambiguous transcripts are retained as unattributed",
248
- "instead of being duplicated across repos. Use `cockpit sessions` to see why",
249
- "a session is or is not collected.",
250
- "New repos start being collected automatically, with no ticket attached.",
251
- "Discovery scans 3 folder levels and up to 50 repos by default; tune with",
252
- "--max-depth and --max-repos.",
253
- "Also self-updates the CLI from npm latest once per day, strictly after",
254
- "collection finishes; set COCKPIT_DISABLE_AUTO_UPDATE=1 to freeze the",
255
- "installed version during incident triage.",
256
- ],
240
+ "Usage: cockpit sync [--workspace <path>] [--dashboard-url <url>] [--json]",
241
+ "",
242
+ "Uploads your latest collected work. If it cannot reach Tower it saves a retry and tries again later.",
243
+ "Omit --dashboard-url for normal production sync; pass it only for staging/custom dashboards or forced re-pairing.",
244
+ "`--repo <path>` remains supported as a backward-compatible alias.",
245
+ "Parent folders sync each child git worktree; Codex AND Claude Code JSONL",
246
+ "transcripts (and Claude subagent sidecars) are attributed to repos",
247
+ "deterministically and ambiguous transcripts are retained as unattributed",
248
+ "instead of being duplicated across repos. Use `cockpit sessions` to see why",
249
+ "a session is or is not collected.",
250
+ "New repos start being collected automatically, with no ticket attached.",
251
+ "Discovery scans 3 folder levels and up to 50 repos by default; tune with",
252
+ "--max-depth and --max-repos.",
253
+ "Also self-updates the CLI from npm latest once per day, strictly after",
254
+ "collection finishes; set COCKPIT_DISABLE_AUTO_UPDATE=1 to freeze the",
255
+ "installed version during incident triage.",
257
256
  ],
257
+ ],
258
+ [
259
+ "analyze",
258
260
  [
259
- "analyze",
260
- [
261
- "Usage: cockpit analyze [--workspace <path>] [--dashboard-url <url>] [--json]",
262
- "",
263
- "Uploads your latest collected work, then asks Tower to analyse it.",
264
- "The command returns after the batch is queued; view status and results in My Work.",
265
- "Omit --dashboard-url for production; pass it only for staging/custom dashboards.",
266
- "`--repo <path>` remains supported as a backward-compatible alias.",
267
- ],
261
+ "Usage: cockpit analyze [--workspace <path>] [--dashboard-url <url>] [--json]",
262
+ "",
263
+ "Uploads your latest collected work, then asks Tower to analyse it.",
264
+ "The command returns after the batch is queued; view status and results in My Work.",
265
+ "Omit --dashboard-url for production; pass it only for staging/custom dashboards.",
266
+ "`--repo <path>` remains supported as a backward-compatible alias.",
268
267
  ],
269
- // BLI-10445: JARVIS, models, Scout and ops live in `local-help-commands-tower-ops.ts`;
270
- // slack, workbook, brief, notes and memory joined `local-help-commands-tower.ts`.
271
- ...TOWER_OPS_COMMAND_HELP,
268
+ ],
269
+ // BLI-10445: JARVIS, models, Scout and ops live in `local-help-commands-tower-ops.ts`;
270
+ // slack, workbook, brief, notes and memory joined `local-help-commands-tower.ts`.
271
+ ...TOWER_OPS_COMMAND_HELP,
272
+ [
273
+ "correct",
272
274
  [
273
- "correct",
274
- [
275
- "Usage: cockpit correct --claim <claimId> --text \"<what is wrong>\" [--for <person>] [--version <pageId>] [--supersedes <id>] [--dashboard-url <url>] [--json]",
276
- "",
277
- "Tells Tower that one line on the page is wrong. Same door the website's correction form uses.",
278
- "Get the claim id from `cockpit brief --claims`; an id the page does not carry is refused before anything is written.",
279
- "--text may be omitted when the correction is piped in on stdin.",
280
- "The claim is checked against the live record FIRST. If the record disagrees, JARVIS says so and the correction is still filed with that outcome on it.",
281
- "--supersedes <correctionId> takes an earlier correction back; nothing is ever edited or deleted.",
282
- ],
275
+ "Usage: cockpit correct --claim <claimId> --text \"<what is wrong>\" [--for <person>] [--version <pageId>] [--supersedes <id>] [--dashboard-url <url>] [--json]",
276
+ "",
277
+ "Tells Tower that one line on the page is wrong. Same door the website's correction form uses.",
278
+ "Get the claim id from `cockpit brief --claims`; an id the page does not carry is refused before anything is written.",
279
+ "--text may be omitted when the correction is piped in on stdin.",
280
+ "The claim is checked against the live record FIRST. If the record disagrees, JARVIS says so and the correction is still filed with that outcome on it.",
281
+ "--supersedes <correctionId> takes an earlier correction back; nothing is ever edited or deleted.",
283
282
  ],
283
+ ],
284
+ [
285
+ "backfill",
284
286
  [
285
- "backfill",
286
- [
287
- "Usage: cockpit backfill (--since-days <n>|--all) [--source codex|claude] [--dry-run] [--max-files <n>] [--max-depth <n>] [--max-repos <n>] [--lock-wait <seconds>] [--yes] [--workspace <path>] [--json]",
288
- "",
289
- "Backfills historical Codex and Claude Code session evidence using the saved collection roots from local config when --workspace is omitted.",
290
- "Omit --source to scan both sources; there is no --source all literal.",
291
- "The non-all window is capped at the collector session paired_at timestamp.",
292
- "--all requires a dry-run review and TTY confirmation; pass --yes for headless agent runs.",
293
- "Repo discovery scans 3 folder levels and up to 50 repos by default.",
294
- "Raise --max-depth or --max-repos when a partial result reports a discovery cap.",
295
- "--dry-run validates the paired collector and dashboard reachability, prints the same summary tables, and writes nothing.",
296
- "Sessions outside every saved root upload too, labelled outside; only an explicit opt-out withholds a session.",
297
- "When the scheduled sync holds the collection lock, backfill waits up to --lock-wait seconds (default 600) and exits 1 with sync_lock_held if it never frees.",
298
- ],
287
+ "Usage: cockpit backfill (--since-days <n>|--all) [--source codex|claude] [--dry-run] [--max-files <n>] [--max-depth <n>] [--max-repos <n>] [--lock-wait <seconds>] [--yes] [--workspace <path>] [--json]",
288
+ "",
289
+ "Backfills historical Codex and Claude Code session evidence using the saved collection roots from local config when --workspace is omitted.",
290
+ "Omit --source to scan both sources; there is no --source all literal.",
291
+ "The non-all window is capped at the collector session paired_at timestamp.",
292
+ "--all requires a dry-run review and TTY confirmation; pass --yes for headless agent runs.",
293
+ "Repo discovery scans 3 folder levels and up to 50 repos by default.",
294
+ "Raise --max-depth or --max-repos when a partial result reports a discovery cap.",
295
+ "--dry-run validates the paired collector and dashboard reachability, prints the same summary tables, and writes nothing.",
296
+ "Sessions outside every saved root upload too, labelled outside; only an explicit opt-out withholds a session.",
297
+ "When the scheduled sync holds the collection lock, backfill waits up to --lock-wait seconds (default 600) and exits 1 with sync_lock_held if it never frees.",
299
298
  ],
299
+ ],
300
+ [
301
+ "status",
300
302
  [
301
- "status",
302
- [
303
- "Usage: cockpit status [--workspace <path>] [--json]",
304
- "",
305
- "Prints install, pairing, active work, upload, and retry state.",
306
- "`--repo <path>` remains supported as a backward-compatible alias.",
307
- ],
303
+ "Usage: cockpit status [--workspace <path>] [--json]",
304
+ "",
305
+ "Prints install, pairing, active work, upload, and retry state.",
306
+ "`--repo <path>` remains supported as a backward-compatible alias.",
308
307
  ],
308
+ ],
309
+ [
310
+ "sessions",
309
311
  [
310
- "sessions",
311
- [
312
- "Usage: cockpit sessions [--source codex|claude] [--since-days <n>|--all] [--workspace <path>] [--json]",
313
- "",
314
- "Read-only: re-runs Codex + Claude session attribution and prints each",
315
- "session's id, source, state, reason, scores, signals, and per-sidecar",
316
- "skip reasons. No upload, no cursor writes. Answers \"why is session X",
317
- "missing?\" locally — counts and labels only, never paths or content.",
318
- "--since-days uses the same paired_at cap as `cockpit backfill`; --all scans the full local history.",
319
- "`--repo <path>` remains supported as a backward-compatible alias.",
320
- ],
312
+ "Usage: cockpit sessions [--source codex|claude] [--since-days <n>|--all] [--workspace <path>] [--json]",
313
+ "",
314
+ "Read-only: re-runs Codex + Claude session attribution and prints each",
315
+ "session's id, source, state, reason, scores, signals, and per-sidecar",
316
+ "skip reasons. No upload, no cursor writes. Answers \"why is session X",
317
+ "missing?\" locally — counts and labels only, never paths or content.",
318
+ "--since-days uses the same paired_at cap as `cockpit backfill`; --all scans the full local history.",
319
+ "`--repo <path>` remains supported as a backward-compatible alias.",
321
320
  ],
321
+ ],
322
+ [
323
+ "serve",
322
324
  [
323
- "serve",
324
- [
325
- "Usage: cockpit serve [--port <port>] [--workspace <path>]",
326
- "",
327
- "Starts the local collector HTTP status server.",
328
- "`--repo <path>` remains supported as a backward-compatible alias.",
329
- ],
325
+ "Usage: cockpit serve [--port <port>] [--workspace <path>]",
326
+ "",
327
+ "Starts the local collector HTTP status server.",
328
+ "`--repo <path>` remains supported as a backward-compatible alias.",
330
329
  ],
330
+ ],
331
+ [
332
+ "autostart",
331
333
  [
332
- "autostart",
333
- [
334
- "Usage: cockpit autostart [install|uninstall|status] [--workspace <path>] [--dashboard-url <url>] [--interval-seconds <n>] [--json]",
335
- "",
336
- "Installs background sync through launchd on Apple Silicon macOS or a",
337
- "per-user Task Scheduler task on native Windows.",
338
- "Runs `cockpit sync` every 15 min by default and survives reboots;",
339
- "the Windows task runs while the user is signed in.",
340
- "Action defaults to `install`. `--workspace` is the parent work folder to sync.",
341
- "`--repo <path>` remains supported as a backward-compatible alias.",
342
- "Omit --dashboard-url for production; pass it only for staging/custom dashboards.",
343
- "See docs/runbooks/cockpit-launchd-sync.md and",
344
- "docs/runbooks/cockpit-windows-task-scheduler-sync.md.",
345
- ],
334
+ "Usage: cockpit autostart [install|uninstall|status] [--workspace <path>] [--dashboard-url <url>] [--interval-seconds <n>] [--json]",
335
+ "",
336
+ "Installs background sync through launchd on Apple Silicon macOS or a",
337
+ "per-user Task Scheduler task on native Windows.",
338
+ "Runs `cockpit sync` every 15 min by default and survives reboots;",
339
+ "the Windows task runs while the user is signed in.",
340
+ "Action defaults to `install`. `--workspace` is the parent work folder to sync.",
341
+ "`--repo <path>` remains supported as a backward-compatible alias.",
342
+ "Omit --dashboard-url for production; pass it only for staging/custom dashboards.",
343
+ "See docs/runbooks/cockpit-launchd-sync.md and",
344
+ "docs/runbooks/cockpit-windows-task-scheduler-sync.md.",
346
345
  ],
346
+ ],
347
+ [
348
+ "agent-rules",
347
349
  [
348
- "agent-rules",
349
- [
350
- "Usage: cockpit agent-rules [install|uninstall|status] [--host codex|claude|all] [--workspace <path>] [--json]",
351
- "",
352
- "Installs a managed Tower-first block into ~/.codex/AGENTS.md",
353
- "and ~/.claude/CLAUDE.md by default. Pass --host to manage only one.",
354
- "The block is scoped to --workspace, or the current directory when omitted,",
355
- "so ticketed work only binds inside that onboarded folder.",
356
- "If CLAUDE.md already includes ~/.codex/AGENTS.md and both hosts are",
357
- "installed together, CLAUDE.md is left to the include instead of duplicating it.",
358
- "Action defaults to `install`.",
359
- ],
350
+ "Usage: cockpit agent-rules [install|uninstall|status] [--host codex|claude|all] [--workspace <path>] [--json]",
351
+ "",
352
+ "Installs a managed Tower-first block into ~/.codex/AGENTS.md",
353
+ "and ~/.claude/CLAUDE.md by default. Pass --host to manage only one.",
354
+ "The block is scoped to --workspace, or the current directory when omitted,",
355
+ "so ticketed work only binds inside that onboarded folder.",
356
+ "If CLAUDE.md already includes ~/.codex/AGENTS.md and both hosts are",
357
+ "installed together, CLAUDE.md is left to the include instead of duplicating it.",
358
+ "Action defaults to `install`.",
360
359
  ],
360
+ ],
361
+ [
362
+ "clean",
361
363
  [
362
- "clean",
363
- [
364
- "Usage: cockpit clean [--dry-run] [--all-committed] [--reconcile] [--dashboard-url <url>] [--json]",
365
- "",
366
- "Reclaims this machine's disk. Prints what it would delete and why, per bucket,",
367
- "then deletes: a staged copy Tower has already accepted goes (a retry re-reads",
368
- "the source file), and anything the upload ledger has NOT vouched for is kept,",
369
- "counted and named — retention never deletes undelivered evidence.",
370
- "--dry-run stops after the printing. --all-committed drops any retry window set",
371
- "with COCKPIT_STAGING_RETENTION_HOURS, so every already-accepted copy goes now, and is the only thing that removes a",
372
- "manual-study-evidence-vault folder (and only when every file in it is accepted).",
373
- "--reconcile asks Tower's own upload ledger about every object this machine's",
374
- "local memory can no longer classify (\"unknown\") before the buckets print — a",
375
- "confirmed-committed pack prunes under the ordinary rule this same run; a pack",
376
- "the server has never seen becomes an ordinary, never-deleted \"uncommitted\"",
377
- "object instead of \"unknown\". A server failure never blocks the rest of clean",
378
- "and is printed on its own line. Combine with --dry-run to ask and print",
379
- "without deleting.",
380
- "The scheduled sync does the same prune on every tick (reconciling one batch first",
381
- "when there is anything unknown); this is the door for \"show me\" and for a",
382
- "laptop that has been off.",
383
- ],
364
+ "Usage: cockpit clean [--dry-run] [--all-committed] [--reconcile] [--dashboard-url <url>] [--json]",
365
+ "",
366
+ "Reclaims this machine's disk. Prints what it would delete and why, per bucket,",
367
+ "then deletes: a staged copy Tower has already accepted goes (a retry re-reads",
368
+ "the source file), and anything the upload ledger has NOT vouched for is kept,",
369
+ "counted and named — retention never deletes undelivered evidence.",
370
+ "--dry-run stops after the printing. --all-committed drops any retry window set",
371
+ "with COCKPIT_STAGING_RETENTION_HOURS, so every already-accepted copy goes now, and is the only thing that removes a",
372
+ "manual-study-evidence-vault folder (and only when every file in it is accepted).",
373
+ "--reconcile asks Tower's own upload ledger about every object this machine's",
374
+ "local memory can no longer classify (\"unknown\") before the buckets print — a",
375
+ "confirmed-committed pack prunes under the ordinary rule this same run; a pack",
376
+ "the server has never seen becomes an ordinary, never-deleted \"uncommitted\"",
377
+ "object instead of \"unknown\". A server failure never blocks the rest of clean",
378
+ "and is printed on its own line. Combine with --dry-run to ask and print",
379
+ "without deleting.",
380
+ "The scheduled sync does the same prune on every tick (reconciling one batch first",
381
+ "when there is anything unknown); this is the door for \"show me\" and for a",
382
+ "laptop that has been off.",
384
383
  ],
384
+ ],
385
+ [
386
+ "sources",
385
387
  [
386
- "sources",
387
- [
388
- "Usage: cockpit sources check [--older-than <days>] [--dashboard-url <url>] [--json]",
389
- "",
390
- "Answers, for every Codex and Claude transcript on this machine, whether Tower",
391
- "holds it: stored in full, stored in part, or not stored, with the reason.",
392
- "--older-than <days> checks only files not modified in that many days.",
393
- "--json lists every file with its path, verdict and reason.",
394
- "Read-only. Tower never deletes these files; deleting one is your own act.",
395
- "Before deleting any transcript by hand, run this and delete only files it",
396
- "answers \"stored in full\". See docs/runbooks/freeing-disk-on-a-collector-machine.md.",
397
- ],
388
+ "Usage: cockpit sources check [--older-than <days>] [--dashboard-url <url>] [--json]",
389
+ "",
390
+ "Answers, for every Codex and Claude transcript on this machine, whether Tower",
391
+ "holds it: stored in full, stored in part, or not stored, with the reason.",
392
+ "--older-than <days> checks only files not modified in that many days.",
393
+ "--json lists every file with its path, verdict and reason.",
394
+ "Read-only. Tower never deletes these files; deleting one is your own act.",
395
+ "Before deleting any transcript by hand, run this and delete only files it",
396
+ "answers \"stored in full\". See docs/runbooks/freeing-disk-on-a-collector-machine.md.",
398
397
  ],
398
+ ],
399
+ [
400
+ "release",
399
401
  [
400
- "release",
401
- [
402
- "Usage: cockpit release [--dry-run] [--skip-checks] [--no-floor] [--tag <tag>] [--access <public|restricted>] [--otp <code>]",
403
- "",
404
- "Maintainer-only helper. Run from inside the bli-cockpit repo checkout.",
405
- "Requires a clean `main` branch and runs `git pull --ff-only` before publishing.",
406
- "Delegates to `npm run publish:public -- ...` so public packages are",
407
- "built, checked, and published in the safe telemetry-core then CLI order.",
408
- "A successful --tag latest publish raises the fleet forced-update floor so",
409
- "every collector pulls the new CLI on its next sync tick; --no-floor skips",
410
- "that for a staged rollout, and --tag next never touches it.",
411
- ],
402
+ "Usage: cockpit release [--dry-run] [--skip-checks] [--no-floor] [--tag <tag>] [--access <public|restricted>] [--otp <code>]",
403
+ "",
404
+ "Maintainer-only helper. Run from inside the bli-cockpit repo checkout.",
405
+ "Requires a clean `main` branch and runs `git pull --ff-only` before publishing.",
406
+ "Delegates to `npm run publish:public -- ...` so public packages are",
407
+ "built, checked, and published in the safe telemetry-core then CLI order.",
408
+ "A successful --tag latest publish raises the fleet forced-update floor so",
409
+ "every collector pulls the new CLI on its next sync tick; --no-floor skips",
410
+ "that for a staged rollout, and --tag next never touches it.",
412
411
  ],
413
- ]);
412
+ ],
413
+ ]);
414
+ export function localSubcommandHelp(command) {
414
415
  // BLI-10431: a Tower page name answers with its own usage line first, then
415
416
  // the manual of the noun it routes to, so `cockpit work --help` names every
416
417
  // ticket verb instead of `Unknown command: work`.
@@ -421,8 +422,8 @@ export function localSubcommandHelp(command) {
421
422
  `\`cockpit ${command}\` is the Tower page's name for \`cockpit ${aliasTarget}\`; both spellings run the same command.`,
422
423
  ...(aliasTarget === "issue" ? ["Projects the Tower tickets are filed under: `cockpit project list`."] : []),
423
424
  "",
424
- ...(helpByCommand.get(aliasTarget) ?? [localCommandHelp()]),
425
+ ...(COMMAND_HELP.get(aliasTarget) ?? [localCommandHelp()]),
425
426
  ].join("\n");
426
427
  }
427
- return (helpByCommand.get(command) ?? [localCommandHelp()]).join("\n");
428
+ return (COMMAND_HELP.get(command) ?? [localCommandHelp()]).join("\n");
428
429
  }