@bli-cockpit/cli 0.2.58 → 0.2.60
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 +1 -1
- package/dist/commands/browser-open.js +88 -0
- package/dist/commands/docs.js +32 -6
- package/dist/commands/doctor-report.js +17 -1
- package/dist/commands/doctor.js +12 -2
- package/dist/commands/heartbeat.js +65 -1
- package/dist/commands/jarvis-answer-envelope.js +82 -0
- package/dist/commands/jarvis-render.js +18 -0
- package/dist/commands/jarvis-turn.js +29 -2
- package/dist/commands/jarvis.js +3 -0
- package/dist/commands/local-args-collector-setup.js +17 -0
- package/dist/commands/local-args-tower-admin.js +12 -2
- package/dist/commands/local-args-tower-chat.js +5 -0
- package/dist/commands/local-args-tower-docs-msg.js +105 -6
- package/dist/commands/local-args-tower-search.js +50 -0
- package/dist/commands/local-args-tower.js +4 -1
- package/dist/commands/local-args.js +28 -13
- package/dist/commands/local-command-shapes.js +12 -0
- package/dist/commands/local-help-commands.js +655 -0
- package/dist/commands/local-help.js +11 -582
- package/dist/commands/local.js +3 -0
- package/dist/commands/login.js +91 -8
- package/dist/commands/memory-install-claude.js +35 -15
- package/dist/commands/memory-install-codex-hooks.js +200 -0
- package/dist/commands/memory-install-codex.js +12 -2
- package/dist/commands/memory-install-receipt.js +222 -0
- package/dist/commands/memory-install-report.js +25 -1
- package/dist/commands/memory-install.js +76 -2
- package/dist/commands/msg.js +85 -2
- package/dist/commands/onboard-completion.js +47 -0
- package/dist/commands/onboard-setup.js +82 -2
- package/dist/commands/ops-render-memory.js +76 -0
- package/dist/commands/ops-render.js +6 -0
- package/dist/commands/ops.js +59 -2
- package/dist/commands/public-root.js +1 -1
- package/dist/commands/search.js +122 -0
- package/dist/commands/setup-receipt-lines.js +71 -0
- package/dist/commands/setup-receipt.js +241 -0
- package/dist/commands/status.js +20 -1
- package/dist/commands/tower-mcp-install.js +4 -2
- package/dist/local-state-pairing-code.js +200 -0
- package/dist/local-state.js +6 -0
- package/package.json +4 -4
|
@@ -31,6 +31,10 @@ export function parseJarvisArgs(args) {
|
|
|
31
31
|
"--trace",
|
|
32
32
|
"--limit",
|
|
33
33
|
"--json",
|
|
34
|
+
// BLI-3755: opt a `--json` turn back into seeing the coding arm's
|
|
35
|
+
// approval code. Without it a `--json` turn is an agent surface and the
|
|
36
|
+
// code is withheld.
|
|
37
|
+
"--show-approval-code",
|
|
34
38
|
],
|
|
35
39
|
valueFlags: [
|
|
36
40
|
"--home",
|
|
@@ -123,6 +127,7 @@ export function parseJarvisArgs(args) {
|
|
|
123
127
|
// callers that want the single-body shape on purpose, not a compat knob.
|
|
124
128
|
stream: !values.booleans.has("--no-stream"),
|
|
125
129
|
json: values.booleans.has("--json"),
|
|
130
|
+
showApprovalCode: values.booleans.has("--show-approval-code"),
|
|
126
131
|
};
|
|
127
132
|
}
|
|
128
133
|
/**
|
|
@@ -17,12 +17,15 @@ export function parseDocsArgs(args) {
|
|
|
17
17
|
"--title",
|
|
18
18
|
"--parent",
|
|
19
19
|
"--clear-parent",
|
|
20
|
+
"--allow-empty",
|
|
20
21
|
"--visibility",
|
|
21
22
|
"--file",
|
|
22
23
|
"--body-stdin",
|
|
24
|
+
"--query",
|
|
25
|
+
"--limit",
|
|
23
26
|
"--json",
|
|
24
27
|
],
|
|
25
|
-
valueFlags: ["--home", "--dashboard-url", "--title", "--parent", "--visibility", "--file"],
|
|
28
|
+
valueFlags: ["--home", "--dashboard-url", "--title", "--parent", "--visibility", "--file", "--query", "--limit"],
|
|
26
29
|
});
|
|
27
30
|
const first = values.positionals[0];
|
|
28
31
|
const action = (first === undefined ? "list" : first);
|
|
@@ -53,10 +56,30 @@ export function parseDocsArgs(args) {
|
|
|
53
56
|
if (clearParent && action !== "update") {
|
|
54
57
|
throw new Error("--clear-parent belongs to `cockpit docs update`.");
|
|
55
58
|
}
|
|
59
|
+
// BLI-3759: the PATCH door refuses a body that empties a document holding
|
|
60
|
+
// text unless the caller sends `allow_empty: true` (`refused_empty_body`,
|
|
61
|
+
// 409, BLI-3757). `--allow-empty` is the terminal's way to say it, and it
|
|
62
|
+
// means nothing on the verbs that never send an existing document a new body.
|
|
63
|
+
const allowEmpty = values.booleans.has("--allow-empty");
|
|
64
|
+
if (allowEmpty && action !== "update") {
|
|
65
|
+
throw new Error("--allow-empty belongs to `cockpit docs update`.");
|
|
66
|
+
}
|
|
56
67
|
const title = optionalNonEmpty(values.flags.get("--title"));
|
|
57
68
|
if (action === "create" && !title) {
|
|
58
69
|
throw new Error("docs create needs --title.");
|
|
59
70
|
}
|
|
71
|
+
// BLI-3737: narrowing belongs to `list` only. `--parent` keeps its create/
|
|
72
|
+
// update meaning elsewhere (which parent to file the document under); on
|
|
73
|
+
// `list` the same word names which parent to list UNDER, plus the literal
|
|
74
|
+
// `root` for the top of the tree.
|
|
75
|
+
const query = optionalNonEmpty(values.flags.get("--query"));
|
|
76
|
+
if (query && action !== "list") {
|
|
77
|
+
throw new Error("--query belongs to `cockpit docs list`.");
|
|
78
|
+
}
|
|
79
|
+
const limit = optionalPositiveInteger(values.flags.get("--limit"), "--limit");
|
|
80
|
+
if (limit !== undefined && action !== "list") {
|
|
81
|
+
throw new Error("--limit belongs to `cockpit docs list`.");
|
|
82
|
+
}
|
|
60
83
|
return {
|
|
61
84
|
kind: "docs",
|
|
62
85
|
action,
|
|
@@ -66,25 +89,96 @@ export function parseDocsArgs(args) {
|
|
|
66
89
|
title,
|
|
67
90
|
...(parentId ? { parentId } : {}),
|
|
68
91
|
clearParent,
|
|
92
|
+
...(allowEmpty ? { allowEmpty } : {}),
|
|
69
93
|
visibility: visibility,
|
|
70
94
|
filePath: optionalNonEmpty(values.flags.get("--file")),
|
|
71
95
|
bodyStdin: values.booleans.has("--body-stdin"),
|
|
96
|
+
...(query ? { query } : {}),
|
|
97
|
+
...(limit === undefined ? {} : { limit }),
|
|
72
98
|
json: values.booleans.has("--json"),
|
|
73
99
|
};
|
|
74
100
|
}
|
|
75
|
-
const MSG_ACTIONS = new Set(["channels", "read", "send", "thread"]);
|
|
101
|
+
const MSG_ACTIONS = new Set(["channels", "read", "send", "thread", "create", "dm"]);
|
|
76
102
|
const MSG_ACTIONS_NEEDING_A_CHANNEL = new Set(["read", "send"]);
|
|
103
|
+
/**
|
|
104
|
+
* `--members a@x.test,b@y.test` — addresses only, split on commas, never
|
|
105
|
+
* fuzzy (BLI-3749). The door resolves each one exactly, so a typo comes back
|
|
106
|
+
* as `person_not_found` naming the address rather than as a stranger added
|
|
107
|
+
* to a private channel.
|
|
108
|
+
*/
|
|
109
|
+
function parseMemberEmails(raw) {
|
|
110
|
+
const value = optionalNonEmpty(raw);
|
|
111
|
+
if (!value)
|
|
112
|
+
return undefined;
|
|
113
|
+
const emails = value
|
|
114
|
+
.split(",")
|
|
115
|
+
.map((part) => part.trim())
|
|
116
|
+
.filter((part) => part !== "");
|
|
117
|
+
if (emails.length === 0)
|
|
118
|
+
throw new Error("msg create --members needs at least one email address.");
|
|
119
|
+
const notAnAddress = emails.find((email) => !email.includes("@"));
|
|
120
|
+
if (notAnAddress) {
|
|
121
|
+
throw new Error(`msg create --members takes email addresses; "${notAnAddress}" is not one.`);
|
|
122
|
+
}
|
|
123
|
+
return emails;
|
|
124
|
+
}
|
|
77
125
|
export function parseMsgArgs(args) {
|
|
78
126
|
const values = parseNamedArgs(args, {
|
|
79
|
-
allowedFlags: [
|
|
80
|
-
|
|
127
|
+
allowedFlags: [
|
|
128
|
+
"--home",
|
|
129
|
+
"--dashboard-url",
|
|
130
|
+
"--channel",
|
|
131
|
+
"--thread",
|
|
132
|
+
"--limit",
|
|
133
|
+
"--private",
|
|
134
|
+
"--members",
|
|
135
|
+
"--description",
|
|
136
|
+
"--json",
|
|
137
|
+
],
|
|
138
|
+
valueFlags: ["--home", "--dashboard-url", "--channel", "--thread", "--limit", "--members", "--description"],
|
|
81
139
|
});
|
|
82
140
|
const first = values.positionals[0];
|
|
83
141
|
const action = (first === undefined ? "channels" : first);
|
|
84
142
|
if (!MSG_ACTIONS.has(action)) {
|
|
85
|
-
throw new Error(`Unknown msg command: ${first}. Try channels, read, send, or
|
|
143
|
+
throw new Error(`Unknown msg command: ${first}. Try channels, read, send, thread, create, or dm.`);
|
|
86
144
|
}
|
|
87
145
|
const rest = values.positionals.slice(first === undefined ? 0 : 1);
|
|
146
|
+
let channelName;
|
|
147
|
+
let dmEmail;
|
|
148
|
+
if (action === "create") {
|
|
149
|
+
channelName = optionalNonEmpty(rest[0]);
|
|
150
|
+
if (!channelName)
|
|
151
|
+
throw new Error("msg create needs a channel name, e.g. `cockpit msg create general`.");
|
|
152
|
+
if (rest.length > 1)
|
|
153
|
+
throw new Error(`msg create takes one channel name, not ${rest.length}.`);
|
|
154
|
+
// `#general` is how a person says it and how `read`/`send` accept it, so
|
|
155
|
+
// the leading # is dropped here rather than becoming part of the name.
|
|
156
|
+
if (channelName.startsWith("#"))
|
|
157
|
+
channelName = channelName.slice(1);
|
|
158
|
+
if (channelName === "")
|
|
159
|
+
throw new Error("msg create needs a channel name, e.g. `cockpit msg create general`.");
|
|
160
|
+
}
|
|
161
|
+
else if (action === "dm") {
|
|
162
|
+
dmEmail = optionalNonEmpty(rest[0]);
|
|
163
|
+
if (!dmEmail)
|
|
164
|
+
throw new Error("msg dm needs the person's email address, e.g. `cockpit msg dm ada@example.com`.");
|
|
165
|
+
if (rest.length > 1)
|
|
166
|
+
throw new Error(`msg dm takes one email address, not ${rest.length}.`);
|
|
167
|
+
if (!dmEmail.includes("@"))
|
|
168
|
+
throw new Error(`msg dm takes an email address; "${dmEmail}" is not one.`);
|
|
169
|
+
}
|
|
170
|
+
const isPrivate = values.booleans.has("--private");
|
|
171
|
+
if (isPrivate && action !== "create") {
|
|
172
|
+
throw new Error("--private belongs to `cockpit msg create`.");
|
|
173
|
+
}
|
|
174
|
+
const memberEmails = parseMemberEmails(values.flags.get("--members"));
|
|
175
|
+
if (memberEmails && action !== "create") {
|
|
176
|
+
throw new Error("--members belongs to `cockpit msg create`.");
|
|
177
|
+
}
|
|
178
|
+
const description = optionalNonEmpty(values.flags.get("--description"));
|
|
179
|
+
if (description && action !== "create") {
|
|
180
|
+
throw new Error("--description belongs to `cockpit msg create`.");
|
|
181
|
+
}
|
|
88
182
|
let channelRef;
|
|
89
183
|
if (MSG_ACTIONS_NEEDING_A_CHANNEL.has(action)) {
|
|
90
184
|
channelRef = optionalNonEmpty(rest[0]);
|
|
@@ -99,7 +193,7 @@ export function parseMsgArgs(args) {
|
|
|
99
193
|
if (rest.length > 1)
|
|
100
194
|
throw new Error(`msg thread takes one thread id, not ${rest.length}.`);
|
|
101
195
|
}
|
|
102
|
-
else if (rest.length > 0) {
|
|
196
|
+
else if (action !== "create" && action !== "dm" && rest.length > 0) {
|
|
103
197
|
throw new Error(`msg ${action} does not take "${rest[0]}".`);
|
|
104
198
|
}
|
|
105
199
|
const threadFlag = optionalNonEmpty(values.flags.get("--thread"));
|
|
@@ -119,6 +213,11 @@ export function parseMsgArgs(args) {
|
|
|
119
213
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
120
214
|
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
121
215
|
...(channelRef ? { channelRef } : {}),
|
|
216
|
+
...(channelName ? { channelName } : {}),
|
|
217
|
+
...(dmEmail ? { dmEmail } : {}),
|
|
218
|
+
...(memberEmails ? { memberEmails } : {}),
|
|
219
|
+
...(description ? { description } : {}),
|
|
220
|
+
isPrivate,
|
|
122
221
|
...(threadId ? { threadId } : {}),
|
|
123
222
|
...(limit === undefined ? {} : { limit }),
|
|
124
223
|
json: values.booleans.has("--json"),
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cockpit search` argument parsing (BLI-3728).
|
|
3
|
+
*
|
|
4
|
+
* Its own sibling of `local-args-tower.ts` rather than folded into
|
|
5
|
+
* `local-args-tower-pages.ts` or `-docs-msg.ts`: search is not one surface's
|
|
6
|
+
* verb, it is the door OVER all of them — documents, messages, issues, meeting
|
|
7
|
+
* notes and memory — and putting it under any one family's doc comment would
|
|
8
|
+
* say something untrue about what it reads.
|
|
9
|
+
*
|
|
10
|
+
* The query is a POSITIONAL, not a flag, because that is how every search
|
|
11
|
+
* command a person has ever typed works (`grep`, `rg`, `gh search`). Several
|
|
12
|
+
* positionals are joined with a space so `cockpit search storage ceiling`
|
|
13
|
+
* behaves the way it looks, without demanding quotes.
|
|
14
|
+
*/
|
|
15
|
+
import { optionalNonEmpty, optionalPositiveInteger, optionalUrl, parseNamedArgs, } from "./local-arg-values.js";
|
|
16
|
+
/** The five corpora. Kept here so an unknown kind is refused BEFORE a round trip. */
|
|
17
|
+
export const SEARCH_KINDS = ["doc", "msg", "issue", "note", "memory"];
|
|
18
|
+
export function parseSearchArgs(args) {
|
|
19
|
+
const values = parseNamedArgs(args, {
|
|
20
|
+
allowedFlags: ["--home", "--dashboard-url", "--kind", "--limit", "--json"],
|
|
21
|
+
valueFlags: ["--home", "--dashboard-url", "--kind", "--limit"],
|
|
22
|
+
});
|
|
23
|
+
const query = values.positionals.join(" ").trim();
|
|
24
|
+
if (query.length === 0) {
|
|
25
|
+
throw new Error('search needs something to search for, e.g. `cockpit search "storage ceiling"`.');
|
|
26
|
+
}
|
|
27
|
+
const kindFlag = optionalNonEmpty(values.flags.get("--kind"));
|
|
28
|
+
let kinds;
|
|
29
|
+
if (kindFlag) {
|
|
30
|
+
kinds = [];
|
|
31
|
+
for (const part of kindFlag.split(",").map((entry) => entry.trim()).filter(Boolean)) {
|
|
32
|
+
if (!SEARCH_KINDS.includes(part)) {
|
|
33
|
+
throw new Error(`search --kind must be one or more of ${SEARCH_KINDS.join(", ")} — not "${part}".`);
|
|
34
|
+
}
|
|
35
|
+
if (!kinds.includes(part))
|
|
36
|
+
kinds.push(part);
|
|
37
|
+
}
|
|
38
|
+
if (kinds.length === 0)
|
|
39
|
+
kinds = undefined;
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
kind: "search",
|
|
43
|
+
query,
|
|
44
|
+
...(kinds ? { kinds } : {}),
|
|
45
|
+
limit: optionalPositiveInteger(values.flags.get("--limit"), "--limit"),
|
|
46
|
+
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
47
|
+
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
48
|
+
json: values.booleans.has("--json"),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
* channels/messages (BLI-3706)
|
|
21
21
|
* local-args-tower-work.ts issue, project — the issue tracker
|
|
22
22
|
* (BLI-3716)
|
|
23
|
+
* local-args-tower-search.ts search — one bar over all five
|
|
24
|
+
* corpora (BLI-3728)
|
|
23
25
|
*
|
|
24
26
|
* Every name this module has ever exported is still importable from here.
|
|
25
27
|
*/
|
|
@@ -27,4 +29,5 @@ export { parseJarvisArgs, parseCorrectArgs } from "./local-args-tower-chat.js";
|
|
|
27
29
|
export { parseBriefArgs, WORKBOOK_MIN_WIDTH, parseWorkbookArgs, parseNotesArgs, } from "./local-args-tower-pages.js";
|
|
28
30
|
export { SCOUT_MIN_PREFIX_LENGTH, parseScoutArgs, parseOpsArgs, SLACK_WORKSPACE_KEYS, parseSlackArgs, parseSettingsArgs, parseTeamArgs, parseModelArgs, } from "./local-args-tower-admin.js";
|
|
29
31
|
export { parseDocsArgs, parseMsgArgs, } from "./local-args-tower-docs-msg.js";
|
|
30
|
-
export { ISSUE_STATES, parseIssueArgs, parseProjectArgs, } from "./local-args-tower-work.js";
|
|
32
|
+
export { ISSUE_STATES, parseIssueArgs, parseProjectArgs, } from "./local-args-tower-work.js";
|
|
33
|
+
export { SEARCH_KINDS, parseSearchArgs } from "./local-args-tower-search.js";
|
|
@@ -1,23 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a person may type, and what each subcommand means once typed.
|
|
3
|
+
*
|
|
4
|
+
* Two things live here and nothing else: `LocalCommand`, the shape every
|
|
5
|
+
* command runner is handed, and `parseLocalArgs`, the table that picks which
|
|
6
|
+
* decision table reads the rest of `argv`. The decision tables themselves are
|
|
7
|
+
* next door, one file per half of the product (BLI-3578):
|
|
8
|
+
*
|
|
9
|
+
* local-arg-values.ts argv into named flags, then one question per value
|
|
10
|
+
* local-args-collector.ts the commands that act on THIS machine
|
|
11
|
+
* local-args-tower.ts the commands that talk to Tower
|
|
12
|
+
*
|
|
13
|
+
* Split out of commands/local.ts originally so the command runners read as a
|
|
14
|
+
* table of contents and the parser (pure, independently testable) can change at
|
|
15
|
+
* its own rate. Behavior-preserving extraction throughout: functions moved
|
|
16
|
+
* verbatim, no logic change.
|
|
17
|
+
*/
|
|
1
18
|
import { parseAgentRulesArgs, parseAnalyzeArgs, parseAutostartArgs, parseBackfillArgs, parseCleanArgs, parseDoctorArgs, parseInstallArgs, parseLoginArgs, parseMemoryArgs, parseLogoutArgs, parseOnboardArgs, parseReleaseArgs, parseServeArgs, parseSessionsArgs, parseStartArgs, parseStatusArgs, parseSyncArgs, parseUpdateArgs, } from "./local-args-collector.js";
|
|
2
|
-
import { parseBriefArgs, parseCorrectArgs, parseDocsArgs, parseIssueArgs, parseJarvisArgs, parseModelArgs, parseMsgArgs, parseNotesArgs, parseOpsArgs, parseProjectArgs, parseScoutArgs, parseSettingsArgs, parseSlackArgs, parseTeamArgs, parseWorkbookArgs, } from "./local-args-tower.js";
|
|
19
|
+
import { parseBriefArgs, parseCorrectArgs, parseDocsArgs, parseIssueArgs, parseJarvisArgs, parseModelArgs, parseMsgArgs, parseNotesArgs, parseOpsArgs, parseProjectArgs, parseScoutArgs, parseSearchArgs, parseSettingsArgs, parseSlackArgs, parseTeamArgs, parseWorkbookArgs, } from "./local-args-tower.js";
|
|
3
20
|
// `normalizeUrl` has always been part of this module's surface — `local.ts` and
|
|
4
21
|
// `local-auth.ts` import it from here — so it stays exported from this address
|
|
5
22
|
// even though it now lives next door. The same goes for the four names the
|
|
6
23
|
// Tower parsers publish.
|
|
7
24
|
export { normalizeUrl } from "./local-arg-values.js";
|
|
25
|
+
// BLI-3728: the command SHAPES moved to a sibling when this file crossed the
|
|
26
|
+
// 700-line ceiling. Re-exported here because ~40 modules and every sibling
|
|
27
|
+
// parser import them from this path.
|
|
28
|
+
export { DOCTOR_SETUP_ALIASES, } from "./local-command-shapes.js";
|
|
8
29
|
export { SCOUT_MIN_PREFIX_LENGTH, SLACK_WORKSPACE_KEYS, WORKBOOK_MIN_WIDTH, ISSUE_STATES, } from "./local-args-tower.js";
|
|
9
|
-
// The six human "set my machine up" doors. They are one thing wearing six
|
|
10
|
-
// hats, so they all run the convergence command — but they keep accepting the
|
|
11
|
-
// flags they always accepted, because DMs, runbooks and AGENTS.md rules across
|
|
12
|
-
// the fleet still spell them out.
|
|
13
|
-
export const DOCTOR_SETUP_ALIASES = [
|
|
14
|
-
"install",
|
|
15
|
-
"onboard",
|
|
16
|
-
"login",
|
|
17
|
-
"pair",
|
|
18
|
-
"update",
|
|
19
|
-
"upgrade",
|
|
20
|
-
];
|
|
21
30
|
export function parseLocalArgs(argv) {
|
|
22
31
|
const command = argv[0];
|
|
23
32
|
switch (command) {
|
|
@@ -32,6 +41,10 @@ export function parseLocalArgs(argv) {
|
|
|
32
41
|
// Aliasing lands once the convergence run honours --ticket. See BLI-2494.
|
|
33
42
|
case "do-everything":
|
|
34
43
|
case "fix":
|
|
44
|
+
// BLI-3768: `doctor` is what the ops board's RED rows, the setup receipt
|
|
45
|
+
// and the heartbeat all tell a person to run. It routes here exactly like
|
|
46
|
+
// `fix` — the check table diagnoses, then converges.
|
|
47
|
+
case "doctor":
|
|
35
48
|
return parseDoctorArgs(command, argv.slice(1));
|
|
36
49
|
case "install":
|
|
37
50
|
return parseInstallArgs(argv.slice(1));
|
|
@@ -92,6 +105,8 @@ export function parseLocalArgs(argv) {
|
|
|
92
105
|
return parseIssueArgs(argv.slice(1));
|
|
93
106
|
case "project":
|
|
94
107
|
return parseProjectArgs(argv.slice(1));
|
|
108
|
+
case "search":
|
|
109
|
+
return parseSearchArgs(argv.slice(1));
|
|
95
110
|
case "release":
|
|
96
111
|
return parseReleaseArgs(argv.slice(1));
|
|
97
112
|
default:
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// The six human "set my machine up" doors. They are one thing wearing six
|
|
2
|
+
// hats, so they all run the convergence command — but they keep accepting the
|
|
3
|
+
// flags they always accepted, because DMs, runbooks and AGENTS.md rules across
|
|
4
|
+
// the fleet still spell them out.
|
|
5
|
+
export const DOCTOR_SETUP_ALIASES = [
|
|
6
|
+
"install",
|
|
7
|
+
"onboard",
|
|
8
|
+
"login",
|
|
9
|
+
"pair",
|
|
10
|
+
"update",
|
|
11
|
+
"upgrade",
|
|
12
|
+
];
|