wicked-crew-api-types 0.167.0 → 0.170.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 +462 -3
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -359,6 +359,43 @@ export interface HealthCapabilities {
359
359
  * the model are on this machine) is {@link VoiceStatus.ready}. ABSENT on an older daemon: read as `false`.
360
360
  */
361
361
  voice?: boolean;
362
+ /**
363
+ * (api-types 0.168.0) `GET /workflows/catalog` is served: the categorised workflow catalog with the
364
+ * requesting operator's usage ({@link WorkflowCatalogResponse}). ABSENT on an older daemon: read as `false`.
365
+ */
366
+ workflowCatalog?: boolean;
367
+ /**
368
+ * (api-types 0.169.0, DES-CHAT-ARTIFACTS-001 §14) What a chat can do with artifacts, one flag per operation, each
369
+ * true only once its slice ships. `context`: `ChatMessageBody.context` is accepted ({@link ChatMessageContext}),
370
+ * `POST /chats {seedFromArtifact}` is served, and each turn's seats get the open artifact, the runs the person names
371
+ * and the ids they may use, recorded per turn as a `context` transcript record. `proposals` (api-types 0.170.0,
372
+ * slice A2): a seat's `wicked-make` block becomes a crew-resolved proposal card answered by a person. The operations
373
+ * (`create`, `refine`, `theme`, `demo`) are later slices and are `false` until then (all `true` with `stub: true` in
374
+ * the test configuration). ABSENT on an older daemon: read every flag as `false`, and send no `context` (the message
375
+ * body is strict there, so the field would be refused).
376
+ */
377
+ chatArtifacts?: ChatArtifactsCapabilities;
378
+ }
379
+
380
+ /** {@link HealthCapabilities.chatArtifacts} (api-types 0.169.0). */
381
+ export interface ChatArtifactsCapabilities {
382
+ context: boolean;
383
+ /**
384
+ * (api-types 0.170.0, slice A2) A seat's `wicked-make` block becomes a crew-resolved proposal ({@link ArtifactProposal},
385
+ * transcript kinds `proposal` / `proposal_accepting` / `proposal_decided`, `/ws` {@link ChatProposalFrame}) and
386
+ * `POST /chats/:id/proposals/:pid` answers it. Seats are told only about the operations below that are `true`, and
387
+ * the resolver and the accept route refuse the others, so with every operation `false` no card is made.
388
+ */
389
+ proposals: boolean;
390
+ create: boolean;
391
+ refine: boolean;
392
+ theme: boolean;
393
+ demo: boolean;
394
+ /**
395
+ * (api-types 0.170.0) The daemon runs the chat-artifacts TEST configuration (DES §13 A2): every operation resolves,
396
+ * and Go on a proposal records a stub dispatch and starts NOTHING. A skin says so on the card. ABSENT otherwise.
397
+ */
398
+ stub?: true;
362
399
  }
363
400
 
364
401
  // ── A run's working document (program DES-POWER-MODE §8.3, §9; api-types 0.148.0) ──────────────────
@@ -7295,6 +7332,115 @@ export interface PresetResponse {
7295
7332
  preset: Preset;
7296
7333
  }
7297
7334
 
