@bli-cockpit/cli 0.2.59 → 0.2.61
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/docs.js +5 -0
- package/dist/commands/jarvis-answer-envelope.js +2 -0
- package/dist/commands/jarvis-render.js +18 -0
- package/dist/commands/jarvis-turn.js +13 -1
- package/dist/commands/local-args-tower-chat.js +5 -0
- package/dist/commands/local-args-tower-docs-msg.js +10 -0
- package/dist/commands/local-args.js +4 -0
- package/dist/commands/local-help-commands.js +15 -3
- package/dist/commands/local-help.js +4 -2
- package/dist/commands/ops-render.js +5 -0
- package/dist/commands/ops.js +3 -1
- package/dist/commands/public-root.js +1 -1
- package/dist/commands/tower-mcp-install.js +4 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ normal user, on both macOS and Windows.
|
|
|
65
65
|
| Command | What it does | Why it exists / why this name |
|
|
66
66
|
|---|---|---|
|
|
67
67
|
| `cockpit onboard` | The named setup subset: signs you in (email code), registers this machine, starts capture, uploads once, completes all-history Codex and Claude backfill for saved approved roots, installs the 15-min background sync, and only then prints proof you're live. | You are boarding the crew. `do-everything` calls this flow when setup is missing; rerunning it directly is safe. Partial or failed backfill blocks readiness with an exact retry reason. |
|
|
68
|
-
| `cockpit do-everything` / `cockpit fix` | Converges a Mac or Windows PC from blank or already-onboarded state: latest CLI, signed-in device token, saved roots, autostart, historical backfill, raw-evidence GC, and fresh sync. Interactive first runs prompt for email OTP and collection roots; headless/`--json` runs explain and exit instead of blocking. `--dry-run` previews without writing. | Edward can post one line and every intern machine should end green. `fix` is the alias people guess. |
|
|
68
|
+
| `cockpit do-everything` / `cockpit fix` / `cockpit doctor` | Converges a Mac or Windows PC from blank or already-onboarded state: latest CLI, signed-in device token, saved roots, autostart, historical backfill, raw-evidence GC, and fresh sync. Interactive first runs prompt for email OTP and collection roots; headless/`--json` runs explain and exit instead of blocking. `--dry-run` previews without writing. | Edward can post one line and every intern machine should end green. `fix` is the alias people guess; `doctor` is the alias the ops board, the setup receipt and the heartbeat all tell you to run, and it is the same command (it checks each row, then fixes it). |
|
|
69
69
|
| `cockpit status` | Prints install / sign-in / capture / upload health in one screen. | The "is it working?" command. Run it whenever you're unsure. |
|
|
70
70
|
| `cockpit backfill --all` | Uploads your HISTORICAL Codex + Claude sessions (from before Cockpit existed on this machine). Discovery defaults to depth 3 and 50 repos; raise `--max-depth` or `--max-repos` when the returned retry command says a cap was reached. | One-time catch-up so your past work counts too. "Backfill" = fill in the back-catalog. |
|
|
71
71
|
| `cockpit sync` | Captures and uploads once, right now. This is what the background agent runs every 15 min — you almost never type it yourself. | Named for what it does: synchronize local session files up to the dashboard. |
|
package/dist/commands/docs.js
CHANGED
|
@@ -235,6 +235,11 @@ async function updateDoc(command, door) {
|
|
|
235
235
|
...(bodyMarkdown !== undefined ? { body_markdown: bodyMarkdown } : {}),
|
|
236
236
|
...(command.visibility !== undefined ? { visibility: command.visibility } : {}),
|
|
237
237
|
...(command.clearParent ? { parent_id: null } : command.parentId ? { parent_id: command.parentId } : {}),
|
|
238
|
+
// BLI-3759: only ever sent when the operator asked for it. Without the
|
|
239
|
+
// key, a body that would empty a document holding text comes back as the
|
|
240
|
+
// door's own `refused_empty_body` (409), which `failAgentDoor` prints
|
|
241
|
+
// verbatim — the CLI never rephrases it and never retries with the flag.
|
|
242
|
+
...(command.allowEmpty ? { allow_empty: true } : {}),
|
|
238
243
|
},
|
|
239
244
|
});
|
|
240
245
|
if (!answer.ok)
|
|
@@ -39,6 +39,7 @@ export const JARVIS_ANSWER_ENVELOPE_KEYS = [
|
|
|
39
39
|
"turn_id",
|
|
40
40
|
"thread_id",
|
|
41
41
|
"trace_thread_id",
|
|
42
|
+
"proposal_id",
|
|
42
43
|
"degraded",
|
|
43
44
|
"degraded_reasons",
|
|
44
45
|
];
|
|
@@ -74,6 +75,7 @@ export function buildJarvisAnswerEnvelope(input) {
|
|
|
74
75
|
turn_id: turnId,
|
|
75
76
|
thread_id: input.thread ?? null,
|
|
76
77
|
trace_thread_id: input.traceThread ?? null,
|
|
78
|
+
proposal_id: input.proposalId ?? null,
|
|
77
79
|
degraded: reasons.length > 0,
|
|
78
80
|
degraded_reasons: reasons,
|
|
79
81
|
};
|
|
@@ -37,6 +37,19 @@ export function validatePrompt(raw) {
|
|
|
37
37
|
* (BLI-3414) — same field names the request handler parses, mirroring the
|
|
38
38
|
* JSON body's fields plus one `image` file field.
|
|
39
39
|
*/
|
|
40
|
+
/**
|
|
41
|
+
* Whether a PROGRAM is reading this turn's answer (BLI-3755).
|
|
42
|
+
*
|
|
43
|
+
* `--json` is a script's contract, and the coding arm's approval gate assumes
|
|
44
|
+
* the code it hands back reaches a person. So a `--json` turn declares itself
|
|
45
|
+
* an agent surface and JARVIS answers with a proposal id in place of the code;
|
|
46
|
+
* `--show-approval-code` opts a script that really is driving a dispatch for a
|
|
47
|
+
* human back in, and the terminal logs that it did. An interactive turn is
|
|
48
|
+
* always a person's and never sends this.
|
|
49
|
+
*/
|
|
50
|
+
export function agentSurface(command) {
|
|
51
|
+
return command.json === true && command.showApprovalCode !== true;
|
|
52
|
+
}
|
|
40
53
|
export function buildAttachmentForm(command, prompt, attachment) {
|
|
41
54
|
const form = new FormData();
|
|
42
55
|
form.set("question", prompt);
|
|
@@ -47,6 +60,11 @@ export function buildAttachmentForm(command, prompt, attachment) {
|
|
|
47
60
|
form.set("model", command.model);
|
|
48
61
|
if (command.date)
|
|
49
62
|
form.set("date", command.date);
|
|
63
|
+
// BLI-3755: an attached-image turn is still a turn on some surface, and the
|
|
64
|
+
// coding arm rides the same belt — dropping this here would hand a code to a
|
|
65
|
+
// program that sent a screenshot.
|
|
66
|
+
if (agentSurface(command))
|
|
67
|
+
form.set("surface", "agent");
|
|
50
68
|
form.set("image", new File([attachment.bytes], attachment.fileName, { type: attachment.mimeType }));
|
|
51
69
|
return form;
|
|
52
70
|
}
|
|
@@ -12,7 +12,7 @@ import { readAttachedImage } from "./jarvis-attachment.js";
|
|
|
12
12
|
import { rememberTurnTrace } from "./jarvis-trace.js";
|
|
13
13
|
import { towerFailureDetail, towerJsonRequest, towerRequest } from "../tower-client.js";
|
|
14
14
|
import { readTowerTurn, streamFailureDetail } from "../tower-stream.js";
|
|
15
|
-
import { activityToTrace, ANSWER_UPDATING_LINE, buildAttachmentForm, clientTimingFields, createLiveAnswer, latencyFields, latencyLogFields, TURN_DEADLINE_MS, writeActivityLine, writeAttachmentRefusal, writeFailure, writeModelReceipt, writeRevision, writeTraceBlock, } from "./jarvis-render.js";
|
|
15
|
+
import { activityToTrace, agentSurface, ANSWER_UPDATING_LINE, buildAttachmentForm, clientTimingFields, createLiveAnswer, latencyFields, latencyLogFields, TURN_DEADLINE_MS, writeActivityLine, writeAttachmentRefusal, writeFailure, writeModelReceipt, writeRevision, writeTraceBlock, } from "./jarvis-render.js";
|
|
16
16
|
export async function sendOneTurn(context, prompt, io) {
|
|
17
17
|
const startedAt = Date.now();
|
|
18
18
|
// BLI-3414: an attached file is read and locally screened (exists,
|
|
@@ -41,6 +41,11 @@ export async function sendOneTurn(context, prompt, io) {
|
|
|
41
41
|
// all three are named. If this number is ever large, the step that made it
|
|
42
42
|
// large is on the same line.
|
|
43
43
|
const preRequestMs = Date.now() - startedAt;
|
|
44
|
+
// BLI-3755: never silently. A script that asked for the code is a script
|
|
45
|
+
// that can spend a human's approval, and the one line saying so is here.
|
|
46
|
+
if (context.command.json && context.command.showApprovalCode) {
|
|
47
|
+
log("[jarvis] approval code requested by a --json caller (--show-approval-code)");
|
|
48
|
+
}
|
|
44
49
|
const requested = await towerRequest({
|
|
45
50
|
dashboardUrl: context.dashboardUrl,
|
|
46
51
|
path: "/api/jarvis/cli",
|
|
@@ -65,6 +70,12 @@ export async function sendOneTurn(context, prompt, io) {
|
|
|
65
70
|
// there is nothing above to revise.
|
|
66
71
|
previousAnswer: context.previous?.answer,
|
|
67
72
|
previousQuestion: context.previous?.question,
|
|
73
|
+
// BLI-3755: who is reading this answer. A `--json` turn is a
|
|
74
|
+
// PROGRAM's, so the coding arm withholds its approval code and
|
|
75
|
+
// answers with a proposal id instead; an interactive turn is a
|
|
76
|
+
// person's and is unchanged. `--show-approval-code` opts a script
|
|
77
|
+
// back in, and says so on stderr below.
|
|
78
|
+
surface: agentSurface(context.command) ? "agent" : undefined,
|
|
68
79
|
},
|
|
69
80
|
log,
|
|
70
81
|
});
|
|
@@ -146,6 +157,7 @@ export async function sendOneTurn(context, prompt, io) {
|
|
|
146
157
|
modelFallback: body.model?.fallback,
|
|
147
158
|
revised: body.revised,
|
|
148
159
|
trace,
|
|
160
|
+
proposalId: body.proposalId,
|
|
149
161
|
}),
|
|
150
162
|
reply: body.reply,
|
|
151
163
|
thread: body.thread ?? context.command.thread,
|
|
@@ -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,6 +17,7 @@ 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",
|
|
@@ -55,6 +56,14 @@ export function parseDocsArgs(args) {
|
|
|
55
56
|
if (clearParent && action !== "update") {
|
|
56
57
|
throw new Error("--clear-parent belongs to `cockpit docs update`.");
|
|
57
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
|
+
}
|
|
58
67
|
const title = optionalNonEmpty(values.flags.get("--title"));
|
|
59
68
|
if (action === "create" && !title) {
|
|
60
69
|
throw new Error("docs create needs --title.");
|
|
@@ -80,6 +89,7 @@ export function parseDocsArgs(args) {
|
|
|
80
89
|
title,
|
|
81
90
|
...(parentId ? { parentId } : {}),
|
|
82
91
|
clearParent,
|
|
92
|
+
...(allowEmpty ? { allowEmpty } : {}),
|
|
83
93
|
visibility: visibility,
|
|
84
94
|
filePath: optionalNonEmpty(values.flags.get("--file")),
|
|
85
95
|
bodyStdin: values.booleans.has("--body-stdin"),
|
|
@@ -41,6 +41,10 @@ export function parseLocalArgs(argv) {
|
|
|
41
41
|
// Aliasing lands once the convergence run honours --ticket. See BLI-2494.
|
|
42
42
|
case "do-everything":
|
|
43
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":
|
|
44
48
|
return parseDoctorArgs(command, argv.slice(1));
|
|
45
49
|
case "install":
|
|
46
50
|
return parseInstallArgs(argv.slice(1));
|
|
@@ -78,6 +78,16 @@ export function localSubcommandHelp(command) {
|
|
|
78
78
|
"Alias for `cockpit do-everything`.",
|
|
79
79
|
],
|
|
80
80
|
],
|
|
81
|
+
[
|
|
82
|
+
"doctor",
|
|
83
|
+
[
|
|
84
|
+
"Usage: cockpit doctor [same flags as cockpit do-everything]",
|
|
85
|
+
"",
|
|
86
|
+
"Alias for `cockpit do-everything`. It checks this machine row by row —",
|
|
87
|
+
"CLI version, sign-in, saved folders, background sync, backfill, disk — and",
|
|
88
|
+
"fixes each row it can. `--dry-run` prints the diagnosis and changes nothing.",
|
|
89
|
+
],
|
|
90
|
+
],
|
|
81
91
|
[
|
|
82
92
|
"login",
|
|
83
93
|
[
|
|
@@ -227,7 +237,7 @@ export function localSubcommandHelp(command) {
|
|
|
227
237
|
[
|
|
228
238
|
"jarvis",
|
|
229
239
|
[
|
|
230
|
-
"Usage: cockpit jarvis [question] [--prompt <question>] [--as <person>] [--date <YYYY-MM-DD>] [--thread <name>] [--model <key>] [--image <path>|--file <path>] [--no-stream] [--threads|--history [--limit <n>]] [--trace <id|last>] [--dashboard-url <url>] [--json]",
|
|
240
|
+
"Usage: cockpit jarvis [question] [--prompt <question>] [--as <person>] [--date <YYYY-MM-DD>] [--thread <name>] [--model <key>] [--image <path>|--file <path>] [--no-stream] [--threads|--history [--limit <n>]] [--trace <id|last>] [--dashboard-url <url>] [--json [--show-approval-code]]",
|
|
231
241
|
"",
|
|
232
242
|
"Chats with the same JARVIS used by Tower web chat and the BLI Slack DM.",
|
|
233
243
|
"--as selects the existing website person space; it changes who the chat is about, never who is authenticated.",
|
|
@@ -239,7 +249,8 @@ export function localSubcommandHelp(command) {
|
|
|
239
249
|
"Each answer prints a per-tool trace line and, only on a fallback or model mismatch, one model receipt line.",
|
|
240
250
|
"Trace lines arrive live while JARVIS works; pass --no-stream to wait for the whole answer in one piece instead.",
|
|
241
251
|
"--json writes one machine-readable response (including trace and model) to stdout; operational metadata stays on stderr. A --json run never streams fragments, whichever mode it is in.",
|
|
242
|
-
"
|
|
252
|
+
"A --json turn is treated as an AGENT surface: if it proposes a coding task, JARVIS answers with proposal_id and NOT the eight-character approval code, because a code a program can read is a code it could approve with. The person fetches the code themself — a Tower browser tab, their Slack DM, or an interactive `cockpit jarvis` — and hands it back. Pass --show-approval-code when a script really is driving a dispatch for a person; the run says on stderr that it did.",
|
|
253
|
+
"That object carries answer, sources (the Source: lines inside it), turn_id (pass it to --trace), thread_id (pass it to --thread), proposal_id (the coding-arm proposal this turn made, or null), degraded and degraded_reasons — the SAME shape the bli-tower MCP server's jarvis_ask tool returns, so a script and an agent read one contract. reply/thread/traceId/model/trace/latency are still there beside it and still mean what they always meant.",
|
|
243
254
|
"A turn that outlives the dashboard's own ceiling is reported as turn_timed_out — an incomplete answer is never printed as a finished one.",
|
|
244
255
|
"The command uses the existing paired device identity. It cannot override the caller, team, role, or person scope.",
|
|
245
256
|
"--threads lists the terminal conversations on this account; --thread <name> --history replays one (the newest --limit <n> messages). Neither takes a question, and neither can reach anybody else's conversations.",
|
|
@@ -540,7 +551,8 @@ export function localSubcommandHelp(command) {
|
|
|
540
551
|
"tree — the same documents nested under their parent, for a sidebar-shaped view.",
|
|
541
552
|
"read <id|slug> — one document's title, slug, visibility, and its body. This is the ONLY verb that returns a body.",
|
|
542
553
|
"create --title \"<title>\" [--parent <id>] [--visibility org|private] [--file <path>|--body-stdin] — the body comes from --file, or stdin (`cat body.md | cockpit docs create --title \"...\"`); neither means an empty body, matching the browser's own default.",
|
|
543
|
-
"update <id|slug> [--title \"<t>\"] [--visibility org|private] [--parent <id>|--clear-parent] [--file <path>|--body-stdin] — only the fields you pass change; a `--parent` change IS a move, there is no separate move verb.",
|
|
554
|
+
"update <id|slug> [--title \"<t>\"] [--visibility org|private] [--parent <id>|--clear-parent] [--file <path>|--body-stdin] [--allow-empty] — only the fields you pass change; a `--parent` change IS a move, there is no separate move verb.",
|
|
555
|
+
" --allow-empty clears the page on purpose. A body that would empty a document that holds text is refused (refused_empty_body) unless you say so, because far more often it is a surface that lost the content than a person who meant it.",
|
|
544
556
|
"A document body is never accepted on the command line — --file (safest on Windows) or a pipe only, same discipline as `cockpit notes paste`.",
|
|
545
557
|
"--json writes one machine-readable object to stdout; every reason and receipt line stays on stderr.",
|
|
546
558
|
"A refusal keeps Tower's own reason label — needs_rls_client, document_not_found_or_unreadable, document_not_writable, slug_taken, circular_parent, and so on.",
|
|
@@ -15,6 +15,7 @@ export const rootCommandNames = new Set([
|
|
|
15
15
|
"upgrade",
|
|
16
16
|
"do-everything",
|
|
17
17
|
"fix",
|
|
18
|
+
"doctor",
|
|
18
19
|
"install",
|
|
19
20
|
"login",
|
|
20
21
|
"pair",
|
|
@@ -57,6 +58,7 @@ export function localCommandHelp(command) {
|
|
|
57
58
|
" cockpit upgrade [same flags as update]",
|
|
58
59
|
" cockpit do-everything [--workspace <path>] [--dashboard-url <url>] [--update-tag <tag>] [--dry-run] [--json]",
|
|
59
60
|
" cockpit fix [same flags as do-everything]",
|
|
61
|
+
" cockpit doctor [same flags as do-everything]",
|
|
60
62
|
" cockpit install [--dashboard-url <url>] [--workspace <path>] [--allow-home-root] [--json]",
|
|
61
63
|
" cockpit login [--pair <code>] [--no-browser] [--legacy-pair] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--no-auth] [--json]",
|
|
62
64
|
" cockpit pair [--pair <code>] [--no-browser] [--legacy-pair] [--email <owner@email>] [--device-name <name>] [--dashboard-url <url>] [--no-auth] [--json]",
|
|
@@ -64,7 +66,7 @@ export function localCommandHelp(command) {
|
|
|
64
66
|
" cockpit start [--ticket <id>|--clear-ticket] [--topic <label>] [--intent <intent>] [--phase <phase>] [--workspace <path>] [--branch <name>] [--max-depth <n>] [--max-repos <n>] [--json]",
|
|
65
67
|
" cockpit sync [--workspace <path>] [--dashboard-url <url>] [--max-depth <n>] [--max-repos <n>] [--json]",
|
|
66
68
|
" cockpit analyze [--workspace <path>] [--dashboard-url <url>] [--max-depth <n>] [--max-repos <n>] [--json]",
|
|
67
|
-
" cockpit jarvis [question] [--prompt <question>] [--as <person>] [--date <YYYY-MM-DD>] [--thread <name>] [--model <key>] [--image <path>|--file <path>] [--no-stream] [--threads|--history [--limit <n>]] [--trace <id|last>] [--dashboard-url <url>] [--json]",
|
|
69
|
+
" cockpit jarvis [question] [--prompt <question>] [--as <person>] [--date <YYYY-MM-DD>] [--thread <name>] [--model <key>] [--image <path>|--file <path>] [--no-stream] [--threads|--history [--limit <n>]] [--trace <id|last>] [--dashboard-url <url>] [--json [--show-approval-code]]",
|
|
68
70
|
" cockpit model [show|set <provider:model>] [--json]",
|
|
69
71
|
" cockpit scout [start|dismiss|undo <experiment-id>] [--days <n>] [--dashboard-url <url>] [--json]",
|
|
70
72
|
" cockpit ops [status [--job <id>] [--skips] [--memory] | recompile --person <email|name|id> [--dry-run]] [--dashboard-url <url>] [--json]",
|
|
@@ -84,7 +86,7 @@ export function localCommandHelp(command) {
|
|
|
84
86
|
" cockpit agent-rules [install|uninstall|status] [--host codex|claude|all] [--workspace <path>] [--json]",
|
|
85
87
|
" cockpit memory [install|status] [--dashboard-url <url>] [--dry-run] [--json]",
|
|
86
88
|
" cockpit clean [--dry-run] [--all-committed] [--reconcile] [--dashboard-url <url>] [--json]",
|
|
87
|
-
" cockpit docs [list|tree|read <id|slug>|create --title <t>|update <id>] [--parent <id>|root|--clear-parent] [--query <text>] [--limit <n>] [--visibility org|private] [--file <path>|--body-stdin] [--dashboard-url <url>] [--json]",
|
|
89
|
+
" cockpit docs [list|tree|read <id|slug>|create --title <t>|update <id>] [--parent <id>|root|--clear-parent] [--query <text>] [--limit <n>] [--visibility org|private] [--file <path>|--body-stdin] [--allow-empty] [--dashboard-url <url>] [--json]",
|
|
88
90
|
" cockpit msg [channels|create <name>|dm <email>|read <channel>|send <channel>|thread <id> --channel <channel>] [--private] [--members a@x,b@y] [--description <text>] [--thread <id>] [--limit <n>] [--dashboard-url <url>] [--json]",
|
|
89
91
|
" cockpit issue [list|show <BLI-id>|create --title <t>|update <BLI-id>|move <BLI-id> <state>|comment <BLI-id>|history <BLI-id>] [--state <s>] [--assignee me|unassigned|<uuid>] [--project <name|id>] [--limit <n>] [--priority 0-4] [--parent <BLI-id>] [--file <path>|--body-stdin] [--dashboard-url <url>] [--json]",
|
|
90
92
|
" cockpit project [list] [--archived] [--dashboard-url <url>] [--json]",
|
|
@@ -25,6 +25,11 @@ export function verdictWord(verdict) {
|
|
|
25
25
|
// rather than to a cron config.
|
|
26
26
|
case "failing":
|
|
27
27
|
return "BAD";
|
|
28
|
+
// BLI-3762. Between "on time" and "dead": the job ran, produced something,
|
|
29
|
+
// and produced LESS than it owed. A partial result that is still moving
|
|
30
|
+
// needs a different next step from either neighbour, so it gets a word.
|
|
31
|
+
case "degraded":
|
|
32
|
+
return "PART";
|
|
28
33
|
case "never_produced":
|
|
29
34
|
return "EMPTY";
|
|
30
35
|
case "unreadable":
|
package/dist/commands/ops.js
CHANGED
|
@@ -75,7 +75,9 @@ async function runOpsStatus(command, io, tower) {
|
|
|
75
75
|
const unhealthy = rows.filter((row) => row.verdict === "stale" ||
|
|
76
76
|
row.verdict === "never_produced" ||
|
|
77
77
|
row.verdict === "unreadable" ||
|
|
78
|
-
row.verdict === "failing"
|
|
78
|
+
row.verdict === "failing" ||
|
|
79
|
+
// BLI-3762: a job that ran and wrote less than it owed is not healthy.
|
|
80
|
+
row.verdict === "degraded");
|
|
79
81
|
if (command.json) {
|
|
80
82
|
writeLine(io.stdout, JSON.stringify(memory ? { ...payload, memory: memory.section } : payload));
|
|
81
83
|
}
|
|
@@ -15,7 +15,7 @@ export async function runCockpitCli(argv, io) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
if (command === "--version" || command === "-V" || command === "version") {
|
|
18
|
-
writeLine(io?.stdout ?? process.stdout, "0.2.
|
|
18
|
+
writeLine(io?.stdout ?? process.stdout, "0.2.61");
|
|
19
19
|
return 0;
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
* verb: that command already runs unasked from `do-everything` and the daily
|
|
7
7
|
* sync tick (`memory-install.ts`'s own header), which is the ONLY way a
|
|
8
8
|
* registration reaches every intern machine without anyone typing anything.
|
|
9
|
-
* A second, un-invoked `
|
|
9
|
+
* A second, un-invoked `mcp install` verb of its own would ship the feature
|
|
10
10
|
* and still leave every existing machine unregistered until someone learned
|
|
11
|
-
* to type
|
|
11
|
+
* to type it. (Deliberately not written as a `cockpit ...` invocation here:
|
|
12
|
+
* BLI-3768's census refuses any spelled-out command the router would answer
|
|
13
|
+
* `Unknown command` to, and this one is a road not taken.)
|
|
12
14
|
*
|
|
13
15
|
* `no_bin_no_write` applies here too, for the identical reason
|
|
14
16
|
* `memory-install.ts` states it for `bli-memory-mcp`: a Claude Code entry
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.61",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"test": "node dist/cli.js --help && node ../../scripts/assert-public-cli-routing.mjs && node ../../scripts/assert-public-cli-runtime-files.mjs && node ../../scripts/assert-public-cli-no-fleet-posts.mjs && node ../../scripts/assert-public-package-pack.mjs --workspace=@bli-cockpit/cli"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@bli-cockpit/memory-mcp": "0.1.
|
|
31
|
-
"@bli-cockpit/mcp": "0.1.
|
|
30
|
+
"@bli-cockpit/memory-mcp": "0.1.8",
|
|
31
|
+
"@bli-cockpit/mcp": "0.1.4",
|
|
32
32
|
"@bli-cockpit/telemetry-core": "0.1.29"
|
|
33
33
|
}
|
|
34
34
|
}
|