@bli-cockpit/cli 0.2.49 → 0.2.51
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/adapters/raw-evidence-claude-reader.js +108 -0
- package/dist/adapters/raw-evidence-codex-reader.js +147 -0
- package/dist/adapters/raw-evidence-collection-state.js +199 -0
- package/dist/adapters/raw-evidence-facts.js +338 -0
- package/dist/adapters/raw-evidence-git-diff-reader.js +187 -0
- package/dist/adapters/raw-evidence-image-reader.js +107 -0
- package/dist/adapters/raw-evidence-sanitize.js +56 -0
- package/dist/adapters/raw-evidence-transcript-file.js +182 -0
- package/dist/adapters/raw-evidence.js +63 -1183
- package/dist/commands/backfill-batches.js +34 -0
- package/dist/commands/backfill-candidates.js +54 -0
- package/dist/commands/backfill-checkpoint.js +101 -0
- package/dist/commands/backfill-command-line.js +70 -0
- package/dist/commands/backfill-evidence-outcomes.js +104 -0
- package/dist/commands/backfill-issues.js +265 -0
- package/dist/commands/backfill-output.js +75 -0
- package/dist/commands/backfill-plan.js +71 -0
- package/dist/commands/backfill-reasons.js +107 -0
- package/dist/commands/backfill-report.js +298 -0
- package/dist/commands/backfill-result.js +150 -0
- package/dist/commands/backfill-scan.js +274 -0
- package/dist/commands/backfill-scope.js +114 -0
- package/dist/commands/backfill-session-report.js +145 -0
- package/dist/commands/backfill-types.js +1 -0
- package/dist/commands/backfill-upload.js +212 -0
- package/dist/commands/backfill.js +41 -1961
- package/dist/commands/doctor.js +57 -0
- package/dist/commands/jarvis-trace.js +184 -0
- package/dist/commands/jarvis.js +144 -4
- package/dist/commands/local-args-collector.js +26 -0
- package/dist/commands/local-args-tower.js +21 -0
- package/dist/commands/local-args.js +3 -1
- package/dist/commands/local-help.js +19 -2
- package/dist/commands/local.js +3 -0
- package/dist/commands/memory-install-claude.js +294 -0
- package/dist/commands/memory-install-codex.js +205 -0
- package/dist/commands/memory-install-contract.js +286 -0
- package/dist/commands/memory-install-files.js +63 -0
- package/dist/commands/memory-install-skills.js +121 -0
- package/dist/commands/memory-install-toml.js +265 -0
- package/dist/commands/memory-install.js +465 -0
- package/dist/commands/public-root.js +1 -1
- package/dist/commands/sync-followups.js +105 -0
- package/dist/commands/sync.js +7 -1
- package/dist/local-state-attributed-target.js +75 -0
- package/dist/local-state-config.js +147 -0
- package/dist/local-state-files.js +59 -0
- package/dist/local-state-identity.js +73 -0
- package/dist/local-state-pairing.js +263 -0
- package/dist/local-state-paths.js +61 -0
- package/dist/local-state-session.js +68 -0
- package/dist/local-state-status.js +163 -0
- package/dist/local-state-work-context.js +190 -0
- package/dist/local-state.js +34 -848
- package/dist/tower-client.js +3 -2
- package/dist/tower-stream.js +57 -3
- package/package.json +2 -1
package/dist/tower-client.js
CHANGED
|
@@ -81,14 +81,15 @@ export async function towerRequest(options) {
|
|
|
81
81
|
};
|
|
82
82
|
try {
|
|
83
83
|
const response = await options.fetch(url, init);
|
|
84
|
+
const respondedMs = Date.now() - startedAt;
|
|
84
85
|
log(`[tower client] responded ${JSON.stringify({
|
|
85
86
|
request: options.label,
|
|
86
87
|
http_status: response.status,
|
|
87
88
|
content_type: response.headers.get("content-type") ?? "none",
|
|
88
89
|
streamed: (response.headers.get("content-type") ?? "").includes("application/x-ndjson"),
|
|
89
|
-
elapsed_ms:
|
|
90
|
+
elapsed_ms: respondedMs,
|
|
90
91
|
})}`);
|
|
91
|
-
return { ok: true, response };
|
|
92
|
+
return { ok: true, response, startedAt, respondedMs };
|
|
92
93
|
}
|
|
93
94
|
catch (error) {
|
|
94
95
|
const reason = isAbortError(error)
|
package/dist/tower-stream.js
CHANGED
|
@@ -40,7 +40,7 @@ const CEILING_HINT_MS = 110_000;
|
|
|
40
40
|
* from a dashboard that does not stream yet (yielded as the final event, after
|
|
41
41
|
* a `stream_not_available` note).
|
|
42
42
|
*/
|
|
43
|
-
export async function* readTowerStream(response) {
|
|
43
|
+
export async function* readTowerStream(response, options = {}) {
|
|
44
44
|
const contentType = response.headers.get("content-type") ?? "";
|
|
45
45
|
if (!contentType.includes("application/x-ndjson")) {
|
|
46
46
|
yield* readPlainJsonBody(response);
|
|
@@ -49,6 +49,7 @@ export async function* readTowerStream(response) {
|
|
|
49
49
|
let buffer = "";
|
|
50
50
|
try {
|
|
51
51
|
for await (const chunk of iterateBody(response)) {
|
|
52
|
+
options.onBytes?.();
|
|
52
53
|
buffer += chunk;
|
|
53
54
|
const lines = buffer.split("\n");
|
|
54
55
|
buffer = lines.pop() ?? "";
|
|
@@ -92,7 +93,16 @@ export async function readTowerTurn(response, options = {}) {
|
|
|
92
93
|
let final = null;
|
|
93
94
|
let draft = "";
|
|
94
95
|
let tokenFrames = 0;
|
|
95
|
-
|
|
96
|
+
let firstByteMs = null;
|
|
97
|
+
let firstFrameMs = null;
|
|
98
|
+
let firstTokenMs = null;
|
|
99
|
+
for await (const item of readTowerStream(response, {
|
|
100
|
+
onBytes: () => {
|
|
101
|
+
firstByteMs ??= Date.now() - startedAt;
|
|
102
|
+
},
|
|
103
|
+
})) {
|
|
104
|
+
if (item.kind === "event")
|
|
105
|
+
firstFrameMs ??= Date.now() - startedAt;
|
|
96
106
|
if (item.kind === "note") {
|
|
97
107
|
if (item.reason === "stream_not_available")
|
|
98
108
|
streamed = false;
|
|
@@ -106,6 +116,9 @@ export async function readTowerTurn(response, options = {}) {
|
|
|
106
116
|
}
|
|
107
117
|
if (item.event.type === "token") {
|
|
108
118
|
const text = item.event.text ?? "";
|
|
119
|
+
// The mark a person actually feels: the first frame with WORDS in it.
|
|
120
|
+
if (text)
|
|
121
|
+
firstTokenMs ??= Date.now() - startedAt;
|
|
109
122
|
tokenFrames += 1;
|
|
110
123
|
draft = item.event.reset ? text : draft + text;
|
|
111
124
|
options.onToken?.(item.event);
|
|
@@ -115,6 +128,7 @@ export async function readTowerTurn(response, options = {}) {
|
|
|
115
128
|
options.onActivity?.(item.event);
|
|
116
129
|
}
|
|
117
130
|
const elapsedMs = Date.now() - startedAt;
|
|
131
|
+
const timing = { firstByteMs, firstFrameMs, firstTokenMs };
|
|
118
132
|
if (!final) {
|
|
119
133
|
// The last named note is the truest reason we have; absent one, a stream
|
|
120
134
|
// that simply stopped near the dashboard's ceiling is a timeout.
|
|
@@ -131,11 +145,21 @@ export async function readTowerTurn(response, options = {}) {
|
|
|
131
145
|
drafted_chars: draft.length,
|
|
132
146
|
notes: notes.length,
|
|
133
147
|
elapsed_ms: elapsedMs,
|
|
148
|
+
// BLI-3591: a turn that died still says how far it got — a stream that
|
|
149
|
+
// never produced a byte and one that produced words and then broke are
|
|
150
|
+
// different failures.
|
|
151
|
+
...turnTimingFields(timing),
|
|
134
152
|
})}`);
|
|
135
153
|
return { ok: false, reason, detail: streamFailureDetail(reason, terminal?.detail) };
|
|
136
154
|
}
|
|
137
155
|
options.log?.(`[tower stream] turn complete ${JSON.stringify({
|
|
138
156
|
streamed,
|
|
157
|
+
// BLI-3582: the dashboard's own split of the wait, relayed verbatim off
|
|
158
|
+
// the final frame — `wire_ms` (request accepted → first byte out),
|
|
159
|
+
// `prep_ms` (→ the model call started) and `model_ttft_ms` (→ its first
|
|
160
|
+
// token). All null against a dashboard that does not send them, which is
|
|
161
|
+
// a different fact from a turn that was instant.
|
|
162
|
+
...finalLatencyFields(final),
|
|
139
163
|
activity_events: activity.length,
|
|
140
164
|
// BLI-3517: zero token frames against a streaming dashboard means the
|
|
141
165
|
// answer arrived all at once — worth telling apart from a quiet turn.
|
|
@@ -143,8 +167,38 @@ export async function readTowerTurn(response, options = {}) {
|
|
|
143
167
|
drafted_chars: draft.length,
|
|
144
168
|
notes: notes.length,
|
|
145
169
|
elapsed_ms: elapsedMs,
|
|
170
|
+
// BLI-3591: this side's own three marks, beside the dashboard's three
|
|
171
|
+
// above. `first_byte_ms` is the socket opening (the dashboard's flushed
|
|
172
|
+
// newline), `first_frame_ms` the first readable frame and
|
|
173
|
+
// `first_token_ms` the first WORDS — so the 1-2 s that used to sit
|
|
174
|
+
// unexplained between the dashboard's first token and the terminal's
|
|
175
|
+
// first visible character now has a number on each end of it.
|
|
176
|
+
...turnTimingFields(timing),
|
|
146
177
|
})}`);
|
|
147
|
-
return { ok: true, final, activity, streamed, draft };
|
|
178
|
+
return { ok: true, final, activity, streamed, draft, timing };
|
|
179
|
+
}
|
|
180
|
+
/** The same three marks as log fields, snake_case like every other line here. */
|
|
181
|
+
export function turnTimingFields(timing) {
|
|
182
|
+
return {
|
|
183
|
+
first_byte_ms: timing.firstByteMs,
|
|
184
|
+
first_frame_ms: timing.firstFrameMs,
|
|
185
|
+
first_token_ms: timing.firstTokenMs,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* The three latency spans off a final frame, as log fields (BLI-3582).
|
|
190
|
+
*
|
|
191
|
+
* Read defensively: this module knows the ENVELOPE, not the body, and a body
|
|
192
|
+
* shape that drifts must degrade to three nulls rather than a thrown turn.
|
|
193
|
+
*/
|
|
194
|
+
function finalLatencyFields(final) {
|
|
195
|
+
const raw = final["latency"];
|
|
196
|
+
const latency = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
197
|
+
const ms = (key) => {
|
|
198
|
+
const value = latency[key];
|
|
199
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
200
|
+
};
|
|
201
|
+
return { wire_ms: ms("wireMs"), prep_ms: ms("prepMs"), model_ttft_ms: ms("modelTtftMs") };
|
|
148
202
|
}
|
|
149
203
|
/** One plain sentence per way a turn can end without an answer. */
|
|
150
204
|
export function streamFailureDetail(reason, detail) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bli-cockpit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.51",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,6 +27,7 @@
|
|
|
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.1",
|
|
30
31
|
"@bli-cockpit/telemetry-core": "0.1.26"
|
|
31
32
|
}
|
|
32
33
|
}
|