7335
+ // ── The workflow catalog (api-types 0.168.0, lane wf-catalog) ───────────────────────────────────
7336
+
7337
+ /** A catalog category id. `yours` is listed only when the operator has saved presets. */
7338
+ export type WorkflowCatalogCategoryId = 'create' | 'resolve' | 'analyze' | 'test' | 'more' | 'yours';
7339
+
7340
+ /** One category of the catalog, in display order, with its ordered subcategories (`[]` for `more` and `yours`). */
7341
+ export interface WorkflowCatalogCategory {
7342
+ id: WorkflowCatalogCategoryId;
7343
+ title: string;
7344
+ /** One line under the heading. */
7345
+ summary: string;
7346
+ subcategories: { id: string; title: string }[];
7347
+ }
7348
+
7349
+ /** What a catalog entry needs before it can start. */
7350
+ export type WorkflowCatalogNeed = 'repo' | 'project' | 'running_app' | 'requirements' | 'document' | 'runs' | 'nothing';
7351
+
7352
+ /** One field the launch asks for, in order. */
7353
+ export interface WorkflowCatalogInput {
7354
+ id: string;
7355
+ label: string;
7356
+ kind: 'text' | 'repo' | 'project' | 'url' | 'requirements' | 'seats';
7357
+ required: boolean;
7358
+ }
7359
+
7360
+ /**
7361
+ * How a client starts an entry: `run` = `POST /runs {workflow}`; `demo` = `POST /projects/:id/demo`;
7362
+ * `compose` = `POST /projects/:id/product/compose` (draft epics); `document` = a new interactive document
7363
+ * of that style (its draft run); `chat` = a chat on its own page; `none` = nothing to launch (coming soon).
7364
+ */
7365
+ export type WorkflowCatalogLaunch =
7366
+ | { kind: 'run'; workflow: string }
7367
+ | { kind: 'demo' }
7368
+ | { kind: 'compose' }
7369
+ | { kind: 'document'; style: 'web' | 'doc' | 'ppt' | 'brochure' }
7370
+ | { kind: 'chat' }
7371
+ | { kind: 'none' };
7372
+
7373
+ /** The requesting operator's use of an entry (scope: {@link WorkflowCatalogResponse.usage}). */
7374
+ export interface WorkflowCatalogUsage {
7375
+ /** Runs this operator launched under the entry's workflow (a retry is not a new launch). */
7376
+ launches: number;
7377
+ /** ISO 8601 launch time of the newest such run, or null. */
7378
+ lastUsedAt: string | null;
7379
+ /** Median wall time in minutes of those runs that COMPLETED, or null when none did. */
7380
+ medianMinutes: number | null;
7381
+ }
7382
+
7383
+ /** One card of the catalog. */
7384
+ export interface WorkflowCatalogEntry {
7385
+ /**
7386
+ * Unique, opaque card id. For `launch.kind === 'run'` it is `launch.workflow`, prefixed `run:` when a non-run
7387
+ * card already holds that id (a saved preset called `presentation`). Launch by `launch.workflow`, never by `id`.
7388
+ */
7389
+ id: string;
7390
+ category: WorkflowCatalogCategoryId;
7391
+ /** A subcategory id of its category, or null. */
7392
+ subcategory: string | null;
7393
+ title: string;
7394
+ /** What it does, one line. */
7395
+ summary: string;
7396
+ /** What you get, one line. */
7397
+ outcome: string;
7398
+ /** 0–4 short phrases saying when to pick it. */
7399
+ useWhen: string[];
7400
+ needs: WorkflowCatalogNeed[];
7401
+ inputs: WorkflowCatalogInput[];
7402
+ /** Static hint in minutes `[low, high]` from observed runs; null = not known. */
7403
+ typicalMinutes: [number, number] | null;
7404
+ /** Relative cost hint (agent phases and seats); null = not known. */
7405
+ cost: 'low' | 'medium' | 'high' | null;
7406
+ /** Shown as chips; searchable. */
7407
+ tags: string[];
7408
+ /** Searchable only. */
7409
+ synonyms: string[];
7410
+ status: 'available' | 'coming_soon' | 'unavailable';
7411
+ /** Why coming soon or unavailable; null when available. */
7412
+ statusNote: string | null;
7413
+ launch: WorkflowCatalogLaunch;
7414
+ /** The workflow requires QE acceptance before it delivers. */
7415
+ requiresQe: boolean;
7416
+ delivers: 'pr' | 'document' | 'video' | 'report' | 'answer' | 'none';
7417
+ /** Where the definition lives: the engine's built-in preset, a crew workflow, the operator's saved preset, studio's own flow, or none yet. */
7418
+ source: 'builtin' | 'crew' | 'saved' | 'studio' | 'none';
7419
+ usage: WorkflowCatalogUsage;
7420
+ }
7421
+
7422
+ /**
7423
+ * `GET /workflows/catalog[?projectId=]` (api-types 0.168.0): the workflows as a categorised catalog with
7424
+ * the requesting operator's usage, derived from the runs the daemon already records (the `run.launched`
7425
+ * trail's principal, the run's resolved workflow). Additive: `GET /workflows` is unchanged.
7426
+ */
7427
+ export interface WorkflowCatalogResponse {
7428
+ categories: WorkflowCatalogCategory[];
7429
+ /** By category order, then subcategory order, then catalog order. */
7430
+ entries: WorkflowCatalogEntry[];
7431
+ /** "Your top": up to 6 available entry ids with launches, by launches then most recent. */
7432
+ top: string[];
7433
+ usage: {
7434
+ /** `operator`: every run this principal launched; `project`: only those filed in `projectId`. */
7435
+ scope: 'operator' | 'project';
7436
+ projectId: string | null;
7437
+ /** The principal the usage is for (`Actor.id`; `local` on a loopback daemon). */
7438
+ actorId: string;
7439
+ /** Runs counted across every entry. */
7440
+ launches: number;
7441
+ };
7442
+ }
7443
+
7298
7444
  // ── Projects (DES-PROJECT-001) — the experience-plane keystone ─────────────────
