@bli-cockpit/cli 0.2.69 → 0.2.72
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/doctor-disk-words.js +59 -0
- package/dist/commands/doctor-pipeline.js +15 -21
- package/dist/commands/heartbeat.js +64 -1
- package/dist/commands/memory-hook-counts.js +61 -0
- package/dist/commands/ops-render-memory.js +34 -0
- package/dist/commands/ops-render.js +1 -1
- package/dist/commands/ops.js +24 -6
- package/dist/commands/public-root.js +1 -1
- package/dist/commands/status.js +8 -1
- package/dist/commands/sync-followups.js +64 -1
- package/dist/commands/sync.js +13 -2
- package/dist/disk-retention.js +5 -1
- package/dist/disk-usage.js +62 -9
- package/dist/evidence-redelivery-plan.js +277 -0
- package/dist/evidence-redelivery.js +280 -0
- package/dist/local-state-status.js +34 -0
- package/package.json +4 -4
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { readStagingInventory } from "./disk-usage.js";
|
|
4
|
+
import { describeError } from "./health-detail.js";
|
|
3
5
|
import { summarizeLocalUploadSpool } from "./spool/local-spool.js";
|
|
4
6
|
import { summarizeInstallEventOutbox } from "./spool/install-event-outbox.js";
|
|
5
7
|
import { readRawEvidenceStagingState, summarizeStuckEvidence, } from "./raw-evidence-staging.js";
|
|
@@ -55,6 +57,10 @@ export async function inspectLocalCollectorStatus(options = {}) {
|
|
|
55
57
|
stuck_evidence_max_attempts: stuckEvidence.max_attempts,
|
|
56
58
|
stuck_evidence_oldest_failure_at: stuckEvidence.oldest_first_failed_at,
|
|
57
59
|
stuck_evidence_reasons: stuckEvidence.reasons,
|
|
60
|
+
staging_uncommitted_count: reading.staging?.uncommitted_count ?? null,
|
|
61
|
+
staging_uncommitted_bytes: reading.staging?.uncommitted_bytes ?? null,
|
|
62
|
+
staging_uncommitted_reason: reading.staging?.dominant_uncommitted_reason?.reason ?? null,
|
|
63
|
+
staging_oldest_uncommitted_at: reading.staging?.oldest_uncommitted_at ?? null,
|
|
58
64
|
details: describeCollectorStatus(reading),
|
|
59
65
|
};
|
|
60
66
|
}
|
|
@@ -76,7 +82,20 @@ async function readCollectorStatus(options, now) {
|
|
|
76
82
|
readRawEvidenceStagingState(paths.state_dir),
|
|
77
83
|
]);
|
|
78
84
|
const stuckEvidence = summarizeStuckEvidence(stagingState, now);
|
|
85
|
+
// Best-effort by construction: a status read must never fail because the
|
|
86
|
+
// staging tree could not be walked, and an absent backlog reads as "this read
|
|
87
|
+
// did not ask", never as "there is none".
|
|
88
|
+
const staging = options.includeStagingBacklog
|
|
89
|
+
? await readStagingInventory(paths, now).catch((error) => {
|
|
90
|
+
console.error("[collector status] the staging tree could not be read; the undelivered backlog is unknown", JSON.stringify({
|
|
91
|
+
reason: "staging_inventory_unreadable",
|
|
92
|
+
...describeError(error),
|
|
93
|
+
}));
|
|
94
|
+
return null;
|
|
95
|
+
})
|
|
96
|
+
: null;
|
|
79
97
|
return {
|
|
98
|
+
staging,
|
|
80
99
|
paths,
|
|
81
100
|
config,
|
|
82
101
|
session,
|
|
@@ -134,6 +153,18 @@ function describeCollectorStatus(reading) {
|
|
|
134
153
|
if (healthOutbox.pending_count > 0) {
|
|
135
154
|
details.push(`Collector health retry pending: ${healthOutbox.pending_count} sanitized receipt(s) queued since ${healthOutbox.oldest_created_at ?? "unknown"}.`);
|
|
136
155
|
}
|
|
156
|
+
// BLI-3797: the line above only sees objects whose delivery FAILED. This one
|
|
157
|
+
// sees evidence that is on this disk and not in the bucket, however it got
|
|
158
|
+
// that way — which is the only question that answers "has everything landed?".
|
|
159
|
+
if (reading.staging && reading.staging.uncommitted_count > 0) {
|
|
160
|
+
const dominant = reading.staging.dominant_uncommitted_reason;
|
|
161
|
+
details.push(`Staged evidence not yet accepted: ${reading.staging.uncommitted_count} object(s), ${mib(reading.staging.uncommitted_bytes)} MB, oldest staged ${reading.staging.oldest_uncommitted_at ?? "unknown"}${dominant
|
|
162
|
+
? ` — biggest reason ${dominant.reason} on ${dominant.count} object(s)`
|
|
163
|
+
: ""}. \`cockpit sync\` re-offers them each tick; \`cockpit doctor --fix\` does it now.`);
|
|
164
|
+
}
|
|
165
|
+
else if (reading.staging) {
|
|
166
|
+
details.push("Staged evidence: every object on this disk is accepted.");
|
|
167
|
+
}
|
|
137
168
|
if (stuckEvidence.stuck_object_count > 0) {
|
|
138
169
|
details.push(`Raw evidence stuck: ${stuckEvidence.stuck_object_count} object(s) have never been accepted (${stuckEvidence.held_object_count} waiting on backoff, worst ${stuckEvidence.max_attempts} attempt(s) since ${stuckEvidence.oldest_first_failed_at ?? "unknown"}) — reasons: ${stuckEvidence.reasons.join(", ") || "unknown"}.`);
|
|
139
170
|
}
|
|
@@ -155,6 +186,9 @@ export function classifyCollectorFreshness(context, lastUploadSuccessAt, now) {
|
|
|
155
186
|
return "stale";
|
|
156
187
|
return now.getTime() - latestActivityAt <= 5 * 60 * 1000 ? "fresh" : "stale";
|
|
157
188
|
}
|
|
189
|
+
function mib(bytes) {
|
|
190
|
+
return (bytes / (1024 * 1024)).toFixed(1);
|
|
191
|
+
}
|
|
158
192
|
function latestTimestamp(values) {
|
|
159
193
|
const timestamps = values
|
|
160
194
|
.map((value) => Date.parse(value ?? ""))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.72",
|
|
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.
|
|
32
|
-
"@bli-cockpit/telemetry-core": "0.1.
|
|
30
|
+
"@bli-cockpit/memory-mcp": "0.1.11",
|
|
31
|
+
"@bli-cockpit/mcp": "0.1.12",
|
|
32
|
+
"@bli-cockpit/telemetry-core": "0.1.32"
|
|
33
33
|
}
|
|
34
34
|
}
|