wicked-crew-api-types 0.134.0 → 0.137.0

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.
Files changed (2) hide show
  1. package/index.d.ts +508 -7
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -287,6 +287,22 @@ export interface HealthCapabilities {
287
287
  * the run. ABSENT on an older daemon — do not send the field (its strict schema 400s on it).
288
288
  */
289
289
  launchPrimary?: boolean;
290
+ /**
291
+ * (api-types 0.136.0, DES-SYSTEM-VIEW) `GET /system` is served: the Nerve Center snapshot
292
+ * ({@link SystemSnapshot}). ABSENT on an older daemon — show the older Health cards instead.
293
+ */
294
+ system?: boolean;
295
+ /**
296
+ * (api-types 0.137.0, DES-SYSTEM-CHAT) The chat history is served: `GET /chats` carries `items` +
297
+ * `nextCursor`, `GET /chats/:id/messages` reopens a chat, `POST /chats/:id/close` ends one and keeps
298
+ * its history. ABSENT on an older daemon — hide the past-chats rail.
299
+ */
300
+ chatList?: boolean;
301
+ /**
302
+ * (api-types 0.137.0) `POST /chats/:id/attachments` and `ChatMessageBody.attachments` are served.
303
+ * ABSENT on an older daemon — hide upload.
304
+ */
305
+ chatAttachments?: boolean;
290
306
  }
291
307
 
292
308
  /** One `GET /health.warnings[]` entry (additive; wicked-core#411 / wicked-crew#497). */