7299
7445
 
7300
7446
  /** Project lifecycle: `active ⇄ archived`, no hard delete (ADR §1.3). */
@@ -7905,6 +8051,18 @@ export interface ChatOpenBody {
7905
8051
  * engine without it is a 409. Send it only when `GET /health.capabilities.chatWorkflows` names it.
7906
8052
  */
7907
8053
  workflow?: string;
8054
+ /**
8055
+ * (api-types 0.169.0, DES-CHAT-ARTIFACTS-001 §6.3) "Ask about this" on a document no open chat holds: the
8056
+ * artifact ref (`<mount>/<doc>`). Allowed for a chat with no `projectId`, or for a project chat whose project is the
8057
+ * document's mount (checked before anything is read; else 400 `seed_out_of_scope`). Crew then checks the document
8058
+ * exists (404 `seed_not_found`) and, for a project chat, that every repository it was made about belongs to the
8059
+ * project (else 400 `seed_out_of_scope`). When the request names no `repoRefs` and its `scopeKind` is not
8060
+ * `everything` or `project`, the chat reads the repositories the document was made about (its recorded binding);
8061
+ * a `system` or `none` kind then becomes the repository scope. A document made about no repository seeds nothing.
8062
+ * A non-person actor is refused (403 `seed_refused`). Send only when
8063
+ * `GET /health.capabilities.chatArtifacts.context === true`.
8064
+ */
8065
+ seedFromArtifact?: string;
7908
8066
  }
7909
8067
 
7910
8068
  /** The scope a `POST /chats` caller may name (api-types 0.39.0, studio#323 R4). */
