wicked-crew-api-types 0.122.0 → 0.127.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 (3) hide show
  1. package/README.md +2 -2
  2. package/index.d.ts +243 -16
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -14,8 +14,8 @@ consumers keep the workspace reference.
14
14
 
15
15
  ## Rules
16
16
 
17
- - **Wire shapes only.** Engine-internal types (`LaunchRunInput`, `RepoOnboardRef`, runtime
18
- constants) stay in the daemon.
17
+ - **Wire shapes only.** Engine-internal types (`LaunchRunInput`) and runtime
18
+ constants stay in the daemon.
19
19
  - **Zero runtime.** This is a `.d.ts`-only package: no JavaScript, nothing to build. Consumers
20
20
  declare it as a devDependency (the published `wicked-crew` tarball never depends on it at
21
21
  runtime). Import it with `import type` only — the `exports` map offers just a `types`
package/index.d.ts CHANGED
@@ -10,8 +10,8 @@
10
10
  * carry, which could drift from the daemon silently (task #84).
11
11
  *
12
12
  * Rules of this package:
13
- * - WIRE SHAPES ONLY. Engine-internal types (`LaunchRunInput`,
14
- * `RepoOnboardRef`, runtime constants) stay in `packages/crew/src/core/types.ts`.
13
+ * - WIRE SHAPES ONLY. Engine-internal types (`LaunchRunInput`) and runtime
14
+ * constants stay in `packages/crew/src/core/types.ts`.
15
15
  * - ZERO RUNTIME. This is a `.d.ts`-only package with no JavaScript; import it
16
16
  * with `import type` exclusively. The `exports` map deliberately offers only
17
17
  * a `types` condition, so a value import fails loudly at resolution time.
@@ -801,6 +801,20 @@ export interface WorkUnit {
801
801
  operator_rulings?: OperatorRuling[];
802
802
  /** (crew#894, wicked-core#810) The phase's worker pool (one creator plus monitors). ABSENT = 1. */
803
803
  pool?: number;
804
+ /**
805
+ * (api-types 0.124.0; crew#1058) Daemon-resolved: the seats a reassign of this unit is REFUSED
806
+ * for — the authors of the work it checks (engine `authored_by` plus every earlier Build/Recon
807
+ * agent unit's seat), served on a Review/Test agent unit of a run whose contract enforces a
808
+ * distinct evaluator. `POST /runs/:id/reassign` answers 409 for such a target BEFORE it approves
809
+ * the gate, so a skin offers none of them. ABSENT when no seat is refused, and on an older daemon.
810
+ */
811
+ reassign_refused?: string[];
812
+ /**
813
+ * (api-types 0.124.0) Engine field (`WorkUnit.authored_by`): every seat this unit was ever
814
+ * dispatched on as its author, current seat aside (reassigned and failed-over creators). ABSENT
815
+ * when empty, and on an older engine.
816
+ */
817
+ authored_by?: string[];
804
818
  /** (crew#894) How that pool was seated, once distributed (see {@link UnitPoolSeating}). ABSENT
805
819
  * for a pool of 1 and before distribution. */
806
820
  pool_seating?: UnitPoolSeating;
@@ -1155,6 +1169,22 @@ export interface RosterSeat {
1155
1169
  * `GET /roster/record`. ABSENT when there is no active bench.
1156
1170
  */
1157
1171
  recent_bench?: SeatRecentBench;
1172
+ /**
1173
+ * (unreleased, wicked-core#976) The engine's HOST-FLOOR bench reason for this seat: on the interim
1174
+ * host floor (`WICKED_SEAT_FLOOR` other than `container`) the engine refuses governed work on any
1175
+ * seat that keeps no per-call check there (anything but claude and a bounded codex), in every run.
1176
+ * The seat still reviews, triages and votes (those calls are ungoverned), so `council_eligible`
1177
+ * does not read it; `chat_admission` and `work_admission` (`host_floor_bench`) do. ABSENT when the
1178
+ * engine does not bench the seat, or its addon cannot say.
1179
+ */
1180
+ host_floor_bench?: string;
1181
+ /**
1182
+ * (unreleased, wicked-core#976) Present on the host floor when crew could not read the engine's
1183
+ * host-floor bench and holds no earlier reading: the operator's sentence. Admission then fails
1184
+ * closed — `chat_admission` refuses the seat (source `engine`, unless signed out), and
1185
+ * `work_admission` / `qe_reviewer` are ABSENT (not known).
1186
+ */
1187
+ host_floor_unknown?: string;
1158
1188
  /**
1159
1189
  * (api-types 0.115.0, A5) Whether a job of each scope kind would give the seat work, including
1160
1190
  * the engine's launcher benches (core#769's codex worktree bench, via `Core.worktreeBenched`).
@@ -1221,7 +1251,8 @@ export interface SeatRecentBench {
1221
1251
  reason: string;
1222
1252
  }
1223
1253
 
1224
- /** Why a seat would get no work, one code per refusal (api-types 0.115.0). */
1254
+ /** Why a seat would get no work, one code per refusal (api-types 0.115.0; `host_floor_bench`
1255
+ * unreleased, wicked-core#976: the engine refuses the seat's governed work on the host floor). */
1225
1256
  export type SeatWorkReasonCode =
1226
1257
  | 'signed_out'
1227
1258
  | 'not_enabled'
@@ -1229,11 +1260,12 @@ export type SeatWorkReasonCode =
1229
1260
  | 'recent_bench'
1230
1261
  | 'login_pending'
1231
1262
  | 'worktree_bench'
1263
+ | 'host_floor_bench'
1232
1264
  | 'scope_ungoverned';
1233
1265
 
1234
1266
  /** `RosterSeat.work_admission[scope]` (api-types 0.115.0). `source`: `auth` — signed out;
1235
1267
  * `launcher` — a launch benches it (disabled, reviewer-only, a recent bench, a pending login
1236
- * check, the engine's worktree bench); `scope` — the scope's governance rule refuses it. */
1268
+ * check, the engine's worktree bench or host-floor bench); `scope` — the scope's governance rule refuses it. */
1237
1269
  export type SeatWorkAdmission =
1238
1270
  | { ok: true }
1239
1271
  | { ok: false; reason_code: SeatWorkReasonCode; source: 'auth' | 'launcher' | 'scope'; reason: string };
@@ -1250,7 +1282,8 @@ export type SeatQeReviewer =
1250
1282
 
1251
1283
  /**
1252
1284
  * One `RosterSeat.issues` entry (api-types 0.115.0). Today's codes: `signed_out`, `qe_blocked`
1253
- * (problems); `quota`, `usage_limit`, `benched`, `codex_worktree`, `version_unproven`,
1285
+ * (problems); `quota`, `usage_limit`, `benched`, `codex_worktree`, `host_floor` and `host_floor_unknown`
1286
+ * (unreleased, wicked-core#976), `version_unproven`,
1254
1287
  * `unchecked` (`params.why`: `no_governance` | `no_host_boundary`), `fence_scoped`,
1255
1288
  * `live_check_failed` (warnings); `opt_in`, `no_qe`, `unverified` (notes). A client must tolerate
1256
1289
  * an unknown code.
@@ -1490,6 +1523,13 @@ export interface GateInfo {
1490
1523
  * advisory: it never gates a decision, and is omitted entirely on a normal gate.
1491
1524
  */
1492
1525
  refusal?: { matched: boolean; reason: string };
1526
+ /**
1527
+ * (api-types 0.124.0) WHY the run paused — the `awaitingHuman.gateKind` the live frame carried
1528
+ * (`deliver`, `escalation`, `plan_approval`, …), or the durable row's `gate_kind` after a restart.
1529
+ * A refused hand-over parks at an `escalation` whose `ord` is still the deliver unit: read the
1530
+ * kind, never infer it from the unit. ABSENT on an older daemon and when the engine did not say.
1531
+ */
1532
+ gateKind?: string;
1493
1533
  /** (crew ≥ 0.9.0) The gated unit's persisted receipt (`WorkUnit.assurance`) — what assured the
1494
1534
  * work this gate asks about. `null` when the unit carries none (no gate evaluated it yet, or an
1495
1535
  * older engine); ABSENT on an older daemon. */
@@ -1612,7 +1652,9 @@ export interface LaunchPlan {
1612
1652
  * Body of `POST /runs/:id/reassign` — the manual operator lever that reassigns a wedged run's
1613
1653
  * cursor unit through the same engine path the stall-watchdog's automatic escalation uses
1614
1654
  * (crew#442). `cli` omitted lets the engine's council re-pick the seat; when present it must be
1615
- * a seat in the run's own pool (`SessionView.clis`) or the route answers 400.
1655
+ * a seat in the run's own pool (`SessionView.clis`) or the route answers 400. On a run parked at a
1656
+ * gate with `cli` named (crew#1058), the unit is re-seated FIRST and the gate approved after: a seat
1657
+ * the engine refuses (see `WorkUnit.reassign_refused`) is a 409 with the gate still open.
1616
1658
  */
1617
1659
  export interface ReassignRequest {
1618
1660
  cli?: string;
@@ -1644,6 +1686,16 @@ export interface CoreEvent {
1644
1686
  message?: string;
1645
1687
  /** `elicitationCreated` (DES-002): the id minted by the actor for this elicitation round. */
1646
1688
  elicitationId?: string;
1689
+ /** `elicitationCreated`: 'ask' for worker questions; chat refusal frames retain their source. */
1690
+ source?: 'ask' | ChatRefusalSource;
1691
+ /** The operator's accepted free-text or single-select answer. */
1692
+ answer?: string;
1693
+ heldMs?: number;
1694
+ /**
1695
+ * ask `elicitationCreated` (wicked-core, additive): the seat key that asked — the asking unit's
1696
+ * roster seat for that `attempt` (e.g. `pi`, `codex#2`). Absent for every other producer.
1697
+ */
1698
+ seat?: string;
1647
1699
  /** `elicitationCreated`: an ordered set of valid responses; `null` / absent = free-text. */
1648
1700
  options?: string[] | null;
1649
1701
  /**
@@ -1698,7 +1750,7 @@ export interface CoreEvent {
1698
1750
  /** `terminalOpened`: the working directory the PTY was opened in. */
1699
1751
  cwd?: string;
1700
1752
  // ── DES-STUDIO-COCKPIT-001 §3 B-events (Phase B insight wires) ──
1701
- /** `unitDispatched`/`cliUsage`: 0-based dispatch attempt (`>0` = a re-dispatch / rework). */
1753
+ /** `unitDispatched`/`cliUsage`/ask `elicitationCreated`: 0-based dispatch attempt (`>0` = a re-dispatch / rework). */
1702
1754
  attempt?: number;
1703
1755
  /** `cliUsage`: prompt/input tokens for the unit run. */
1704
1756
  inputTokens?: number;
@@ -5160,6 +5212,18 @@ export interface WorkflowDef {
5160
5212
  * attributed QE PASS, or no push) and is never waived by `reducedAssurance`.
5161
5213
  */
5162
5214
  required_instruments?: string[] | null;
5215
+ /**
5216
+ * (api-types 0.123.0; DES-CHAT-FIRST-001 C2, wicked-core-ts after 0.12.1) How the workflow is
5217
+ * described to an operator: a short display name (`"Build a feature"`). Display data only — the
5218
+ * daemon never sends it to the engine (whose def parser is strict). Served on a built-in that is
5219
+ * not a system workflow, copied from its preset ({@link Preset.title}); ABSENT on a system workflow,
5220
+ * a runtime def, and on any daemon or engine older than the field. Absent ⇒ show the `id`.
5221
+ */
5222
+ title?: string;
5223
+ /** (api-types 0.123.0, C2) One line on what the workflow does. Absent as {@link WorkflowDef.title} is. */
5224
+ summary?: string;
5225
+ /** (api-types 0.123.0, C2) 2–4 short phrases saying when to pick it. Absent as {@link WorkflowDef.title} is. */
5226
+ use_when?: string[];
5163
5227
  }
5164
5228
 
5165
5229
  /** A drop-in workflow definition the ENGINE refused, with the engine's own reason (wicked-crew#718). */
@@ -5659,6 +5723,17 @@ export interface ElicitationInfo {
5659
5723
  * focus, DESIGN-interaction rule 6).
5660
5724
  */
5661
5725
  recommended?: number;
5726
+ /**
5727
+ * (ask) Who asked, relayed from the engine's additive `elicitationCreated` fields for a seat's
5728
+ * MCP `ask` question: `source: "ask"`, the asking unit's `ord` and dispatch `attempt`, and the
5729
+ * `seat` key that asked (the roster instance, e.g. `pi`, `codex#2`). ABSENT for every other
5730
+ * producer and on an engine that predates them; a skin then names the seat running the run's
5731
+ * current step.
5732
+ */
5733
+ source?: 'ask';
5734
+ ord?: number;
5735
+ attempt?: number;
5736
+ seat?: string;
5662
5737
  receivedAt: string;
5663
5738
  }
5664
5739
 
@@ -5751,6 +5826,17 @@ export interface Preset {
5751
5826
  * on every preset it serves (api-types 0.48.0); absent from an older daemon.
5752
5827
  */
5753
5828
  system?: boolean;
5829
+ /**
5830
+ * (api-types 0.123.0; DES-CHAT-FIRST-001 C2, wicked-core-ts after 0.12.1) A short display name,
5831
+ * set by the engine on a built-in row (`created_by: "builtin"`). Absent on a saved preset —
5832
+ * including a project row that shadows a built-in's name — and from an older engine: list it by
5833
+ * `name`.
5834
+ */
5835
+ title?: string;
5836
+ /** (api-types 0.123.0, C2) One line on what the preset does. Absent as {@link Preset.title} is. */
5837
+ summary?: string;
5838
+ /** (api-types 0.123.0, C2) 2–4 short phrases saying when to pick it. Absent as {@link Preset.title} is. */
5839
+ use_when?: string[];
5754
5840
  [k: string]: unknown;
5755
5841
  }
5756
5842
 
@@ -6303,6 +6389,9 @@ export interface InteractionRequest {
6303
6389
  /** The already-run unit the gate reviews, when attributable. */
6304
6390
  reviewing_ord: number | null;
6305
6391
  prompt: string;
6392
+ /** (api-types 0.124.0 types the engine field) WHY the run paused — mirrors
6393
+ * `awaitingHuman.gateKind`. `null`/ABSENT on a row written before the field. */
6394
+ gate_kind?: string | null;
6306
6395
  status: 'open' | 'answered' | 'expired' | 'cancelled';
6307
6396
  /**
6308
6397
  * The decision payload (JSON text, e.g. `{"approve":true,"amend":null}`) once resolved. Its
@@ -7826,18 +7915,35 @@ export interface ListProposalsResponse {
7826
7915
  * landing that could not complete reports `outcome:"failed"` with a loud, operator-readable `error`
7827
7916
  * (recoverable by hand via `POST /governance/rules`) rather than turning the approve into a 500.
7828
7917
  */
7918
+ /**
7919
+ * (api-types 0.126.0) What a proposal is ABOUT — the one `reach` word for memories and policies.
7920
+ * `operator`: how the operator works (style, preferences, standing extra steps, standing rules) —
7921
+ * applies in EVERY project (a memory lands at the operator scope every recall includes; a rule lands
7922
+ * with no project). `project`: that project's or repo's code (a rule lands with `targets.project`).
7923
+ * `pattern` (memories only): a general pattern the person lets cross projects.
7924
+ */
7925
+ export type PolicyReach = 'project' | 'operator';
7926
+ export type MemoryReach = 'project' | 'pattern' | 'operator';
7927
+
7829
7928
  export interface PolicyLandingResult {
7830
- /** `landed` = the steering rule is in the store; `failed` = the proposal is approved but no rule
7831
- * was written — `error` says why. */
7929
+ /** `landed` = the steering rule is in the store and the proposal is approved; `failed` = no rule
7930
+ * is in force — `error` says why. Since crew 0.13.3 the rule lands BEFORE estate marks the
7931
+ * proposal approved, so on `failed` from `POST /proposals/:id/approve` the proposal is still
7932
+ * pending and can be approved again (an older daemon left it approved with no rule). */
7832
7933
  outcome: 'landed' | 'failed';
7833
7934
  /** The upserted rule's id (deterministic `proposal:<proposalId>`, idempotent on replay). Present on `landed`. */
7834
7935
  ruleId?: string;
7936
+ /** (api-types 0.126.0) The reach the rule landed with: `operator` = every project, `project` =
7937
+ * {@link PolicyLandingResult.project} only. Present on `landed` from crew ≥ 0.13.3. */
7938
+ reach?: PolicyReach;
7835
7939
  /** The steering type derived from the proposal's `kind_type` (`policy:<type>`). Present on `landed`. */
7836
7940
  steering_type?: SteeringType;
7837
7941
  /**
7838
7942
  * (api-types 0.77.0, DC-S3) The project the landed rule is scoped to — the proposal's `project`
7839
- * facet, kept as `targets.project` and confirmed by reading the rule back. Absent on a landing
7840
- * with no project (the rule applies everywhere).
7943
+ * facet (else, since crew 0.13.3, the project of the run that filed it), kept as
7944
+ * `targets.project` and confirmed by reading the rule back. Absent on a landing with no project
7945
+ * (the rule applies everywhere). A proposal scoped only to a `repo` that resolves to no project
7946
+ * fails instead of landing everywhere.
7841
7947
  */
7842
7948
  project?: string;
7843
7949
  /** Present iff `outcome:"failed"` — the loud reason the rule did not land. */
@@ -7860,8 +7966,8 @@ export type ApproveProposalResponse =
7860
7966
  * `POST /proposals/:id/approve` body (api-types 0.49.0) — present only for an accept WITH an edit;
7861
7967
  * no body (or `{}`) is the plain approve. estate has no proposal edit, so the daemon submits the
7862
7968
  * edited copy to the same queue (`payload.edited_from = <id>`), approves it, then rejects the
7863
- * original. Memory proposals only (400 otherwise; 404 when `id` is not pending; 409 while another
7864
- * accept of the same `id` is in flight).
7969
+ * original. `content` is for memory proposals only (400 otherwise; 404 when `id` is not pending;
7970
+ * 409 while another accept of the same `id` is in flight); a policy proposal takes `reach` alone.
7865
7971
  */
7866
7972
  export interface ApproveProposalBody {
7867
7973
  /** The edited memory text (replaces `payload.content`). */
@@ -7870,8 +7976,12 @@ export interface ApproveProposalBody {
7870
7976
  * (the human act that lets a pattern cross projects; refused on anything but a captured memory, `payload.capture: "memory"`).
7871
7977
  * `"project"`: it stays scoped to its project — gaining the proposing run's project as its
7872
7978
  * `project` facet when the worker filed none (400 when no project files that run). An accept
7873
- * that changes nothing the store keeps approves the original as filed (no copy, no `edited`). */
7874
- reach?: 'project' | 'pattern';
7979
+ * that changes nothing the store keeps approves the original as filed (no copy, no `edited`).
7980
+ * `"operator"` (api-types 0.126.0): the memory is about how the operator works — it lands at the
7981
+ * operator scope, recalled in every project, with no project/repo facet pinning it to one.
7982
+ * On a POLICY proposal (`reach` only, no `content`): `"operator"` lands the rule for every
7983
+ * project, `"project"` for its project (400 when it names none); `"pattern"` is refused. */
7984
+ reach?: MemoryReach;
7875
7985
  }
7876
7986
 
7877
7987
  /**
@@ -7925,7 +8035,8 @@ export interface CaptureImageFile {
7925
8035
  * per-run inbox and launches a repo-less run filed to the project (through `POST /runs`, so its
7926
8036
  * refusals are that route's). The run's output is proposals in the `/proposals` queue — each with
7927
8037
  * `kind_type: "memory"` (or `"policy:<type>"` for a rule), `payload.capture` = `intent` |
7928
- * `decision` | `memory` | `rule`, `provenance.run_id` = the returned `runId`, and `facets.project`
8038
+ * `choice` | `memory` | `rule` (a memory row filed before crew 0.13.3 may say `decision` for a
8039
+ * `choice`; `decision` on a POLICY row means the decision ledger filed it, DES-decision-capture), `provenance.run_id` = the returned `runId`, and `facets.project`
7929
8040
  * unless the team marked a memory `payload.reach: "pattern"` (the user decides on accept).
7930
8041
  */
7931
8042
  export interface CaptureBody {
@@ -8415,6 +8526,28 @@ export interface RetireMemoryResponse {
8415
8526
  erased: number;
8416
8527
  }
8417
8528
 
8529
+ /**
8530
+ * `POST /memory/edit` body (api-types 0.125.0; wicked-studio's Memory page): change ONE memory's
8531
+ * words. estate has no in-place update, so crew writes `content` as a new memory with the old one's
8532
+ * tier, scope and facets (`memory.capture`), then erases the old one by id. Erase-by-id is checked
8533
+ * before anything is written. When a later step does not answer as expected, crew re-reads the store:
8534
+ * a replacement that landed is a 200; a new copy beside a surviving old memory is taken back out.
8535
+ * 400: empty or unchanged `content`; 404: no memory has that id; 409: an edit of the same memory is in
8536
+ * flight; 501 `estate_upgrade_required`: the estate cannot erase by id (nothing was written); 502: an
8537
+ * estate step failed, and the error says what the store holds now (nothing changed, or which ids remain).
8538
+ */
8539
+ export interface EditMemoryBody {
8540
+ memory_id: string;
8541
+ /** The new words (1–4000 chars, trimmed). */
8542
+ content: string;
8543
+ }
8544
+
8545
+ /** `POST /memory/edit` → 200: the new memory's id and the id of the one it replaced (now erased). */
8546
+ export interface EditMemoryResponse {
8547
+ memory_id: string;
8548
+ retired: string;
8549
+ }
8550
+
8418
8551
  // ── Team events on the bus (DES-TEAMING-002 §6, wicked-core T1; api-types 0.41.0) ──────────────
8419
8552
  //
8420
8553
  // The `wicked.team.*` facts wicked-core publishes on the cross-product bus (`domain`
@@ -10992,3 +11125,97 @@ export interface McpInspectLogResponse {
10992
11125
  state: McpInspectState;
10993
11126
  error: string | null;
10994
11127
  }
11128
+
11129
+ // ── Global search (`GET /search`; api-types 0.127.0) ─────────────────────────────────────────────
11130
+ //
11131
+ // One query over every major entity the daemon can read, answered grouped by type, ranked, with a
11132
+ // snippet per hit. The daemon keeps an in-memory text index it builds lazily on the first search
11133
+ // (off the request path) and keeps current from its own writes and engine frames. A query never
11134
+ // holds the event loop: it yields while it scans, stops at a hard time budget (`partial: true`)
11135
+ // and stops early when the client disconnects (a superseded query).
11136
+
11137
+ /** The searchable entity types, in the order the daemon answers them. */
11138
+ export type SearchType = 'run' | 'project' | 'repo' | 'transcript' | 'rule' | 'memory' | 'doc';
11139
+
11140
+ /** A half-open `[start, end)` UTF-16 range of matched text inside a hit's `title` or `snippet`. */
11141
+ export type SearchSpan = [number, number];
11142
+
11143
+ /** Where a hit opens. A skin maps each kind to its own address. */
11144
+ export type SearchTarget =
11145
+ | { kind: 'run'; run_id: string; chat_id: string | null }
11146
+ | { kind: 'project'; project_id: string }
11147
+ | { kind: 'repo'; repo_id: string }
11148
+ /** A chat's transcript (a live chat: chat transcripts are kept only while the chat is open). */
11149
+ | { kind: 'chat'; chat_id: string }
11150
+ /** One unit's captured output (its transcript) inside a run. */
11151
+ | { kind: 'unit'; run_id: string; ord: number; chat_id: string | null }
11152
+ | { kind: 'rule'; rule_id: string; steering_type: string | null }
11153
+ | { kind: 'memory'; memory_id: string; scope: string }
11154
+ | { kind: 'doc'; project_id: string; doc: string };
11155
+
11156
+ export interface SearchHit {
11157
+ type: SearchType;
11158
+ /** Unique within `type`. */
11159
+ id: string;
11160
+ title: string;
11161
+ /** The matched ranges in `title`. */
11162
+ title_spans: SearchSpan[];
11163
+ /** A short window of the matched body text (whitespace collapsed, `…` where cut); `null` when the hit has no body. */
11164
+ snippet: string | null;
11165
+ snippet_spans: SearchSpan[];
11166
+ /** Higher is better; comparable only within one group. */
11167
+ score: number;
11168
+ /** Unix MILLIS of the entity's last known change, when the daemon knows it. */
11169
+ updated_at: number | null;
11170
+ project_id: string | null;
11171
+ /** The entity's own state word where it has one (a run's status, `retired`, `archived`), else `null`. */
11172
+ status: string | null;
11173
+ target: SearchTarget;
11174
+ }
11175
+
11176
+ export interface SearchGroup {
11177
+ type: SearchType;
11178
+ /** Every match the query found in this type (a lower bound when `partial`). */
11179
+ total: number;
11180
+ /** This page, best first. */
11181
+ hits: SearchHit[];
11182
+ /** Pass back as `cursor` (with `types=<this type>`) for the next page; `null` on the last page. */
11183
+ next_cursor: string | null;
11184
+ }
11185
+
11186
+ /**
11187
+ * How much of a type the index holds. `indexing`: the first read of that source is still running
11188
+ * (search again shortly); `unavailable`: the source could not be read (`note` says why), so the
11189
+ * type was not searched.
11190
+ */
11191
+ export interface SearchSourceState {
11192
+ type: SearchType;
11193
+ state: 'ready' | 'indexing' | 'unavailable';
11194
+ /** Entities of this type the index holds. */
11195
+ indexed: number;
11196
+ note: string | null;
11197
+ }
11198
+
11199
+ /**
11200
+ * `GET /search?q=&types=&limit=&cursor=` → 200.
11201
+ *
11202
+ * - `q` (required, 2–256 chars after trimming): words (each must match, case-insensitive, anywhere
11203
+ * in a title or body) and `"quoted phrases"`. 400 when missing, too short or too long.
11204
+ * - `types`: comma-separated `SearchType`s (default every type). 400 on an unknown type.
11205
+ * - `limit`: hits per group, 1–50 (default 5).
11206
+ * - `cursor`: a group's `next_cursor`; needs exactly one type in `types` (400 otherwise).
11207
+ *
11208
+ * Unit transcripts are indexed from a capped head and tail of each output (the full output stays at
11209
+ * `GET /runs/:id/units/:unit/output`); the oldest transcripts leave the index first when its text
11210
+ * budget is full.
11211
+ */
11212
+ export interface SearchResponse {
11213
+ query: string;
11214
+ /** One group per searched type with at least one hit, in `SearchType` order. */
11215
+ groups: SearchGroup[];
11216
+ /** One row per requested type. */
11217
+ sources: SearchSourceState[];
11218
+ /** The time budget ran out before every type was scanned: totals are lower bounds. */
11219
+ partial: boolean;
11220
+ took_ms: number;
11221
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-crew-api-types",
3
- "version": "0.122.0",
3
+ "version": "0.127.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",