@@ -739,6 +755,12 @@ export interface WorkUnit {
739
755
  /** (api-types 0.102.0; wicked-core#850, core-ts ≥ 0.7.46) The receipt of this unit's LAST gate,
740
756
  * as `gateEvaluated.assurance` carried it. ABSENT until a gate ran, and on an older engine. */
741
757
  assurance?: AssuranceReceipt;
758
+ /** (api-types 0.135.0) Every layer other than the repo-checks floor that denied this unit's last
759
+ * gate, plus any earlier denial over the same tree that gate did not ask again — the record
760
+ * `operator_judgment` reads (it is refused while any stands). `[]`: known, nothing but the floor
761
+ * denied. ABSENT (or `null`): unknown — a unit from before the record, or an older engine. The
762
+ * engine's own serialization, so its fields are snake_case (`claim_id`, `rule_ids`, …). */
763
+ denials_behind?: Array<{ source: string; reason: string; [k: string]: unknown }> | null;
742
764
  /** Evaluator≠creator role. Present on def-driven units; absent on legacy/free-text. */
743
765
  role?: PhaseRole;
744
766
  /** Gate policy for this phase. Present on def-driven units; absent on legacy/free-text. */
@@ -1191,6 +1213,13 @@ export interface RosterSeat {
1191
1213
  * `GET /roster/record`. ABSENT when there is no active bench.
1192
1214
  */
1193
1215
  recent_bench?: SeatRecentBench;
1216
+ /**
1217
+ * (unreleased, PRODUCT-WORKS J4) The active bench, flat, for the Nerve Center
1218
+ * (`SystemCli.benchedUntil` / `stateReason`): ISO-8601 of when it lifts (`recent_bench.lifts_at`)
1219
+ * and why, in the operator's words. Both present iff `recent_bench` is.
1220
+ */
1221
+ benchedUntil?: string;
1222
+ benchReason?: string;
1194
1223
  /**
1195
1224
  * (unreleased, wicked-core#976) The engine's HOST-FLOOR bench reason for this seat: on the interim
1196
1225
  * host floor (`WICKED_SEAT_FLOOR` other than `container`) the engine refuses governed work on any
@@ -1288,10 +1317,19 @@ export interface SeatRecentBench {
1288
1317
  runs: number;
1289
1318
  /** ISO-8601 of the latest bench. */
1290
1319
  last_at: string;
1291
- /** ISO-8601 of when crew stops carrying it to new launches. Crew's window, NOT a provider reset
1292
- * time (no provider states one on the wire today). */
1320
+ /** ISO-8601 of when crew stops carrying it to new launches. (unreleased, PRODUCT-WORKS J4) For a
1321
+ * quota bench (`quota_exhausted`, `usage_limit`): the engine's lift time (the provider's reset time
1322
+ * when the refusal stated one, else the engine's backoff), or crew's backoff of 15, 30, then 60
1323
+ * minutes by `strikes`; any other kind keeps crew's 30-minute window. */
1293
1324
  lifts_at: string;
1294
- /** Who benched it in the run: `worker` or `judge`. */
1325
+ /** (unreleased, J4) Where `lifts_at` came from: the engine's `seatBenched.benchedUntilMs`, crew's
1326
+ * quota backoff, or the fixed window. */
1327
+ until_source: 'engine' | 'backoff' | 'window';
1328
+ /** (unreleased, J4) Quota benches in a row with no good turn between (the backoff step); 0 on a
1329
+ * non-quota bench. */
1330
+ strikes: number;
1331
+ /** Who benched it in the run: `worker`, `judge`, or (unreleased, J4) `reprobe` — its quota bench
1332
+ * fell due and it did not answer the engine's re-probe. */
1295
1333
  source: string;
1296
1334
  /** The engine's own reason, verbatim (technical details). */
1297
1335
  reason: string;
@@ -1706,6 +1744,19 @@ export interface GateDecision {
1706
1744
  * {@link GateInfo.rejudge} says beforehand. Unlike a plain approve there, it is never the
1707
1745
  * operator's own judgment. */
1708
1746
  | 'rejudge'
1747
+ /** (api-types 0.135.0, operator ruling 2026-10-21) APPROVE AS YOUR OWN JUDGMENT at the
1748
+ * escalation gate of a FAILED REPO-CHECKS FLOOR (`gateEscalated.condition: 'floor_failed'`,
1749
+ * `denialSource: 'repo_checks' | 'repo_checks_timeout'`), with `approve: true` and the written
1750
+ * rationale in `amend` — required, non-empty (a 400 otherwise); no `amendScope` or `plan`. The
1751
+ * operator judges from the evidence that the failures are not the work's (load flakes,
1752
+ * pre-existing reds): the unit counts as it stands, its gate receipt records an
1753
+ * {@link OperatorJudgment} with `floorOverride` set (the floor result it overrode, labelled
1754
+ * "floor overridden by operator"), and the run ({@link RunAssurance.floorOverrides}) and the
1755
+ * delivery carry the label. It overrides the floor ONLY: the engine refuses it (409, gate left
1756
+ * open) when any other layer of the same gate also denied, on a team member's step, on a tool or
1757
+ * deliver step and at every other gate. QE acceptance is never waived by it — a run that
1758
+ * requires it still needs its PASS before delivery. Engine: wicked-core-ts after 0.15.6. */
1759
+ | 'operator_judgment'
1709
1760
  /** (core#820) A `consent` gate's choice from its dry-run plan (`awaitingHuman.choices`), with
1710
1761
  * `approve: true`: `consent:worker` (the default), `consent:operator`, …; `reject` declines. */
1711
1762
  | `consent:${string}`;
@@ -2317,7 +2368,8 @@ export type AssuranceInstrument =
2317
2368
  | 'judge'
2318
2369
  | 'evaluator_pass'
2319
2370
  | 'distinct_evaluator'
2320
- /** (api-types 0.110.0) The operator judged a gate whose judge could not rule. */
2371
+ /** (api-types 0.110.0) The operator judged a gate whose judge could not rule — or (api-types
2372
+ * 0.135.0) overrode a failed repo-checks floor (`operatorJudges[].floorOverride`). */
2321
2373
  | 'operator_judge'
2322
2374
  | (string & {});
2323
2375
 
@@ -2330,9 +2382,34 @@ export interface OperatorJudgment {
2330
2382
  by: string;
2331
2383
  /** Unix millis. */
2332
2384
  at: number;
2385
+ /** The operator's note; on a floor override, the written rationale (never empty). */
2333
2386
  note: string | null;
2334
- /** Why the judge could not rule (the gate's denial reason). */
2387
+ /** Why the judge could not rule (the gate's denial reason) — or, on a floor override, why the
2388
+ * floor denied. */
2335
2389
  reason: string | null;
2390
+ /** (api-types 0.135.0) Set when this judgment OVERRODE a failed repo-checks floor
2391
+ * ({@link GateDecision.action} `'operator_judgment'`); ABSENT on a judge-unavailable judgment
2392
+ * and on an older engine. */
2393
+ floorOverride?: FloorOverride;
2394
+ }
2395
+
2396
+ /**
2397
+ * (api-types 0.135.0, operator ruling 2026-10-21) The failed floor result an operator's judgment
2398
+ * overrode. It answers the repo-checks floor only: every other layer of the gate still denies, and
2399
+ * QE acceptance is untouched.
2400
+ */
2401
+ export interface FloorOverride {
2402
+ /** The floor layer that denied: `repo_checks` | `repo_checks_timeout`. */
2403
+ layer: string;
2404
+ /** The floor result overridden — `<run>:unit-<ord>:attempt-<n>:<layer>`, the unit's
2405
+ * `repoChecksEvaluated` frame for that attempt (or the carried result it stood on). */
2406
+ resultId: string;
2407
+ ord: number;
2408
+ attempt: number;
2409
+ /** The tree the overridden checks ran on, when the report names it. */
2410
+ tree: string | null;
2411
+ /** `floor overridden by operator` — the line to show as-is. */
2412
+ label: string;
2336
2413
  }
2337
2414
 
2338
2415
  /**
@@ -2375,8 +2452,14 @@ export interface RunAssurance {
2375
2452
  * exactly when `required` holds `qe_acceptance`. ABSENT on an older engine (then a required
2376
2453
  * `qe_acceptance` is enforced). */
2377
2454
  qe?: QeAcceptanceDecision;
2455
+ /** (api-types 0.135.0) Every failed floor the operator overrode on this run ("floor overridden
2456
+ * by operator"), each with who, when and the rationale; ABSENT when none or on an older engine. */
2457
+ floorOverrides?: OperatorJudgment[];
2378
2458
  }
2379
2459
 
2460
+ /** (api-types 0.135.0) The label an overridden floor carries on the run, the gate and the delivery. */
2461
+ export type FloorOverrideLabel = 'floor overridden by operator';
2462
+
2380
2463
  /** (api-types 0.106.0) `QeAcceptanceDecision.status`. */
2381
2464
  export type QeAcceptanceStatus = 'required' | 'waived' | 'skipped' | (string & {});
2382
2465
 
@@ -6599,6 +6682,8 @@ export interface ChatOpenBody {
6599
6682
  * (`path.started.selection: "random"`).
6600
6683
  */
6601
6684
  primary?: string;
6685
+ /** (api-types 0.137.0, DES-SYSTEM-CHAT) The page the chat was started on, for the history list. */
6686
+ startedOn?: ChatStartedOn;
6602
6687
  }
6603
6688
 
6604
6689
  /** The scope a `POST /chats` caller may name (api-types 0.39.0, studio#323 R4). */
@@ -6859,9 +6944,18 @@ export interface ChatSummary {
6859
6944
  readRoots?: string[];
6860
6945
  }
6861
6946
 
6862
- /** `GET /chats` → 200. */
6947
+ /**
6948
+ * `GET /chats` → 200. `chats`: the live engine / ask-path rows, unchanged. From api-types 0.137.0
6949
+ * (DES-SYSTEM-CHAT) also the paged chat HISTORY: `items` newest first by `updatedAt`, and
6950
+ * `nextCursor` to pass as `?cursor=` for the next page (`null` on the last). Query: `?limit=`
6951
+ * (1–100, default 20), `?cursor=`, `?status=open|closed|all` (default `all`). Under
6952
+ * `auth: required` only the caller's own chats are listed. ABSENT on an older daemon (no
6953
+ * `capabilities.chatList`).
6954
+ */
6863
6955
  export interface ChatListResponse {
6864
6956
  chats: ChatSummary[];
6957
+ items?: ChatHistoryEntry[];
6958
+ nextCursor?: string | null;
6865
6959
  }
6866
6960
 
6867
6961
  /**
@@ -6886,7 +6980,8 @@ export interface ChatUsage {
6886
6980
  * "exceeded the N s turn budget … target it on your next message to re-seat it").
6887
6981
  */
6888
6982
  export type ChatTranscriptRecord =
6889
- | { at: number; turnId: string; kind: 'user'; text: string; seats: string[] }
6983
+ /** `attachments` (api-types 0.137.0): the files the message carried, ABSENT when none. */
6984
+ | { at: number; turnId: string; kind: 'user'; text: string; seats: string[]; attachments?: ChatAttachment[] }
6890
6985
  | { at: number; turnId: string; kind: 'seat'; cliKey: string; text: string; ok: boolean; usage: ChatUsage | null }
6891
6986
  /**
6892
6987
  * The citation verdicts of the `seat` record with the same `turnId` + `cliKey` (api-types 0.68.0,
@@ -6921,6 +7016,133 @@ export type ChatTranscriptRecord =
6921
7016
  */
6922
7017
  | { at: number; turnId: string; kind: 'system'; text: string };
6923
7018
 
7019
+ // ── System chat: history, close, attachments (api-types 0.137.0, DES-SYSTEM-CHAT "Crew") ────────
7020
+ //
7021
+ // The floating system chat's past-chats rail, its Close, and its uploads. Capabilities:
7022
+ // `GET /health.capabilities.chatList` (the history list, `POST /chats/:id/close`,
7023
+ // `GET /chats/:id/messages`) and `.chatAttachments` (`POST /chats/:id/attachments` and
7024
+ // `ChatMessageBody.attachments`). A chat's history is kept until `DELETE /chats/:id`, which still
7025
+ // ends the chat AND deletes its history and attachments; `POST /chats/:id/close` ends it and keeps both.
7026
+
7027
+ /** The page a chat was started on: studio's route and its human label ("Run 9b43ee44"). */
7028
+ export interface ChatStartedOn {
7029
+ route: string;
7030
+ label: string;
7031
+ }
7032
+
7033
+ /** One past or open system chat, as the history list shows it. */
7034
+ export interface ChatHistoryEntry {
7035
+ /** The chat id: `GET /chats/:id/messages` reopens it, `POST /chats/:id/close` ends it. */
7036
+ id: string;
7037
+ /** The first operator message, whitespace-collapsed and cut at 80 characters (an ellipsis
7038
+ * included); "New chat" before the first message. */
7039
+ title: string;
7040
+ /** Where the chat was started, when the opener said (`ChatOpenBody.startedOn`); else `null`. */
7041
+ startedOn: ChatStartedOn | null;
7042
+ /** The CLI that answers (the chat's primary agent once known, else the operator's choice, else
7043
+ * its first eligible seat); `null` when none was seated. */
7044
+ cli: string | null;
7045
+ /** ISO-8601. */
7046
+ createdAt: string;
7047
+ /** ISO-8601 of the newest message (or of the open, before any). */
7048
+ updatedAt: string;
7049
+ /** Operator messages plus seat replies (prefaces, citations and decision records excluded). */
7050
+ messageCount: number;
7051
+ /** Files uploaded to the chat. */
7052
+ attachmentCount: number;
7053
+ /** `open`: live on this daemon; `closed`: ended (Close, idle, or a daemon restart), history kept. */
7054
+ status: 'open' | 'closed';
7055
+ /** ISO-8601 of the end; present with `status: 'closed'`. */
7056
+ closedAt?: string;
7057
+ }
7058
+
7059
+ /** `GET /chats/:id/messages` → 200 (404 for an id with no history). An open chat answers its live
7060
+ * transcript; a closed one its kept history. Same records as `ChatDetailResponse.messages`. */
7061
+ export interface ChatMessagesResponse {
7062
+ chat: ChatHistoryEntry;
7063
+ messages: ChatTranscriptRecord[];
7064
+ attachments: ChatAttachment[];
7065
+ }
7066
+
7067
+ /** `POST /chats/:id/close` → 200: the chat is ended (its seats released, its run cancelled) and its
7068
+ * history and attachments are kept. Idempotent: closing a closed chat answers its entry again. */
7069
+ export interface ChatCloseResponse {
7070
+ ok: true;
7071
+ chat: ChatHistoryEntry;
7072
+ }
7073
+
7074
+ /** `POST /chats/:id/close` → **502** when the chat's run could not be cancelled: the chat IS closed
7075
+ * and its history kept, but its run may still be running — cancel it from the run (`runId`). */
7076
+ export interface ChatCloseCancelFailed {
7077
+ error: string;
7078
+ runId: string;
7079
+ chat: ChatHistoryEntry;
7080
+ }
7081
+
7082
+ /** What an attachment is to a seat: an image (png, jpeg, gif, webp), text (UTF-8), or a pdf. */
7083
+ export type ChatAttachmentKind = 'image' | 'text' | 'pdf';
7084
+
7085
+ /** One uploaded file. Stored under the state home (`<state home>/chats/attachments/<chat>/`),
7086
+ * removed with its chat on `DELETE /chats/:id`. */
7087
+ export interface ChatAttachment {
7088
+ id: string;
7089
+ chatId: string;
7090
+ /** The uploaded file name, sanitized (no path). */
7091
+ name: string;
7092
+ /** The verified media type (`image/png`, `text/plain`, `application/pdf`, …). */
7093
+ mediaType: string;
7094
+ kind: ChatAttachmentKind;
7095
+ bytes: number;
7096
+ sha256: string;
7097
+ /** ISO-8601. */
7098
+ createdAt: string;
7099
+ }
7100
+
7101
+ /** The caps an upload and a message are held to (also on every 413). */
7102
+ export interface ChatAttachmentLimits {
7103
+ /** One file, bytes. */
7104
+ maxFileBytes: number;
7105
+ /** All files one message references (and one upload request carries), bytes. */
7106
+ maxMessageBytes: number;
7107
+ /** Files per message (and per upload request). */
7108
+ maxFiles: number;
7109
+ /** The media types accepted. */
7110
+ mediaTypes: string[];
7111
+ }
7112
+
7113
+ /** `POST /chats/:id/attachments` (multipart/form-data, one or more file parts) → 201. */
7114
+ export interface ChatAttachmentUploadResponse {
7115
+ attachments: ChatAttachment[];
7116
+ limits: ChatAttachmentLimits;
7117
+ }
7118
+
7119
+ /**
7120
+ * An upload or a send refused over an attachment: 413 `attachment_too_large` (one file over
7121
+ * `maxFileBytes`) or `attachments_too_large` (the request or the message over `maxMessageBytes`, or
7122
+ * over `maxFiles`); 415 `attachment_type` (not an image, UTF-8 text or pdf, or its bytes do not
7123
+ * match its type); 404 `attachment_unknown` (a message names an id this chat does not have); 400
7124
+ * `attachment_malformed` (not multipart, or no file part).
7125
+ */
7126
+ export interface ChatAttachmentError {
7127
+ error: string;
7128
+ code: 'attachment_too_large' | 'attachments_too_large' | 'attachment_type' | 'attachment_unknown' | 'attachment_malformed';
7129
+ /** The file the refusal is about, when one. */
7130
+ name?: string;
7131
+ bytes?: number;
7132
+ limits: ChatAttachmentLimits;
7133
+ }
7134
+
7135
+ /** `POST /chats/:id/messages` body (named in api-types 0.137.0; `text` and `targets` unchanged). */
7136
+ export interface ChatMessageBody {
7137
+ text: string;
7138
+ targets?: string[];
7139
+ /** (api-types 0.137.0) Ids from `POST /chats/:id/attachments` this message carries (at most
7140
+ * `maxFiles`, together at most `maxMessageBytes`). Each reaches the answering seat as a read-only
7141
+ * file: a path it can open (images as images where the CLI reads them) plus, for text and pdf,
7142
+ * the extracted text. Send only when `GET /health.capabilities.chatAttachments === true`. */
7143
+ attachments?: string[];
7144
+ }
7145
+
6924
7146
  /** `GET /chats/:id` → 200. */
6925
7147
  export interface ChatDetailResponse {
6926
7148
  chatId: string;
@@ -8035,6 +8257,285 @@ export interface NoEligibleSeatBody {
8035
8257
  remedy: string;
8036
8258
  }
8037
8259
 
8260
+ // ── System snapshot — the Nerve Center (api-types 0.136.0, DES-SYSTEM-VIEW) ────────────────────
8261
+ //
8262
+ // `GET /api/v1/system`: ONE derived, read-only snapshot answering "is anything stopping work, why,
8263
+ // and what fixes it?" — the CLIs, the unfinished runs, the infrastructure and the governance
8264
+ // instruments, plus `attention[]`, the union of every item that needs a look. Every infra row is a
8265
+ // real probe run for THIS request under a bounded timeout (a probe that did not answer reads
8266
+ // `unknown` with its timeout, never `ok`); liveness is computed from evidence; a number the daemon
8267
+ // cannot count is `null` (or the field is absent where the doc says so), never a fabricated 0. The
8268
+ // whole snapshot answers within a fixed overall bound (`budgetMs`) even when probes hang.
8269
+ // `GET /health.capabilities.system === true` advertises the route. `/diagnostics` stays the raw dump;
8270
+ // each of its blocks is reachable from here (see each row's `details`).
8271
+
8272
+ /** One state for every infra row and governance card. `off`: the component is not part of this
8273
+ * deployment right now (the container gateway on the host floor, an interactive bridge nothing has
8274
+ * started yet) — not a problem and never in `attention[]`. */
8275
+ export type SystemState = 'ok' | 'degraded' | 'down' | 'unknown' | 'off';
8276
+
8277
+ /** The Nerve Center light: `red` when work is blocked, `yellow` when something needs a look but
8278
+ * work still flows, `green` when `attention[]` is empty. Derived from `attention[]` only. */
8279
+ export type SystemLevel = 'green' | 'yellow' | 'red';
8280
+
8281
+ /** The existing action an attention item or row offers (the snapshot itself is read-only):
8282
+ * `sign_in` — the CLI's sign-in (`POST /seats/:cli/login…` / the Agents page); `recheck` — read
8283
+ * the snapshot again (every probe runs fresh per read); `open_gate` — the run's open gate;
8284
+ * `open_run` — the run. */
8285
+ export type SystemActionKind = 'sign_in' | 'recheck' | 'open_gate' | 'open_run';
8286
+
8287
+ /** Where an item points. A skin maps it to its own route; crew never spells a studio URL. */
8288
+ export type SystemTarget =
8289
+ | { kind: 'infra'; key: SystemInfraKey }
8290
+ | { kind: 'cli'; cli: string }
8291
+ | { kind: 'run'; runId: string; gateOrd?: number; interactionId?: string }
8292
+ | { kind: 'governance'; key: SystemGovernanceKey };
8293
+
8294
+ export interface SystemAction {
8295
+ kind: SystemActionKind;
8296
+ /** The button's words ("Sign in", "Re-check", "Open the gate", "Open the run"). */
8297
+ label: string;
8298
+ }
8299
+
8300
+ /** `GET /api/v1/system`. */
8301
+ export interface SystemSnapshot {
8302
+ /** ISO-8601 of when this snapshot was assembled (the probes ran just before it). */
8303
+ checkedAt: string;
8304
+ /** The overall bound the daemon held this answer to, in ms. */
8305
+ budgetMs: number;
8306
+ /** How long assembling it took, in ms. */
8307
+ tookMs: number;
8308
+ /** `red` iff some attention item is `red`, else `yellow` iff any item, else `green`. */
8309
+ level: SystemLevel;
8310
+ /** Every item that needs a look, worst first (red before yellow, then by how many runs it
8311
+ * blocks, then infra › cli › run › governance). Empty when all is clear. */
8312
+ attention: SystemAttentionItem[];
8313
+ /** One entry per CLI on the roster, in roster order. */
8314
+ clis: SystemCli[];
8315
+ /** Every unfinished run (not completed / cancelled / failed), worst first:
8316
+ * waiting_on_you › held › stalled › quiet › working, then oldest evidence first. */
8317
+ runs: SystemRun[];
8318
+ infra: SystemInfraRow[];
8319
+ governance: SystemGovernanceCard[];
8320
+ }
8321
+
8322
+ export interface SystemAttentionItem {
8323
+ /** Stable across reads while the same thing is wrong (`infra:gateway`, `cli:copilot`,
8324
+ * `run:<id>`, `judge:<runId>`, `governance:dead_letters`). */
8325
+ id: string;
8326
+ severity: 'red' | 'yellow';
8327
+ source: 'infra' | 'cli' | 'run' | 'governance';
8328
+ /** The one-line headline ("gateway down", "copilot benched (quota)", "run 9b43ee44 stalled"). */
8329
+ title: string;
8330
+ /** Why, in plain words. */
8331
+ reason: string;
8332
+ /** What fixes it, in plain words. */
8333
+ remedy: string;
8334
+ /** How many unfinished runs it blocks (0 when it blocks none directly). */
8335
+ blocks: number;
8336
+ target: SystemTarget;
8337
+ /** The one existing action that helps, or `null`. */
8338
+ action: SystemAction | null;
8339
+ }
8340
+
8341
+ // ── clis[] ──
8342
+
8343
+ /** `signed_in`: the roster reads the seat signed in (or not needing a sign-in) and no bench is
8344
+ * active; `signed_out`: it needs a sign-in; `benched`: the engine benched it in a run on its own
8345
+ * refusal (quota / 429, usage limit, not logged in…) and crew keeps it out of new launches until
8346
+ * `benchedUntil`; `unknown`: the daemon cannot tell cheaply (the check has not answered). */
8347
+ export type SystemCliState = 'signed_in' | 'signed_out' | 'benched' | 'unknown';
8348
+
8349
+ export interface SystemCli {
8350
+ cli: string;
8351
+ label: string;
8352
+ state: SystemCliState;
8353
+ /** Why the state is not `signed_in`, in the operator's words; `null` when it is. */
8354
+ stateReason: string | null;
8355
+ /** ISO-8601 of when an active bench lifts; present only with `state: 'benched'`. */
8356
+ benchedUntil?: string;
8357
+ /** Whether the seat can be signed in from studio (a container sign-in or a login command). */
8358
+ canSignIn: boolean;
8359
+ /** May be seated as a judge/council member right now (the roster's `council_eligible`). */
8360
+ councilEligible: boolean;
8361
+ /** May be seated for work right now (the roster's `work_eligible`; absent there reads true). */
8362
+ workEligible: boolean;
8363
+ /** The installed version the roster's background probe read; `null` before the first reading. */
8364
+ version: string | null;
8365
+ /** The ACP version pin, when the seat is pinned: `matched: false` fails its governance closed. */
8366
+ versionPin: { pinned: string; observed: string | null; matched: boolean } | null;
8367
+ /** The engine's governance class for the seat, verbatim; `null` on an engine without it. */
8368
+ governanceClass: string | null;
8369
+ /** The governance mode per scope kind (`RosterSeat.governance_mode`); `null` when unread. */
8370
+ governanceMode: Record<string, string> | null;
8371
+ /** `wrapped` | `acp` — how the seat runs; `null` when the seat governance read failed. */
8372
+ transport: string | null;
8373
+ /** The seat's sandbox in words: `container` (the seat floor), `host:<launcher>`, `os_sandbox`,
8374
+ * or `none`. */
8375
+ sandbox: string;
8376
+ /** The last seat-level error the daemon observed, or `null`. */
8377
+ lastError: { at: string; message: string } | null;
8378
+ /** The 7-day record folded from the run store; `null` when the engine has no event-log read
8379
+ * binding, or the fold did not finish inside the snapshot's bound (`statsNote` says which). */
8380
+ stats: SystemCliStats | null;
8381
+ statsNote?: string;
8382
+ /** The `/diagnostics` facts for this CLI, verbatim: `acp` = `acp.byCli[cli]`, `seatGovernance`
8383
+ * = its `seatGovernance.seats[]` entry, `health` = `RosterSeat.health`. */
8384
+ details: {
8385
+ acp: AcpCliDiagnostics | null;
8386
+ seatGovernance: DiagnosticsSeatGovernanceEntry | null;
8387
+ health: SeatHealth | null;
8388
+ };
8389
+ }
8390
+
8391
+ /** A CLI's last 7 days, folded from the runs' durable event logs (event time, `ts`). */
8392
+ export interface SystemCliStats {
8393
+ days: number;
8394
+ /** Window start, unix millis. Day buckets are 24 h slices from here. */
8395
+ since: number;
8396
+ /** When the fold ran (unix millis) — the stats are cached up to 30 s; every probe is not. */
8397
+ asOf: number;
8398
+ /** Distinct units dispatched to the CLI inside the window. */
8399
+ units: number;
8400
+ /** Of those, the units whose first gate evaluation in the window ran. */
8401
+ gated: number;
8402
+ /** Units whose first gate evaluation passed (combined, no denial). */
8403
+ firstPass: number;
8404
+ /** `round(firstPass / gated * 100)`; `null` when `gated` is 0. */
8405
+ passPct: number | null;
8406
+ /** Median of dispatch → captured output per unit attempt on this CLI, ms; `null` when none
8407
+ * finished in the window. */
8408
+ medianUnitMs: number | null;
8409
+ /** `seatBenched` frames for the CLI whose reason is a quota / rate / usage limit (the 429s). */
8410
+ rateLimited: number;
8411
+ /** All `seatBenched` frames for the CLI (any reason). */
8412
+ benches: number;
8413
+ /** `acpFallback` frames for the CLI. */
8414
+ fallbacks: number;
8415
+ /** Units dispatched per 24 h slice, oldest first (`days` entries) — the sparkline. */
8416
+ perDay: number[];
8417
+ /** Tokens, only where the CLI reported them (`cliUsage`); ABSENT otherwise, never 0. */
8418
+ tokens?: { input: number; output: number };
8419
+ /** Dollar cost, only where a price was known; ABSENT otherwise, never 0. */
8420
+ costUsd?: number;
8421
+ /** Runs read for the fold, and whether the run cap cut the window. */
8422
+ runsRead: number;
8423
+ truncated: boolean;
8424
+ }
8425
+
8426
+ // ── runs[] ──
8427
+
8428
+ /**
8429
+ * A run's computed liveness:
8430
+ * - `waiting_on_you` — paused at an open gate or question the operator answers (`gate` says which);
8431
+ * - `held` — paused and escalated (a failed floor, a judge that could not rule, a refused
8432
+ * hand-over: `gateKind: 'escalation'`), or paused with no open gate on record;
8433
+ * - `stalled` — executing with no evidence (an event, unit output or a busy child process) for at
8434
+ * least `stallAfterMs`;
8435
+ * - `quiet` — executing with no evidence for at least `quietAfterMs`;
8436
+ * - `working` — executing with evidence inside `quietAfterMs`. Never claimed without evidence: a
8437
+ * run with no evidence on record at all reads `stalled` (or `quiet` when it began recently).
8438
+ */
8439
+ export type SystemRunLiveness = 'waiting_on_you' | 'held' | 'stalled' | 'quiet' | 'working';
8440
+
8441
+ export interface SystemRun {
8442
+ runId: string;
8443
+ title: string;
8444
+ /** The engine's status (`SessionStatus`). */
8445
+ status: string;
8446
+ liveness: SystemRunLiveness;
8447
+ /** Plain-words why ("waiting on you: plan approval", "no event for 42 min"). */
8448
+ reason: string;
8449
+ /** The cursor unit's phase (`phase_ref`, else `stage`); `null` before planning. */
8450
+ phase: string | null;
8451
+ /** The cursor unit's ord; `null` when none is in flight. */
8452
+ unitOrd: number | null;
8453
+ /** The seat on the cursor unit; `null` when none. */
8454
+ seat: string | null;
8455
+ /** ISO-8601 of the newest evidence of life (an event or a busy process); `null` when none is on
8456
+ * record. */
8457
+ lastEventAt: string | null;
8458
+ /** Where `lastEventAt` came from: the durable event log, the live relay, or a busy process. */
8459
+ evidence: 'event_log' | 'relay' | 'process' | null;
8460
+ /** ms since `lastEventAt`; `null` when there is none. */
8461
+ quietForMs: number | null;
8462
+ /** The thresholds the verdict used (from `workerStallMinutes`). */
8463
+ quietAfterMs: number;
8464
+ stallAfterMs: number;
8465
+ /** The open gate or question, when the run waits on one. */
8466
+ gate?: { interactionId: string | null; ord: number | null; kind: string | null; prompt: string | null };
8467
+ /** ISO-8601 the run was launched, when known. */
8468
+ createdAt: string | null;
8469
+ }
8470
+
8471
+ // ── infra[] ──
8472
+
8473
+ export type SystemInfraKey =
8474
+ | 'daemon'
8475
+ | 'gateway'
8476
+ | 'broker'
8477
+ | 'interactive'
8478
+ | 'estate'
8479
+ | 'bus'
8480
+ | 'vault'
8481
+ | 'skills'
8482
+ | 'state_home'
8483
+ | 'stores'
8484
+ | 'seat_floor'
8485
+ | 'disk'
8486
+ | 'load';
8487
+
8488
+ export interface SystemInfraRow {
8489
+ key: SystemInfraKey;
8490
+ label: string;
8491
+ state: SystemState;
8492
+ /** What the probe saw, in plain words. */
8493
+ reason: string;
8494
+ /** What fixes it; `null` when `ok` / `off`. */
8495
+ remedy: string | null;
8496
+ /** ISO-8601 of when this row's probe settled (or gave up). */
8497
+ checkedAt: string;
8498
+ /** How long the probe took, ms. */
8499
+ durationMs: number;
8500
+ /** The probe's own bound, ms (present on rows that spawn or dial). */
8501
+ timeoutMs?: number;
8502
+ /** The raw probe reading and the `/diagnostics` block(s) this row covers, verbatim
8503
+ * (daemon: `components`, `daemon`, `recentErrors`, `ping`, `warnings`; stores: `stores`;
8504
+ * skills: `skills`; state_home: `stateHome`; estate: `memoryStore`; vault: `vault`;
8505
+ * seat_floor: `rosterFile`, `hostBoundary`, `roleFindings`). */
8506
+ details: Record<string, unknown>;
8507
+ }
8508
+
8509
+ // ── governance[] ──
8510
+
8511
+ export type SystemGovernanceKey =
8512
+ | 'judges'
8513
+ | 'floor_outcomes'
8514
+ | 'qe_acceptance'
8515
+ | 'gates_answered'
8516
+ | 'dead_letters'
8517
+ | 'steering_rules'
8518
+ | 'findings'
8519
+ | 'store';
8520
+
8521
+ export interface SystemGovernanceCard {
8522
+ key: SystemGovernanceKey;
8523
+ label: string;
8524
+ state: SystemState;
8525
+ /** The headline number; `null` when the daemon cannot count it. */
8526
+ value: number | null;
8527
+ /** Counts behind the headline (floor outcomes by kind, gates by who…); absent when none. */
8528
+ breakdown?: Record<string, number>;
8529
+ /** Plain words: what the number means and where it came from. */
8530
+ reason: string;
8531
+ remedy: string | null;
8532
+ /** Window start (unix millis) for the 7-day cards; absent on point-in-time cards. */
8533
+ since?: number;
8534
+ /** The `/diagnostics` facts this card covers, verbatim (store/dead_letters/findings:
8535
+ * `governance`; findings also `decisions` and the skills findings). */
8536
+ details?: Record<string, unknown>;
8537
+ }
8538
+
8038
8539
  // ── Memory proposal queue (DES-MEM-FACETED-001 §5.0, api-types 0.21.0) ─────────
8039
8540
 
8040
8541
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-crew-api-types",
3
- "version": "0.134.0",
3
+ "version": "0.137.0",
4
4
  "description": "The wire contract of the wicked-crew daemon's /api/v1 REST surface and /ws CoreEvent frames \u2014 types only, zero runtime",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",