@@ -8205,7 +8363,17 @@ export interface ChatUsage {
8205
8363
  */
8206
8364
  export type ChatTranscriptRecord =
8207
8365
  /** `attachments` (api-types 0.137.0): the files the message carried, ABSENT when none. */
8208
- | { at: number; turnId: string; kind: 'user'; text: string; seats: string[]; attachments?: ChatAttachment[] }
8366
+ | {
8367
+ at: number;
8368
+ turnId: string;
8369
+ kind: 'user';
8370
+ text: string;
8371
+ seats: string[];
8372
+ attachments?: ChatAttachment[];
8373
+ /** (api-types 0.170.0) Sent by the chat's owner, a person (the message route's own check). Only these words count
8374
+ * as the person's for a proposal (a demo address, a document they named). ABSENT for any other sender. */
8375
+ owner?: true;
8376
+ }
8209
8377
  | { at: number; turnId: string; kind: 'seat'; cliKey: string; text: string; ok: boolean; usage: ChatUsage | null }
8210
8378
  /**
8211
8379
  * The citation verdicts of the `seat` record with the same `turnId` + `cliKey` (api-types 0.68.0,
@@ -8238,7 +8406,218 @@ export type ChatTranscriptRecord =
8238
8406
  * 0.85.0, DC-S7): the rules remembered since they last heard from crew. Disclosed here so the
8239
8407
  * operator sees exactly what crew added; the `user` record keeps the operator's own words.
8240
8408
  */
8241
- | { at: number; turnId: string; kind: 'system'; text: string };
8409
+ | { at: number; turnId: string; kind: 'system'; text: string }
8410
+ /**
8411
+ * What the seats of `turnId` were given beside the operator's words (api-types 0.169.0, DES-CHAT-ARTIFACTS-001
8412
+ * §5.1): the open artifact's copies, the run briefs, and what was refused. Written with the turn's `user` record.
8413
+ */
8414
+ | ({ at: number; turnId: string; kind: 'context' } & ChatContextBinding)
8415
+ /**
8416
+ * (api-types 0.170.0, DES-CHAT-ARTIFACTS-001 §4.2) A proposal crew resolved from a seat's `wicked-make` block in the
8417
+ * reply of `turnId`. A later `proposal` record with the same `proposal.pid` REPLACES it (a re-resolution after the
8418
+ * document's head moved); a newer pid in the same chat supersedes an open one.
8419
+ */
8420
+ | { at: number; turnId: string; kind: 'proposal'; proposal: ArtifactProposal }
8421
+ /** (api-types 0.170.0, §4.3 step 2) A person said go: what was accepted, written before anything starts. */
8422
+ | ({ at: number; turnId: string; kind: 'proposal_accepting' } & ProposalAccepting)
8423
+ /** (api-types 0.170.0) The proposal's answer: go (with what it started) or not now. */
8424
+ | ({ at: number; turnId: string; kind: 'proposal_decided' } & ProposalDecided);
8425
+
8426
+ // ── Chat proposals (api-types 0.170.0, DES-CHAT-ARTIFACTS-001 §4, slice A2) ─────────────────────────────────────────
8427
+ //
8428
+ // A seat proposes an artifact job in a fenced `wicked-make` block. Crew cuts it out of the reply (it never reaches a
8429
+ // reader), resolves it against its own records, and appends a `proposal` transcript record plus a `chatProposal`
8430
+ // frame. The card's facts are crew's, never the seat's. Only `POST /chats/:id/proposals/:pid` (a person, the chat's
8431
+ // owner) starts anything. Capabilities: `GET /health.capabilities.chatArtifacts.proposals` and one flag per operation.
8432
+
8433
+ /** What a proposal makes. `create` and `demo` come from a catalog entry; `refine` changes a document; `theme` is a
8434
+ * studio appearance patch. */
8435
+ export type ArtifactProposalKind = 'create' | 'refine' | 'theme' | 'demo';
8436
+
8437
+ /** One "From" chip: a source the block named, as crew resolved and authorized it. */
8438
+ export interface ProposalSource {
8439
+ /** The token as crew reads it: `chat`, `page`, `message:<turnId>`, `run:<full id>`, `doc:<mount>/<doc>`,
8440
+ * `attachment:<id>` (a run prefix the seat wrote is resolved to the full id when it can be). */
8441
+ token: string;
8442
+ /** Plain words: "this conversation", "run 29bbbfb1 · stopped", "Release note v4". */
8443
+ label: string;
8444
+ /** `struck`: the draft never sees it; `reason` says why ("run 1a2b3c4d · not named in this chat"). */
8445
+ status: 'ok' | 'struck';
8446
+ reason?: string;
8447
+ /** The project the source belongs to (`null`: Unfiled, or not a project's); absent for `chat` and `page`. A form that
8448
+ * changes the project strikes a chip whose project differs. */
8449
+ projectId?: string | null;
8450
+ }
8451
+
8452
+ /** "Codex and Claude Code: one writes, the other checks": two distinct eligible seats (never who writes). */
8453
+ export interface ProposalHelpers {
8454
+ seats: string[];
8455
+ label: string;
8456
+ }
8457
+
8458
+ /** "About 10–20 min · 3 agent steps · median of 4 past documents here: 9 min, $0.62". Unknown parts are left out. */
8459
+ export interface ProposalTime {
8460
+ /** The catalog entry's `typicalMinutes`. */
8461
+ minutes: [number, number] | null;
8462
+ /** The catalog entry's relative cost. */
8463
+ cost: 'low' | 'medium' | 'high' | null;
8464
+ /** Agent steps of the workflow. */
8465
+ steps: number | null;
8466
+ /** Over completed runs of the same workflow on this daemon. `costUsd` only from at least 3 runs whose every agent
8467
+ * step reported a cost (`costRuns` of them); else `null`. */
8468
+ median: { runs: number; minutes: number; costUsd: number | null; costRuns: number } | null;
8469
+ label: string;
8470
+ }
8471
+
8472
+ /** A proposal as crew resolved it. Every line is crew's: the seat chose only the block's words. */
8473
+ export interface ArtifactProposal {
8474
+ /** `<chatId>:<turnId>` for a turn's proposal (later slices add `<chatId>:redo:<runId>` / `:retry:`). */
8475
+ pid: string;
8476
+ chatId: string;
8477
+ /** The turn whose reply carried the block; `null` for a crew-made proposal (`sourceRunId`). */
8478
+ turnId: string | null;
8479
+ sourceRunId?: string;
8480
+ kind: ArtifactProposalKind;
8481
+ /** The seat that wrote the block. */
8482
+ seat: string;
8483
+ /** The "What" line: `label` is "Slides · Domain coverage for new engineers"; `outcome` is the catalog entry's. */
8484
+ what: { entry: string | null; title: string; label: string; outcome: string | null };
8485
+ /** The brief (create), the ask (refine), or what to show (demo), as the seat wrote it. */
8486
+ brief: string | null;
8487
+ reason: string | null;
8488
+ sources: ProposalSource[];
8489
+ /** Repositories (names), each in the chat's scope. */
8490
+ repos: string[];
8491
+ /** `null` for a theme (no run). */
8492
+ helpers: ProposalHelpers | null;
8493
+ /** `null` for a theme. */
8494
+ time: ProposalTime | null;
8495
+ /** "Stops for you if the check fails. The plan or an escalation may also ask." `null` for a theme. */
8496
+ stops: string | null;
8497
+ /** The project the result is filed in; `label` is the project's name or "Not in a project · this chat". */
8498
+ filedIn: { projectId: string | null; label: string };
8499
+ /** refine: the document (`<mount>/<doc>`), its title, and the head it was proposed on. */
8500
+ target?: { ref: string; title: string; base: number };
8501
+ /** refine: the parts the seat pointed at (`data-wid`s); hand edits are kept unless the person says otherwise. */
8502
+ touches?: string[];
8503
+ /** theme: the partial appearance patch and the keys it changes. */
8504
+ theme?: { name: string; patch: Record<string, string | number | boolean>; changes: string[] };
8505
+ /** demo: the app address (from the person's words), the audience and what to show. */
8506
+ demo?: { url: string; audience: string | null; show: string | null };
8507
+ /** Go is refused with this reason ("Needs a second helper to check it"); the card shows it. `null` = Go is open. */
8508
+ blocked: string | null;
8509
+ }
8510
+
8511
+ /**
8512
+ * What a person may change before Go (typed per kind; crew re-checks every edit with the rules of §4.2). In this
8513
+ * release (slice A2) crew takes `title`, `brief`, `sources` and `helpers` on a create, `ask` and `helpers` on a refine,
8514
+ * `name` and `patch` on a theme, and `audience`, `show` and `helpers` on a demo; `project`, `repos`, `url` and `allow`
8515
+ * are refused (400 `edits_invalid`) until the slices whose forms edit them. A source the person adds that cannot be used
8516
+ * is refused too, never dropped. An interrupted (accepting) proposal resumes with its accepted choices: only its
8517
+ * `helpers` may change.
8518
+ */
8519
+ export interface ProposalEdits {
8520
+ /** create */
8521
+ title?: string;
8522
+ brief?: string;
8523
+ sources?: string[];
8524
+ repos?: string[];
8525
+ project?: string | null;
8526
+ /** refine */
8527
+ ask?: string;
8528
+ allow?: string[];
8529
+ /** theme */
8530
+ name?: string;
8531
+ patch?: Record<string, string | number | boolean>;
8532
+ /** demo */
8533
+ url?: string;
8534
+ audience?: string;
8535
+ show?: string;
8536
+ /** any kind with a run */
8537
+ helpers?: string[];
8538
+ }
8539
+
8540
+ /** What the accepted proposal is named by: the artifact, and the run derived from the pid. */
8541
+ export interface ProposalIdentity {
8542
+ /** `<mount>/<doc>`: the document a create makes (its name derived from the pid) or a refine changes; `null` for a
8543
+ * theme or a demo. */
8544
+ artifactRef: string | null;
8545
+ /** A name-based UUID of the pid: the launch's `sessionId`, so a retry can only adopt it. */
8546
+ runId: string;
8547
+ }
8548
+
8549
+ /** What Go started. */
8550
+ export interface ProposalResult {
8551
+ runId: string;
8552
+ artifactRef: string | null;
8553
+ /** Found already launched (a retry, a second tab) and adopted rather than started again. */
8554
+ adopted: boolean;
8555
+ /** The test configuration's recording stub took it: nothing was started. */
8556
+ stub: boolean;
8557
+ }
8558
+
8559
+ export interface ProposalAccepting {
8560
+ pid: string;
8561
+ /** The person's actor id. */
8562
+ actor: string;
8563
+ edits: ProposalEdits | null;
8564
+ /** The effective proposal after the edits were applied and checked. */
8565
+ resolution: ArtifactProposal;
8566
+ identity: ProposalIdentity;
8567
+ }
8568
+
8569
+ export interface ProposalDecided {
8570
+ pid: string;
8571
+ actor: string;
8572
+ decision: 'go' | 'not_now';
8573
+ /** `null` for not now. */
8574
+ result: ProposalResult | null;
8575
+ }
8576
+
8577
+ /** A proposal folded from its records. */
8578
+ export interface ChatProposalView {
8579
+ proposal: ArtifactProposal;
8580
+ /** `accepting`: Go was recorded and its result was not (an interrupted Go: "Go again" resumes the same identity). */
8581
+ state: 'open' | 'accepting' | 'decided' | 'superseded';
8582
+ decision?: 'go' | 'not_now';
8583
+ result?: ProposalResult | null;
8584
+ /** Unix millis of the decision. */
8585
+ decidedAt?: number;
8586
+ }
8587
+
8588
+ /** `POST /chats/:id/proposals/:pid` body. */
8589
+ export interface ChatProposalDecisionBody {
8590
+ decision: 'go' | 'not_now';
8591
+ edits?: ProposalEdits;
8592
+ }
8593
+
8594
+ /**
8595
+ * `POST /chats/:id/proposals/:pid` → 200: the proposal as decided (a repeat of the same decision answers the stored
8596
+ * result again, so a lost response is safe to retry). Only a person answers: under `auth: required` a worker, agent or
8597
+ * system token is refused; under `auth: off` every request is the local person (the daemon's documented local-mode
8598
+ * posture, as for gates). Refusals carry `code`: 403 `proposal_refused` (not a person),
8599
+ * 404 (no such chat or proposal, or a chat that is not the caller's under `auth: required`: its existence is not
8600
+ * disclosed), 409 `proposal_superseded` | `proposal_decided` | `proposal_blocked` | `operation_unavailable` |
8601
+ * `chat_busy` | `document_busy` | `source_gone` | `helper_unavailable` | `chat_gone` | `proposal_reresolved` (the
8602
+ * document moved: `view.proposal` is the fresh one), 400 `edits_invalid`, 502 `launch_failed` (accepting stays
8603
+ * recorded; Go again resumes the same identity). A 409 carries the current `view` when there is one.
8604
+ */
8605
+ export interface ChatProposalDecisionResponse {
8606
+ view: ChatProposalView;
8607
+ }
8608
+
8609
+ /**
8610
+ * `/ws` (api-types 0.170.0): a proposal record was appended to chat `chat` (the same record the transcript holds).
8611
+ * `project_id`: the chat's project, when it has one. A `type` alias (like the daemon's other synthetic frames) so it
8612
+ * satisfies {@link CoreEvent}'s index signature.
8613
+ */
8614
+ export type ChatProposalFrame = {
8615
+ type: 'chatProposal';
8616
+ chat: string;
8617
+ turn_id: string;
8618
+ record: Extract<ChatTranscriptRecord, { kind: 'proposal' | 'proposal_accepting' | 'proposal_decided' }>;
8619
+ project_id?: string;
8620
+ };
8242
8621
 
8243
8622
  // ── System chat: history, close, attachments (api-types 0.137.0, DES-SYSTEM-CHAT "Crew") ────────
8244
8623
  //
@@ -8365,6 +8744,84 @@ export interface ChatMessageBody {
8365
8744
  * file: a path it can open (images as images where the CLI reads them) plus, for text and pdf,
8366
8745
  * the extracted text. Send only when `GET /health.capabilities.chatAttachments === true`. */
8367
8746
  attachments?: string[];
8747
+ /**
8748
+ * (api-types 0.169.0, DES-CHAT-ARTIFACTS-001 §5.1) What studio shows beside the message: the artifact open on the
8749
+ * surface it was sent from, the tab's appearance, and studio's page summary. Send only when
8750
+ * `GET /health.capabilities.chatArtifacts.context === true`. Crew checks the chat's owner and scope before it
8751
+ * reads anything; the seat gets labelled copies (data, never instructions), and the turn's `context` transcript
8752
+ * record says what it was given.
8753
+ */
8754
+ context?: ChatMessageContext;
8755
+ }
8756
+
8757
+ /** {@link ChatMessageBody.context} (api-types 0.169.0). */
8758
+ export interface ChatMessageContext {
8759
+ /** The artifact on the surface the message was sent from (inline, pane, Made or full screen). */
8760
+ artifact?: ChatArtifactContext;
8761
+ /** The tab's effective appearance (DES §9), sent when `chatArtifacts.theme` is advertised. */
8762
+ appearance?: ChatContextAppearance;
8763
+ /**
8764
+ * Studio's page summary (the context pack), kept apart from the person's typed words. Crew labels it as studio's
8765
+ * and reads from it only the run of the page it describes and the runs added as chips. At most 32,768 characters.
8766
+ */
8767
+ page?: string;
8768
+ }
8769
+
8770
+ /** {@link ChatMessageContext.artifact} (api-types 0.169.0). */
8771
+ export interface ChatArtifactContext {
8772
+ /** `<mount>/<doc>`: the mount is a project id or `_unfiled`; the doc is the interactive document name. */
8773
+ ref: string;
8774
+ /** The version the person is looking at (≥ 0: a document's first version is 0), read after the editor's in-flight
8775
+ * writes finished. */
8776
+ version: number;
8777
+ /** The `data-wid` of each part the person selected (at most 16). */
8778
+ anchors?: string[];
8779
+ }
8780
+
8781
+ /** {@link ChatMessageContext.appearance} (api-types 0.169.0): studio's appearance scalars, plus an active preview. */
8782
+ export interface ChatContextAppearance {
8783
+ theme?: string;
8784
+ accent_h?: number;
8785
+ accent_s?: number;
8786
+ accent_l?: number;
8787
+ ambient?: boolean;
8788
+ ambient_still?: boolean;
8789
+ /** The name of the theme proposal being previewed, when one is. */
8790
+ previewOf?: string;
8791
+ }
8792
+
8793
+ /**
8794
+ * What one turn's seats were given (api-types 0.169.0, DES-CHAT-ARTIFACTS-001 §5.1 "Bindings kept"): the `context`
8795
+ * transcript record. Paths are relative to the chat's scratch root. A reader folds it onto the turn's `user` record; a
8796
+ * skin that does not know this kind ignores it.
8797
+ */
8798
+ export interface ChatContextBinding {
8799
+ /** The open artifact, when the message carried one in scope. */
8800
+ artifact?: {
8801
+ ref: string;
8802
+ title: string;
8803
+ kind: string;
8804
+ /** The version the person was looking at, and the latest when the turn was sent. */
8805
+ viewed: number;
8806
+ head: number;
8807
+ /** `null` for an Unfiled document. */
8808
+ projectId: string | null;
8809
+ /** The copies the seat read: `open/<mount>__<doc>-v<n>.html`. When the version they look at is missing or could
8810
+ * not be copied, only the latest's copy is here, and `viewed` still says what they asked about. */
8811
+ copies: string[];
8812
+ anchors: string[];
8813
+ };
8814
+ /** The run briefs the seat was given: `context/run-<id>-<sha8>.md` (named by content, so a later brief of the same
8815
+ * run never replaces these bytes), with the sha256 of the brief as written. */
8816
+ runs: Array<{ id: string; status: string; brief: string; sha256: string }>;
8817
+ /** What was named but not read, and why ("not in this chat's project", "no such run on this daemon"). */
8818
+ refused: Array<{ token: string; reason: string }>;
8819
+ /** Every run and document the person has named in this chat up to this turn. On later turns a run is kept while it
8820
+ * is still on this daemon and in the chat's scope, a document while it is in the chat's scope; an earlier brief is
8821
+ * offered again only while its file still holds the bytes its sha256 records. */
8822
+ named: { runs: string[]; docs: string[] };
8823
+ /** Studio's page summary rode as `context.page` (true), never mixed into the person's words. */
8824
+ page: boolean;
8368
8825
  }
8369
8826
 
8370
8827
  /** `GET /chats/:id` → 200. */
@@ -9811,7 +10268,9 @@ export interface SystemRun {
9811
10268
  liveness: SystemRunLiveness;
9812
10269
  /** Plain-words why ("waiting on you: plan approval", "no event for 42 min"). */
9813
10270
  reason: string;
9814
- /** The cursor unit's phase (`phase_ref`, else `stage`); `null` before planning. */
10271
+ /** The step the cursor unit is on, as display words: the step id its unit id names (`answer-1` → `answer 1`),
10272
+ * else a named `phase_ref`, else its catalog entry, else its `stage`; an engine-numbered step (`unit-N`, `uN`)
10273
+ * never shows. `null` before planning. */
9815
10274
  phase: string | null;
9816
10275
  /** The cursor unit's ord; `null` when none is in flight. */
9817
10276
  unitOrd: number | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-crew-api-types",
3
- "version": "0.167.0",
3
+ "version": "0.170.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",