@bli-cockpit/cli 0.2.57 → 0.2.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/browser-open.js +88 -0
- package/dist/commands/docs.js +27 -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/issue-contracts.js +99 -0
- package/dist/commands/issue-write.js +129 -0
- package/dist/commands/issue.js +189 -0
- package/dist/commands/jarvis-answer-envelope.js +80 -0
- package/dist/commands/jarvis-turn.js +16 -1
- 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-docs-msg.js +95 -6
- package/dist/commands/local-args-tower-search.js +50 -0
- package/dist/commands/local-args-tower-work.js +178 -0
- package/dist/commands/local-args-tower.js +7 -1
- package/dist/commands/local-args.js +29 -14
- package/dist/commands/local-command-shapes.js +12 -0
- package/dist/commands/local-help-commands.js +643 -0
- package/dist/commands/local-help.js +12 -551
- package/dist/commands/local.js +9 -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-config.js +140 -0
- package/dist/commands/memory-install-receipt.js +222 -0
- package/dist/commands/memory-install-report.js +113 -0
- package/dist/commands/memory-install.js +99 -276
- package/dist/commands/msg.js +85 -2
- package/dist/commands/notes-door.js +120 -0
- package/dist/commands/notes-reads.js +134 -0
- package/dist/commands/notes-writes.js +208 -0
- package/dist/commands/notes.js +16 -442
- 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 +13 -1
- package/dist/commands/ops.js +65 -3
- package/dist/commands/project.js +38 -0
- 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/local-state-pairing-code.js +200 -0
- package/dist/local-state.js +6 -0
- package/dist/repo-identity-fingerprint.js +88 -0
- package/dist/repo-identity-git.js +76 -0
- package/dist/repo-identity-linked-worktrees.js +81 -0
- package/dist/repo-identity.js +5 -222
- package/package.json +7 -7
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cockpit issue` and `cockpit project` argument parsing (BLI-3716) — the
|
|
3
|
+
* Work surface's half of `local-args-tower.ts`, a sibling of
|
|
4
|
+
* `local-args-tower-docs-msg.ts` for the same reason that file is a sibling
|
|
5
|
+
* of the pages family: issues are their own noun with their own vocabulary
|
|
6
|
+
* (a state, an assignee, a project) and folding them into another family's
|
|
7
|
+
* parser would stretch that family's doc comment past the truth.
|
|
8
|
+
*
|
|
9
|
+
* Two commands, because a person types `cockpit project list`, not
|
|
10
|
+
* `cockpit issue projects` — the nouns are what a person says.
|
|
11
|
+
*
|
|
12
|
+
* Bodies never travel on argv: `create --title` names the issue, but the
|
|
13
|
+
* DESCRIPTION and every comment come from stdin or `--file`, the same
|
|
14
|
+
* discipline `cockpit docs` and `cockpit notes paste` keep (BLI-3706, and
|
|
15
|
+
* the sourcing-secrets verdict before it — argv is world-readable on a
|
|
16
|
+
* shared machine and lands in shell history).
|
|
17
|
+
*/
|
|
18
|
+
import { optionalNonEmpty, optionalPositiveInteger, optionalUrl, parseNamedArgs, } from "./local-arg-values.js";
|
|
19
|
+
const ISSUE_ACTIONS = new Set([
|
|
20
|
+
"list",
|
|
21
|
+
"show",
|
|
22
|
+
"create",
|
|
23
|
+
"update",
|
|
24
|
+
"move",
|
|
25
|
+
"comment",
|
|
26
|
+
"history",
|
|
27
|
+
]);
|
|
28
|
+
/** Every verb except `list` and `create` names ONE issue first. */
|
|
29
|
+
const ISSUE_ACTIONS_NEEDING_AN_ISSUE = new Set([
|
|
30
|
+
"show",
|
|
31
|
+
"update",
|
|
32
|
+
"move",
|
|
33
|
+
"comment",
|
|
34
|
+
"history",
|
|
35
|
+
]);
|
|
36
|
+
/**
|
|
37
|
+
* The closed state vocabulary, copied verbatim from
|
|
38
|
+
* `apps/dashboard/src/lib/work/api-doors.ts` `WORK_ISSUE_STATES` (which is
|
|
39
|
+
* itself the migration's CHECK constraint). Duplicated rather than imported
|
|
40
|
+
* because no dependency edge exists from the collector to the dashboard;
|
|
41
|
+
* `issue.ts`'s tests pin the list so a drift shows up here rather than as a
|
|
42
|
+
* 400 on a fleet machine.
|
|
43
|
+
*/
|
|
44
|
+
export const ISSUE_STATES = ["backlog", "todo", "in_progress", "in_review", "done", "canceled"];
|
|
45
|
+
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
46
|
+
export function parseIssueArgs(args) {
|
|
47
|
+
const values = parseNamedArgs(args, {
|
|
48
|
+
allowedFlags: [
|
|
49
|
+
"--home",
|
|
50
|
+
"--dashboard-url",
|
|
51
|
+
"--state",
|
|
52
|
+
"--assignee",
|
|
53
|
+
"--project",
|
|
54
|
+
"--limit",
|
|
55
|
+
"--title",
|
|
56
|
+
"--priority",
|
|
57
|
+
"--parent",
|
|
58
|
+
"--file",
|
|
59
|
+
"--body-stdin",
|
|
60
|
+
"--json",
|
|
61
|
+
],
|
|
62
|
+
valueFlags: [
|
|
63
|
+
"--home",
|
|
64
|
+
"--dashboard-url",
|
|
65
|
+
"--state",
|
|
66
|
+
"--assignee",
|
|
67
|
+
"--project",
|
|
68
|
+
"--limit",
|
|
69
|
+
"--title",
|
|
70
|
+
"--priority",
|
|
71
|
+
"--parent",
|
|
72
|
+
"--file",
|
|
73
|
+
],
|
|
74
|
+
});
|
|
75
|
+
const first = values.positionals[0];
|
|
76
|
+
const action = (first === undefined ? "list" : first);
|
|
77
|
+
if (!ISSUE_ACTIONS.has(action)) {
|
|
78
|
+
throw new Error(`Unknown issue command: ${first}. Try list, show, create, update, move, comment, or history.`);
|
|
79
|
+
}
|
|
80
|
+
const rest = values.positionals.slice(first === undefined ? 0 : 1);
|
|
81
|
+
let issueRef;
|
|
82
|
+
let moveState;
|
|
83
|
+
if (ISSUE_ACTIONS_NEEDING_AN_ISSUE.has(action)) {
|
|
84
|
+
issueRef = optionalNonEmpty(rest[0]);
|
|
85
|
+
if (!issueRef)
|
|
86
|
+
throw new Error(`issue ${action} needs an issue id or identifier, e.g. BLI-3654.`);
|
|
87
|
+
if (action === "move") {
|
|
88
|
+
moveState = optionalNonEmpty(rest[1]);
|
|
89
|
+
if (!moveState) {
|
|
90
|
+
throw new Error(`issue move needs a state: ${ISSUE_STATES.join(", ")}.`);
|
|
91
|
+
}
|
|
92
|
+
if (rest.length > 2)
|
|
93
|
+
throw new Error(`issue move takes an issue and one state, not ${rest.length} words.`);
|
|
94
|
+
}
|
|
95
|
+
else if (rest.length > 1) {
|
|
96
|
+
throw new Error(`issue ${action} takes one issue reference, not ${rest.length}.`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (rest.length > 0) {
|
|
100
|
+
throw new Error(`issue ${action} does not take "${rest[0]}".`);
|
|
101
|
+
}
|
|
102
|
+
if (moveState && !ISSUE_STATES.includes(moveState)) {
|
|
103
|
+
throw new Error(`issue move state must be one of: ${ISSUE_STATES.join(", ")}.`);
|
|
104
|
+
}
|
|
105
|
+
const stateFilter = optionalNonEmpty(values.flags.get("--state"));
|
|
106
|
+
if (stateFilter !== undefined && !ISSUE_STATES.includes(stateFilter)) {
|
|
107
|
+
throw new Error(`--state must be one of: ${ISSUE_STATES.join(", ")}.`);
|
|
108
|
+
}
|
|
109
|
+
if (stateFilter !== undefined && action !== "list") {
|
|
110
|
+
throw new Error("--state filters `cockpit issue list`; to move an issue use `cockpit issue move <id> <state>`.");
|
|
111
|
+
}
|
|
112
|
+
const title = optionalNonEmpty(values.flags.get("--title"));
|
|
113
|
+
if (action === "create" && !title)
|
|
114
|
+
throw new Error("issue create needs --title.");
|
|
115
|
+
// Not `optionalPositiveInteger`: 0 is a legitimate priority ("none", the
|
|
116
|
+
// column default), and that helper refuses it as non-positive.
|
|
117
|
+
const priorityRaw = optionalNonEmpty(values.flags.get("--priority"));
|
|
118
|
+
let priority;
|
|
119
|
+
if (priorityRaw !== undefined) {
|
|
120
|
+
priority = Number(priorityRaw);
|
|
121
|
+
if (!Number.isInteger(priority) || priority < 0 || priority > 4) {
|
|
122
|
+
throw new Error("--priority must be 0-4 (0 none, 1 urgent, 2 high, 3 medium, 4 low).");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// An assignee is `me`, `unassigned`, or a person's uuid. A name or an
|
|
126
|
+
// email is refused HERE rather than travelling to Postgres as a malformed
|
|
127
|
+
// uuid, which would come back as a 500 that names nothing useful.
|
|
128
|
+
const assignee = optionalNonEmpty(values.flags.get("--assignee"));
|
|
129
|
+
if (assignee !== undefined && assignee !== "me" && assignee !== "unassigned" && !UUID_PATTERN.test(assignee)) {
|
|
130
|
+
throw new Error('--assignee must be "me", "unassigned", or a person\'s uuid (see `cockpit team`).');
|
|
131
|
+
}
|
|
132
|
+
if (assignee === "unassigned" && action !== "list") {
|
|
133
|
+
throw new Error('--assignee unassigned filters `cockpit issue list`; to clear an assignee pass --assignee "" is not supported yet.');
|
|
134
|
+
}
|
|
135
|
+
const limit = optionalPositiveInteger(values.flags.get("--limit"), "--limit");
|
|
136
|
+
if (limit !== undefined && action !== "list" && action !== "history") {
|
|
137
|
+
throw new Error("--limit belongs to `cockpit issue list` or `cockpit issue history`.");
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
kind: "issue",
|
|
141
|
+
action,
|
|
142
|
+
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
143
|
+
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
144
|
+
...(issueRef ? { issueRef } : {}),
|
|
145
|
+
...(moveState ? { moveState } : {}),
|
|
146
|
+
...(stateFilter ? { stateFilter } : {}),
|
|
147
|
+
...(assignee ? { assignee } : {}),
|
|
148
|
+
project: optionalNonEmpty(values.flags.get("--project")),
|
|
149
|
+
...(limit === undefined ? {} : { limit }),
|
|
150
|
+
title,
|
|
151
|
+
...(priority === undefined ? {} : { priority }),
|
|
152
|
+
parentRef: optionalNonEmpty(values.flags.get("--parent")),
|
|
153
|
+
filePath: optionalNonEmpty(values.flags.get("--file")),
|
|
154
|
+
bodyStdin: values.booleans.has("--body-stdin"),
|
|
155
|
+
json: values.booleans.has("--json"),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
export function parseProjectArgs(args) {
|
|
159
|
+
const values = parseNamedArgs(args, {
|
|
160
|
+
allowedFlags: ["--home", "--dashboard-url", "--archived", "--json"],
|
|
161
|
+
valueFlags: ["--home", "--dashboard-url"],
|
|
162
|
+
});
|
|
163
|
+
const first = values.positionals[0];
|
|
164
|
+
const action = (first === undefined ? "list" : first);
|
|
165
|
+
if (action !== "list")
|
|
166
|
+
throw new Error(`Unknown project command: ${first}. The only verb is list.`);
|
|
167
|
+
const rest = values.positionals.slice(first === undefined ? 0 : 1);
|
|
168
|
+
if (rest.length > 0)
|
|
169
|
+
throw new Error(`project list does not take "${rest[0]}".`);
|
|
170
|
+
return {
|
|
171
|
+
kind: "project",
|
|
172
|
+
action,
|
|
173
|
+
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
174
|
+
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
175
|
+
includeArchived: values.booleans.has("--archived"),
|
|
176
|
+
json: values.booleans.has("--json"),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
@@ -18,10 +18,16 @@
|
|
|
18
18
|
* model
|
|
19
19
|
* local-args-tower-docs-msg.ts docs, msg — the document library and
|
|
20
20
|
* channels/messages (BLI-3706)
|
|
21
|
+
* local-args-tower-work.ts issue, project — the issue tracker
|
|
22
|
+
* (BLI-3716)
|
|
23
|
+
* local-args-tower-search.ts search — one bar over all five
|
|
24
|
+
* corpora (BLI-3728)
|
|
21
25
|
*
|
|
22
26
|
* Every name this module has ever exported is still importable from here.
|
|
23
27
|
*/
|
|
24
28
|
export { parseJarvisArgs, parseCorrectArgs } from "./local-args-tower-chat.js";
|
|
25
29
|
export { parseBriefArgs, WORKBOOK_MIN_WIDTH, parseWorkbookArgs, parseNotesArgs, } from "./local-args-tower-pages.js";
|
|
26
30
|
export { SCOUT_MIN_PREFIX_LENGTH, parseScoutArgs, parseOpsArgs, SLACK_WORKSPACE_KEYS, parseSlackArgs, parseSettingsArgs, parseTeamArgs, parseModelArgs, } from "./local-args-tower-admin.js";
|
|
27
|
-
export { parseDocsArgs, parseMsgArgs, } from "./local-args-tower-docs-msg.js";
|
|
31
|
+
export { parseDocsArgs, parseMsgArgs, } from "./local-args-tower-docs-msg.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, parseJarvisArgs, parseModelArgs, parseMsgArgs, parseNotesArgs, parseOpsArgs, 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";
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export const DOCTOR_SETUP_ALIASES = [
|
|
14
|
-
"install",
|
|
15
|
-
"onboard",
|
|
16
|
-
"login",
|
|
17
|
-
"pair",
|
|
18
|
-
"update",
|
|
19
|
-
"upgrade",
|
|
20
|
-
];
|
|
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";
|
|
29
|
+
export { SCOUT_MIN_PREFIX_LENGTH, SLACK_WORKSPACE_KEYS, WORKBOOK_MIN_WIDTH, ISSUE_STATES, } from "./local-args-tower.js";
|
|
21
30
|
export function parseLocalArgs(argv) {
|
|
22
31
|
const command = argv[0];
|
|
23
32
|
switch (command) {
|
|
@@ -88,6 +97,12 @@ export function parseLocalArgs(argv) {
|
|
|
88
97
|
return parseDocsArgs(argv.slice(1));
|
|
89
98
|
case "msg":
|
|
90
99
|
return parseMsgArgs(argv.slice(1));
|
|
100
|
+
case "issue":
|
|
101
|
+
return parseIssueArgs(argv.slice(1));
|
|
102
|
+
case "project":
|
|
103
|
+
return parseProjectArgs(argv.slice(1));
|
|
104
|
+
case "search":
|
|
105
|
+
return parseSearchArgs(argv.slice(1));
|
|
91
106
|
case "release":
|
|
92
107
|
return parseReleaseArgs(argv.slice(1));
|
|
93
108
|
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
|
+
];
|