@bli-cockpit/cli 0.2.161 → 0.2.162
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-rename.js +48 -0
- package/dist/commands/local-args-tower.js +2 -1
- package/dist/commands/local-args.js +3 -1
- package/dist/commands/local-help-commands-tower.js +11 -0
- package/dist/commands/local-help.js +2 -0
- package/dist/commands/local.js +3 -0
- package/dist/commands/public-root.js +1 -1
- package/dist/commands/rename-scope.js +57 -0
- package/package.json +2 -2
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { optionalNonEmpty, optionalUrl, parseNamedArgs } from "./local-arg-values.js";
|
|
2
|
+
export const RENAME_SCOPES = ["page", "everywhere", "undo"];
|
|
3
|
+
export function parseRenameArgs(args) {
|
|
4
|
+
const values = parseNamedArgs(args, {
|
|
5
|
+
allowedFlags: ["--home", "--dashboard-url", "--scope", "--wrong", "--right", "--json"],
|
|
6
|
+
valueFlags: ["--home", "--dashboard-url", "--scope", "--wrong", "--right"],
|
|
7
|
+
});
|
|
8
|
+
const positionals = [...values.positionals];
|
|
9
|
+
const typed = positionals.shift() ?? "list";
|
|
10
|
+
if (typed !== "list" && typed !== "resolve") {
|
|
11
|
+
throw new Error(`Unknown rename command: ${typed}. Try list, or resolve <id> --scope page|everywhere|undo.`);
|
|
12
|
+
}
|
|
13
|
+
const id = positionals.shift();
|
|
14
|
+
// An OLD rule has no open choice and so no id: `--wrong X --right Y --scope
|
|
15
|
+
// undo` names it by its pair and removes the caller's own row.
|
|
16
|
+
const wrong = optionalNonEmpty(values.flags.get("--wrong"));
|
|
17
|
+
const right = optionalNonEmpty(values.flags.get("--right"));
|
|
18
|
+
const byPair = typed === "resolve" && !id && wrong !== undefined && right !== undefined;
|
|
19
|
+
if (typed === "resolve" && !id && !byPair) {
|
|
20
|
+
throw new Error("rename resolve needs the id from `cockpit rename list`, or --wrong and --right with --scope undo.");
|
|
21
|
+
}
|
|
22
|
+
if ((wrong !== undefined || right !== undefined) && (typed !== "resolve" || id || wrong === undefined || right === undefined)) {
|
|
23
|
+
throw new Error("--wrong and --right go together, on `cockpit rename resolve --scope undo`, instead of an id.");
|
|
24
|
+
}
|
|
25
|
+
if (positionals.length > 0 || (typed === "list" && id)) {
|
|
26
|
+
throw new Error(`rename ${typed} does not take "${typed === "list" ? id : positionals[0]}".`);
|
|
27
|
+
}
|
|
28
|
+
const scope = optionalNonEmpty(values.flags.get("--scope"));
|
|
29
|
+
if (typed === "resolve" && (!scope || !RENAME_SCOPES.includes(scope))) {
|
|
30
|
+
throw new Error(`rename resolve needs --scope ${RENAME_SCOPES.join("|")}.`);
|
|
31
|
+
}
|
|
32
|
+
if (byPair && scope !== "undo") {
|
|
33
|
+
throw new Error("--wrong and --right name a rule that already exists, so they take --scope undo only.");
|
|
34
|
+
}
|
|
35
|
+
if (typed === "list" && scope) {
|
|
36
|
+
throw new Error("--scope belongs to `cockpit rename resolve`.");
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
kind: "rename",
|
|
40
|
+
action: typed,
|
|
41
|
+
...(id ? { id } : {}),
|
|
42
|
+
...(scope ? { scope: scope } : {}),
|
|
43
|
+
...(byPair ? { wrongForm: wrong, canonicalForm: right } : {}),
|
|
44
|
+
homeDir: optionalNonEmpty(values.flags.get("--home")),
|
|
45
|
+
dashboardUrl: optionalUrl(values.flags.get("--dashboard-url")),
|
|
46
|
+
json: values.booleans.has("--json"),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -37,4 +37,5 @@ export { parseModelsArgs } from "./local-args-tower-models.js";
|
|
|
37
37
|
export { parseMailArgs } from "./local-args-tower-mail.js";
|
|
38
38
|
export { parseCalArgs } from "./local-args-tower-cal.js";
|
|
39
39
|
export { parseUsageArgs } from "./local-args-tower-usage.js";
|
|
40
|
-
export { parseCareersArgs } from './local-args-tower-careers.js';
|
|
40
|
+
export { parseCareersArgs } from './local-args-tower-careers.js';
|
|
41
|
+
export { parseRenameArgs } from './local-args-tower-rename.js';
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { parseRootsArgs } from "./roots.js";
|
|
19
19
|
import { SURFACE_ALIASES } from "./local-help.js";
|
|
20
20
|
import { parseAgentRulesArgs, parseAnalyzeArgs, parseAutostartArgs, parseBackfillArgs, parseCleanArgs, parseDoctorArgs, parseInstallArgs, parseLoginArgs, parseMemoryArgs, parseLogoutArgs, parseOnboardArgs, parseReleaseArgs, parseServeArgs, parseSessionsArgs, parseSourcesArgs, parseStartArgs, parseStatusArgs, parseSyncArgs, parseUpdateArgs, } from "./local-args-collector.js";
|
|
21
|
-
import { parseBriefArgs, parseCorrectArgs, parseDocsArgs, parseIssueArgs, parseJarvisArgs, parseMailArgs, parseCalArgs, parseModelArgs, parseMsgArgs, parseNotesArgs, parseOpsArgs, parseProjectArgs, parseModelsArgs, parseScoutArgs, parseSearchArgs, parseSettingsArgs, parseSlackArgs, parseTeamArgs, parseWorkbookArgs, parseUsageArgs, parseCareersArgs, } from "./local-args-tower.js";
|
|
21
|
+
import { parseBriefArgs, parseCorrectArgs, parseDocsArgs, parseIssueArgs, parseJarvisArgs, parseMailArgs, parseCalArgs, parseModelArgs, parseMsgArgs, parseNotesArgs, parseOpsArgs, parseProjectArgs, parseModelsArgs, parseScoutArgs, parseSearchArgs, parseSettingsArgs, parseSlackArgs, parseTeamArgs, parseWorkbookArgs, parseUsageArgs, parseCareersArgs, parseRenameArgs, } from "./local-args-tower.js";
|
|
22
22
|
// `normalizeUrl` has always been part of this module's surface — `local.ts` and
|
|
23
23
|
// `local-auth.ts` import it from here — so it stays exported from this address
|
|
24
24
|
// even though it now lives next door. The same goes for the four names the
|
|
@@ -127,6 +127,8 @@ export function parseLocalArgs(argv) {
|
|
|
127
127
|
return parseReleaseArgs(argv.slice(1));
|
|
128
128
|
case "careers":
|
|
129
129
|
return parseCareersArgs(argv.slice(1));
|
|
130
|
+
case "rename":
|
|
131
|
+
return parseRenameArgs(argv.slice(1));
|
|
130
132
|
case "usage":
|
|
131
133
|
return parseUsageArgs(argv.slice(1));
|
|
132
134
|
default:
|
|
@@ -22,6 +22,17 @@ const SEARCH_KIND_LIST = SEARCH_KINDS.join(",");
|
|
|
22
22
|
const SEARCH_CORPORA_COUNT = SEARCH_KINDS.length;
|
|
23
23
|
/** One entry per Tower noun, in the order `cockpit --help` lists them. */
|
|
24
24
|
export const TOWER_COMMAND_HELP = [
|
|
25
|
+
[
|
|
26
|
+
"rename",
|
|
27
|
+
[
|
|
28
|
+
"Usage: cockpit rename [list|resolve <id> --scope <page|everywhere|undo>] [--dashboard-url <url>] [--json]",
|
|
29
|
+
"",
|
|
30
|
+
"A correction JARVIS cannot classify is fixed on ONE page and waits for your call: just this page, or everywhere from now on. A bare `cockpit rename` lists what is waiting.",
|
|
31
|
+
"resolve <id> --scope page — keep it a one-page fix. everywhere — write the rule and fix every other page. undo — take back a rule JARVIS applied on its own (yours only, unless you are a super admin).",
|
|
32
|
+
"An OLD rule has no open choice: `cockpit rename resolve --wrong <form> --right <form> --scope undo` removes your own row for that pair (a super admin may remove anyone's).",
|
|
33
|
+
"A fact (a status, a date, a number) is never made a rule, whatever is asked. The same door answers the panel's two buttons, a spoken answer, `cockpit jarvis` and the rename_* MCP tools.",
|
|
34
|
+
],
|
|
35
|
+
],
|
|
25
36
|
[
|
|
26
37
|
"careers",
|
|
27
38
|
[
|
|
@@ -75,6 +75,7 @@ export const rootCommandNames = new Set([
|
|
|
75
75
|
"search",
|
|
76
76
|
"release",
|
|
77
77
|
"careers",
|
|
78
|
+
"rename",
|
|
78
79
|
"usage",
|
|
79
80
|
...SURFACE_ALIASES.keys(),
|
|
80
81
|
]);
|
|
@@ -128,6 +129,7 @@ export function localCommandHelp(command) {
|
|
|
128
129
|
` cockpit search "<words>" [--kind ${SEARCH_KINDS.join(",")}] [--limit <n>] [--dashboard-url <url>] [--json]`,
|
|
129
130
|
" cockpit release [--dry-run] [--skip-checks] [--no-floor] [--tag <tag>] [--access <public|restricted>] [--otp <code>]",
|
|
130
131
|
" 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]",
|
|
132
|
+
" cockpit rename [list|resolve <id> --scope <page|everywhere|undo>] [--dashboard-url <url>] [--json]",
|
|
131
133
|
" cockpit usage sessions [--task <BLI-NNNN> | --subject <name>] [--repo <label>] [--since <window>] [--json]",
|
|
132
134
|
" cockpit usage sessions --session <id> [--from-window <n>] [--json]",
|
|
133
135
|
" --by-topic groups work types; --by-subject groups open subjects from session summaries.",
|
package/dist/commands/local.js
CHANGED
|
@@ -46,6 +46,7 @@ import { runMail } from "./mail.js";
|
|
|
46
46
|
import { runProject } from "./project.js";
|
|
47
47
|
import { runSearch } from "./search.js";
|
|
48
48
|
import { runCareers } from "./careers.js";
|
|
49
|
+
import { runRename } from "./rename-scope.js";
|
|
49
50
|
import { runUsage } from "./usage.js";
|
|
50
51
|
import { parseLocalArgs } from "./local-args.js";
|
|
51
52
|
// `./local.js` is the published entry point for this command surface: the
|
|
@@ -234,6 +235,8 @@ export async function runLocalCockpitCli(argv, io = defaultIo()) {
|
|
|
234
235
|
return await runRelease(command, io);
|
|
235
236
|
case "careers":
|
|
236
237
|
return await runCareers(command, io);
|
|
238
|
+
case "rename":
|
|
239
|
+
return await runRename(command, io);
|
|
237
240
|
case "usage":
|
|
238
241
|
return await runUsage(command, io);
|
|
239
242
|
}
|
|
@@ -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.162");
|
|
25
25
|
return 0;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cockpit rename list` / `cockpit rename resolve <id> --scope ...` (BLI-12378).
|
|
3
|
+
*
|
|
4
|
+
* The terminal twin of the panel's two buttons, over the same door
|
|
5
|
+
* (`/api/jarvis/rename-scope`) with the same device token. The door's reply
|
|
6
|
+
* sentence is printed as it is: it is the one JARVIS says everywhere.
|
|
7
|
+
*
|
|
8
|
+
* Metadata only in the logs: the ids and counts, never the words being renamed.
|
|
9
|
+
*/
|
|
10
|
+
import { askAgentDoor, emitAgentDoor, failAgentDoor, openAgentDoor } from "./agent-door.js";
|
|
11
|
+
import { writeLine } from "./cli-io.js";
|
|
12
|
+
const TAG = "[rename cli]";
|
|
13
|
+
const DEADLINE_MS = 120_000;
|
|
14
|
+
export async function runRename(command, io) {
|
|
15
|
+
const door = await openAgentDoor("rename", command, io);
|
|
16
|
+
const listing = command.action === "list";
|
|
17
|
+
const answer = await askAgentDoor(door, {
|
|
18
|
+
path: "/api/jarvis/rename-scope",
|
|
19
|
+
method: listing ? "GET" : "POST",
|
|
20
|
+
label: `rename ${command.action}`,
|
|
21
|
+
timeoutMs: DEADLINE_MS,
|
|
22
|
+
...(listing
|
|
23
|
+
? {}
|
|
24
|
+
: {
|
|
25
|
+
body: command.id
|
|
26
|
+
? { pendingId: command.id, choice: command.scope }
|
|
27
|
+
: { wrongForm: command.wrongForm, canonicalForm: command.canonicalForm, choice: command.scope },
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
if (!answer.ok)
|
|
31
|
+
return failAgentDoor(door, TAG, answer.reason, answer.detail);
|
|
32
|
+
const body = answer.body;
|
|
33
|
+
// An HTTP 200 with no recognisable shape is a dashboard that has not shipped
|
|
34
|
+
// this door, not an empty list.
|
|
35
|
+
if (listing ? !Array.isArray(body.pending) : typeof body.reply !== "string") {
|
|
36
|
+
return failAgentDoor(door, TAG, "rename_answer_unreadable", "Tower answered 200 with no rename receipt in it. The usual cause is a dashboard that has not shipped /api/jarvis/rename-scope yet; nothing was changed.");
|
|
37
|
+
}
|
|
38
|
+
writeLine(door.io.stderr, `${TAG} ${command.action} ${JSON.stringify({ open: body.pending?.length ?? null, ok: body.ok ?? null, scope: command.scope ?? null })}`);
|
|
39
|
+
if (door.json)
|
|
40
|
+
return emitAgentDoor(door, answer.body);
|
|
41
|
+
if (listing) {
|
|
42
|
+
const open = body.pending ?? [];
|
|
43
|
+
if (open.length === 0) {
|
|
44
|
+
writeLine(door.io.stdout, "No correction is waiting on you. Nothing was made a rule without a yes.");
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
for (const row of open) {
|
|
48
|
+
const what = row.kind === "undo" ? "applied everywhere, can be undone" : "this page only, waiting for your call";
|
|
49
|
+
writeLine(door.io.stdout, `${row.id} “${row.wrongForm}” -> ${row.canonicalForm} (${what})`);
|
|
50
|
+
}
|
|
51
|
+
writeLine(door.io.stdout, "");
|
|
52
|
+
writeLine(door.io.stdout, "Answer one with: cockpit rename resolve <id> --scope page|everywhere|undo");
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
writeLine(door.io.stdout, body.reply);
|
|
56
|
+
return body.ok === false ? 1 : 0;
|
|
57
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.162",
|
|
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.45",
|
|
31
|
-
"@bli-cockpit/mcp": "0.1.
|
|
31
|
+
"@bli-cockpit/mcp": "0.1.80",
|
|
32
32
|
"@bli-cockpit/telemetry-core": "0.1.57"
|
|
33
33
|
},
|
|
34
34
|
"repository": {
|