@bli-cockpit/cli 0.2.192 → 0.2.193
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/local-args-tower-search.js +12 -22
- package/dist/commands/local-args-tower.js +1 -1
- package/dist/commands/local-help-commands-tower.js +11 -17
- package/dist/commands/local-help.js +2 -2
- package/dist/commands/public-root.js +1 -1
- package/dist/commands/search.js +33 -3
- package/package.json +2 -2
|
@@ -15,40 +15,29 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { optionalNonEmpty, optionalPositiveInteger, optionalUrl, parseNamedArgs, } from "./local-arg-values.js";
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* the
|
|
18
|
+
* What `--kind` names is the SERVER's to say (BLI-13027). This used to be a copy
|
|
19
|
+
* of the dashboard's kind list that refused anything it did not hold, so an
|
|
20
|
+
* installed CLI told a person that Scout did not exist the day Scout shipped.
|
|
21
|
+
* Now the CLI forwards the words, and the door answers `unknown_kind` with the
|
|
22
|
+
* list this account is offered. `cockpit search --categories` prints that list.
|
|
21
23
|
*/
|
|
22
|
-
export const SEARCH_KINDS = [
|
|
23
|
-
"doc",
|
|
24
|
-
"msg",
|
|
25
|
-
"issue",
|
|
26
|
-
"note",
|
|
27
|
-
"mail",
|
|
28
|
-
"cal",
|
|
29
|
-
"memory",
|
|
30
|
-
];
|
|
31
24
|
export function parseSearchArgs(args) {
|
|
32
25
|
const values = parseNamedArgs(args, {
|
|
33
|
-
allowedFlags: ["--home", "--dashboard-url", "--kind", "--limit", "--json"],
|
|
26
|
+
allowedFlags: ["--home", "--dashboard-url", "--kind", "--limit", "--json", "--categories"],
|
|
34
27
|
valueFlags: ["--home", "--dashboard-url", "--kind", "--limit"],
|
|
35
28
|
});
|
|
36
29
|
const query = values.positionals.join(" ").trim();
|
|
37
|
-
|
|
30
|
+
const categories = values.booleans.has("--categories");
|
|
31
|
+
if (query.length === 0 && !categories) {
|
|
38
32
|
throw new Error('search needs something to search for, e.g. `cockpit search "storage ceiling"`.');
|
|
39
33
|
}
|
|
40
34
|
const kindFlag = optionalNonEmpty(values.flags.get("--kind"));
|
|
41
35
|
let kinds;
|
|
42
36
|
if (kindFlag) {
|
|
43
37
|
kinds = [];
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (!SEARCH_KINDS.includes(part)) {
|
|
48
|
-
throw new Error(`search --kind must be one or more of ${SEARCH_KINDS.join(", ")} — not "${raw}".`);
|
|
49
|
-
}
|
|
50
|
-
if (!kinds.includes(part))
|
|
51
|
-
kinds.push(part);
|
|
38
|
+
for (const raw of kindFlag.split(",").map((entry) => entry.trim().toLowerCase()).filter(Boolean)) {
|
|
39
|
+
if (!kinds.includes(raw))
|
|
40
|
+
kinds.push(raw);
|
|
52
41
|
}
|
|
53
42
|
if (kinds.length === 0)
|
|
54
43
|
kinds = undefined;
|
|
@@ -56,6 +45,7 @@ export function parseSearchArgs(args) {
|
|
|
56
45
|
return {
|
|
57
46
|
kind: "search",
|
|
58
47
|
query,
|
|
48
|
+
...(categories ? { categories: true } : {}),
|
|
59
49
|
...(kinds ? { kinds } : {}),
|
|
60
50
|
limit: optionalPositiveInteger(values.flags.get("--limit"), "--limit"),
|
|
61
51
|
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
@@ -33,7 +33,7 @@ export { SCOUT_MIN_PREFIX_LENGTH, parseScoutArgs, parseOpsArgs, SLACK_WORKSPACE_
|
|
|
33
33
|
export { parseDocsArgs, parseMsgArgs, } from "./local-args-tower-docs-msg.js";
|
|
34
34
|
export { ISSUE_STATES, parseIssueArgs, parseProjectArgs, } from "./local-args-tower-work.js";
|
|
35
35
|
export { parseGithubArgs } from "./local-args-tower-github.js";
|
|
36
|
-
export {
|
|
36
|
+
export { parseSearchArgs } from "./local-args-tower-search.js";
|
|
37
37
|
export { parseModelsArgs } from "./local-args-tower-models.js";
|
|
38
38
|
export { parseMailArgs } from "./local-args-tower-mail.js";
|
|
39
39
|
export { parseCalArgs } from "./local-args-tower-cal.js";
|
|
@@ -11,15 +11,6 @@
|
|
|
11
11
|
* Every string moved verbatim. Help output is what an intern pastes back when
|
|
12
12
|
* something breaks, so it is a user-visible contract like any other.
|
|
13
13
|
*/
|
|
14
|
-
import { SEARCH_KINDS } from "./local-args-tower-search.js";
|
|
15
|
-
/**
|
|
16
|
-
* The corpora `cockpit search` can name, spelled the way `--kind` takes them.
|
|
17
|
-
* Read off `SEARCH_KINDS` rather than typed out: the help string said five for
|
|
18
|
-
* the two months `mail` and `cal` were searchable, so a person was told the
|
|
19
|
-
* door was narrower than it is (BLI-4048).
|
|
20
|
-
*/
|
|
21
|
-
const SEARCH_KIND_LIST = SEARCH_KINDS.join(",");
|
|
22
|
-
const SEARCH_CORPORA_COUNT = SEARCH_KINDS.length;
|
|
23
14
|
/** One entry per Tower noun, in the order `cockpit --help` lists them. */
|
|
24
15
|
export const TOWER_COMMAND_HELP = [
|
|
25
16
|
[
|
|
@@ -207,10 +198,11 @@ export const TOWER_COMMAND_HELP = [
|
|
|
207
198
|
[
|
|
208
199
|
"search",
|
|
209
200
|
[
|
|
210
|
-
|
|
201
|
+
'Usage: cockpit search "<words>" [--kind <category,...>] [--limit <n>] [--json]',
|
|
202
|
+
" cockpit search --categories [--json]",
|
|
211
203
|
"",
|
|
212
|
-
|
|
213
|
-
"events and
|
|
204
|
+
"One bar over every corpus Tower holds: tickets, documents, meeting notes, messages, mail,",
|
|
205
|
+
"calendar events, memory, Scout and (where you may read it) Careers.",
|
|
214
206
|
"It presses the SAME door the browser's search bar presses (GET /api/search), so what you",
|
|
215
207
|
"read here is the same row, the same ranking and the same snippet a person sees in Tower.",
|
|
216
208
|
"",
|
|
@@ -219,14 +211,16 @@ export const TOWER_COMMAND_HELP = [
|
|
|
219
211
|
"Quoted phrases and -word work inside the query itself — the query goes to Postgres's",
|
|
220
212
|
"websearch parser, which shrugs at anything a person can type instead of raising.",
|
|
221
213
|
"",
|
|
222
|
-
|
|
223
|
-
|
|
214
|
+
"--kind narrows to one or more categories, comma separated (ticket works for issue).",
|
|
215
|
+
"--categories prints the list Tower offers THIS account, in the order the browser's Command-K",
|
|
216
|
+
"chips use, so the names are never a guess; an unknown --kind is refused by the door with that list.",
|
|
217
|
+
"Omit --kind and every category is searched.",
|
|
224
218
|
"--limit caps the number of results (default 20, maximum 50).",
|
|
225
219
|
"--json writes the door's whole answer to stdout, hits, per-kind counts, failures and all.",
|
|
226
220
|
"",
|
|
227
|
-
|
|
228
|
-
"
|
|
229
|
-
"the list; memory
|
|
221
|
+
"Every result is scoped by what YOU may read: most corpora (and Careers always) are searched on",
|
|
222
|
+
"your own database session, so a document, a channel or an applicant you cannot open is not in",
|
|
223
|
+
"the list; memory and Scout run on the service role behind their own gates.",
|
|
230
224
|
"",
|
|
231
225
|
"A corpus that could not ANSWER gets its own line, separately from \"nothing matched\" —",
|
|
232
226
|
"those are different facts and folding them together would let a broken search read as silence.",
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* user-visible contract like any other.
|
|
9
9
|
*/
|
|
10
10
|
import { DEFAULT_DASHBOARD_URL } from "../local-state.js";
|
|
11
|
-
import { SEARCH_KINDS } from "./local-args-tower-search.js";
|
|
12
11
|
import { localSubcommandHelp } from "./local-help-commands.js";
|
|
13
12
|
/**
|
|
14
13
|
* The Tower PAGE names a person reads in the rail, each routed to the CLI noun
|
|
@@ -136,7 +135,8 @@ export function localCommandHelp(command) {
|
|
|
136
135
|
" cockpit cal [today|week|next|find \"<words>\"|calendars|add-ical|create --calendar <id> --title <t> --at <iso> --until <iso>|share <id> --org-visible|--private|sync <id> [--full]|detach <id>] [--tz <zone>] [--offset <n>] [--hours <n>] [--from <d> --to <d>] [--calendar <id>] [--limit <n>] [--all] [--dashboard-url <url>] [--json]",
|
|
137
136
|
" cockpit project [list] [--archived] [--dashboard-url <url>] [--json]",
|
|
138
137
|
" cockpit github <pr|merge|retitle|rerun> <owner/repo> <n> [--claim <state>] [--method squash|merge|rebase] [--title \"<text>\"] [--run <id>] [--confirm <code>] [--dashboard-url <url>] [--json]",
|
|
139
|
-
` cockpit search "<words>" [--kind
|
|
138
|
+
` cockpit search "<words>" [--kind <category,...>] [--limit <n>] [--dashboard-url <url>] [--json]`,
|
|
139
|
+
" cockpit search --categories [--dashboard-url <url>] [--json]",
|
|
140
140
|
" cockpit release [--dry-run] [--skip-checks] [--no-floor] [--tag <tag>] [--access <public|restricted>] [--otp <code>]",
|
|
141
141
|
" cockpit careers [list|show <id>|rescreen <id>|send-takehome <id>|decide <id> --decision <passed_on|archived|reopen>|followup <id> [--record-sent-at <iso>]|interview <id> <--at <iso>|--clear>|grade <id> [--now]|resume <id> [--out <path>]|takehome show <role>|takehome set <role> --body-file <path>|settings show|settings set --enabled <true|false> --followup-enabled <true|false> --followup-after-days <n> --takehome-window-hours <n>] [--role <slug>] [--min-score <n>] [--since <date>] [--stage <s>] [--force] [--json]",
|
|
142
142
|
" cockpit glossary list|add <wrong> --to <name>|remove <wrong> [--dashboard-url <url>] [--json]",
|
|
@@ -21,7 +21,7 @@ export async function runCockpitCli(argv, io) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
if (command === "--version" || command === "-V" || command === "version") {
|
|
24
|
-
writeLine(io?.stdout ?? process.stdout, "0.2.
|
|
24
|
+
writeLine(io?.stdout ?? process.stdout, "0.2.193");
|
|
25
25
|
return 0;
|
|
26
26
|
}
|
|
27
27
|
|
package/dist/commands/search.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `cockpit search` — one bar over
|
|
2
|
+
* `cockpit search` — one bar over every corpus, in a terminal (BLI-3728).
|
|
3
3
|
*
|
|
4
4
|
* The SAME door the browser's search bar presses: `GET /api/search`, opted
|
|
5
5
|
* into the collector device token in `route-caller-census.test.ts`. So a
|
|
@@ -42,10 +42,15 @@ const KIND_LABELS = {
|
|
|
42
42
|
mail: "MAIL",
|
|
43
43
|
cal: "CALENDAR",
|
|
44
44
|
memory: "MEMORY",
|
|
45
|
+
scout: "SCOUT",
|
|
46
|
+
careers: "CAREERS",
|
|
45
47
|
};
|
|
46
|
-
const KIND_ORDER = ["doc", "msg", "issue", "note", "mail", "cal", "memory"];
|
|
48
|
+
const KIND_ORDER = ["doc", "msg", "issue", "note", "mail", "cal", "memory", "scout", "careers"];
|
|
47
49
|
export async function runSearch(command, io) {
|
|
48
50
|
const door = await openAgentDoor("search", command, io);
|
|
51
|
+
// BLI-13027: the list the browser's Command-K chips are drawn from.
|
|
52
|
+
if (command.categories)
|
|
53
|
+
return await runCategories(door);
|
|
49
54
|
const params = new URLSearchParams({ q: command.query });
|
|
50
55
|
if (command.kinds && command.kinds.length > 0)
|
|
51
56
|
params.set("kinds", command.kinds.join(","));
|
|
@@ -64,6 +69,28 @@ export async function runSearch(command, io) {
|
|
|
64
69
|
return emitAgentDoor(door, body);
|
|
65
70
|
return render(door, body);
|
|
66
71
|
}
|
|
72
|
+
async function runCategories(door) {
|
|
73
|
+
const answer = await askAgentDoor(door, {
|
|
74
|
+
path: "/api/search?categories=1",
|
|
75
|
+
method: "GET",
|
|
76
|
+
label: "search categories",
|
|
77
|
+
timeoutMs: READ_DEADLINE_MS,
|
|
78
|
+
});
|
|
79
|
+
if (!answer.ok)
|
|
80
|
+
return failAgentDoor(door, TAG, answer.reason, answer.detail);
|
|
81
|
+
const body = answer.body;
|
|
82
|
+
if (door.json)
|
|
83
|
+
return emitAgentDoor(door, body);
|
|
84
|
+
const categories = body.categories ?? [];
|
|
85
|
+
writeLine(door.io.stdout, `${body.everything?.label ?? "Everything"} (searched when --kind is left out)`);
|
|
86
|
+
for (const entry of categories) {
|
|
87
|
+
const aliases = (entry.aliases ?? []).length > 0 ? ` (also: ${(entry.aliases ?? []).join(", ")})` : "";
|
|
88
|
+
writeLine(door.io.stdout, ` ${entry.kind} ${entry.label}${aliases}`);
|
|
89
|
+
}
|
|
90
|
+
writeLine(door.io.stdout, "");
|
|
91
|
+
writeLine(door.io.stdout, `${categories.length} categories. Name them with --kind, comma separated.`);
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
67
94
|
function render(door, body) {
|
|
68
95
|
const hits = body.hits ?? [];
|
|
69
96
|
const failures = body.failures ?? {};
|
|
@@ -76,7 +103,10 @@ function render(door, body) {
|
|
|
76
103
|
writeLine(door.io.stdout, "Nothing matched in the corpora that answered.");
|
|
77
104
|
}
|
|
78
105
|
}
|
|
79
|
-
|
|
106
|
+
// Known kinds in the usual order, then any kind this CLI has never heard of
|
|
107
|
+
// (a newer door than this build): printed, not swallowed.
|
|
108
|
+
const unknownKinds = [...new Set(hits.map((hit) => hit.kind))].filter((kind) => !KIND_ORDER.includes(kind));
|
|
109
|
+
for (const kind of [...KIND_ORDER, ...unknownKinds]) {
|
|
80
110
|
const group = hits.filter((hit) => hit.kind === kind);
|
|
81
111
|
if (group.length === 0)
|
|
82
112
|
continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.193",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@bli-cockpit/memory-mcp": "0.1.57",
|
|
31
|
-
"@bli-cockpit/mcp": "0.1.
|
|
31
|
+
"@bli-cockpit/mcp": "0.1.105",
|
|
32
32
|
"@bli-cockpit/telemetry-core": "0.1.66"
|
|
33
33
|
},
|
|
34
34
|
"repository": {
|