wicked-crew-api-types 0.149.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.
- package/index.d.ts +1267 -15
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -353,6 +353,49 @@ export interface HealthCapabilities {
|
|
|
353
353
|
* ABSENT on an older daemon: read as `false` and hide the switch.
|
|
354
354
|
*/
|
|
355
355
|
powerMode?: boolean | undefined;
|
|
356
|
+
/**
|
|
357
|
+
* (api-types 0.156.0, DES-VOICE) Voice mode's routes are served: `GET /voice/status`, `POST|DELETE /voice/model`,
|
|
358
|
+
* `POST /voice/transcribe` and `GET|PUT /voice/dashboard`. Whether transcription can run NOW (the engine and
|
|
359
|
+
* the model are on this machine) is {@link VoiceStatus.ready}. ABSENT on an older daemon: read as `false`.
|
|
360
|
+
*/
|
|
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;
|
|
356
399
|
}
|
|
357
400
|
|
|
358
401
|
// ── A run's working document (program DES-POWER-MODE §8.3, §9; api-types 0.148.0) ──────────────────
|
|
@@ -360,10 +403,12 @@ export interface HealthCapabilities {
|
|
|
360
403
|
/** The working document's sections, in order. */
|
|
361
404
|
export type WorkingDocSectionId = 'goal' | 'approach' | 'decisions' | 'constraints' | 'questions' | 'next';
|
|
362
405
|
|
|
363
|
-
/** Who wrote a version: a person (the operator), a plugin's own generated lines,
|
|
406
|
+
/** Who wrote a version: a person (the operator), a plugin's own generated lines, the power orchestrator's own notes
|
|
407
|
+
* (`agent`, id `agent:<seat>`: Approach and Decisions only, never a steer), or crew (the first version). */
|
|
364
408
|
export type WorkingDocAuthor =
|
|
365
409
|
| { kind: 'human'; id: string }
|
|
366
410
|
| { kind: 'plugin'; id: string }
|
|
411
|
+
| { kind: 'agent'; id: string }
|
|
367
412
|
| { kind: 'system'; id: 'crew' };
|
|
368
413
|
|
|
369
414
|
/** One version of the working document, as crew attributed it. */
|
|
@@ -401,6 +446,9 @@ export interface WorkingDocSteer {
|
|
|
401
446
|
error: string | null;
|
|
402
447
|
supersededBy?: string | null;
|
|
403
448
|
renewals?: number;
|
|
449
|
+
/** (0.161.0, DES-VOICE) The person said the edit and confirmed it on screen: the thread says "You (by voice)".
|
|
450
|
+
* ABSENT on a typed edit (and on an older daemon). It grants nothing. */
|
|
451
|
+
input?: 'voice';
|
|
404
452
|
}
|
|
405
453
|
|
|
406
454
|
/** `GET /runs/:id/working-doc` (and the body of `POST /runs/:id/working-doc`). */
|
|
@@ -412,15 +460,23 @@ export interface WorkingDocView {
|
|
|
412
460
|
labels: Record<WorkingDocSectionId, string>;
|
|
413
461
|
trail: WorkingDocTrailEntry[];
|
|
414
462
|
steers: WorkingDocSteer[];
|
|
463
|
+
/** (0.151.0) `true` when crew itself writes the document's event-derived lines (Decisions answered, Open questions,
|
|
464
|
+
* Next) from the run's own log, as `plugin:wicked-phase-report@…`: a host plugin then writes none of its own and
|
|
465
|
+
* only renders and takes a person's edits. ABSENT on an older daemon — read as `false` (the plugin keeps writing). */
|
|
466
|
+
eventLines?: boolean;
|
|
415
467
|
}
|
|
416
468
|
|
|
417
469
|
/** `POST /runs/:id/working-doc/versions`. `author: 'operator'` only from a person; `author: 'plugin'` writes only the
|
|
418
|
-
* plugin's own
|
|
470
|
+
* plugin's own lines, under `decisions`, `questions` and `next` (never `goal`, `approach` or `constraints`: 403). A
|
|
471
|
+
* plugin's write never steers, in any section (`steer` is null). 409 `{head}` when the document moved since `base`. */
|
|
419
472
|
export interface ProposeWorkingDocRequest {
|
|
420
473
|
base: number;
|
|
421
474
|
sections: Partial<Record<WorkingDocSectionId, string>>;
|
|
422
475
|
author: 'operator' | 'plugin';
|
|
423
476
|
plugin?: { id: string; version: string };
|
|
477
|
+
/** (0.161.0, DES-VOICE) The person said this edit and confirmed it on screen. On `author: 'operator'` only (400
|
|
478
|
+
* otherwise); kept on the steer ({@link WorkingDocSteer.input}) and the `run.steered.doc` audit line. */
|
|
479
|
+
input?: 'voice';
|
|
424
480
|
}
|
|
425
481
|
|
|
426
482
|
export interface ProposeWorkingDocResponse {
|
|
@@ -776,7 +832,46 @@ export type PowerActivityEvent = {
|
|
|
776
832
|
subject: string | null;
|
|
777
833
|
};
|
|
778
834
|
|
|
835
|
+
/** `/ws` frame: a seat's tool call started or finished, live from its stream as it happens (bus
|
|
836
|
+
* `wicked.run.tool.started` / `wicked.run.tool.finished`). Sent for claude, codex (`exec --json` items) and pi
|
|
837
|
+
* (`--mode json` tool executions); at most 24 frames per 2 s and 4000 per attempt, and a call shown starting is
|
|
838
|
+
* always shown finishing. `target` is a repo-relative path, a search, or a command with secrets cut, at most 160
|
|
839
|
+
* characters. (0.151.0) `state: 'working'` (bus `wicked.run.tool.working`) is a quiet seat's heartbeat, any seat,
|
|
840
|
+
* copilot included: after 15 s with no frame, one per 15 s while it stays quiet, `id` `working-<attempt>` (update one
|
|
841
|
+
* row), `kind: 'working'`, `tool` the seat, `target` `last output N s ago`, `durationMs` that silence. */
|
|
842
|
+
export type ToolActivityEvent = {
|
|
843
|
+
type: 'toolActivity';
|
|
844
|
+
session: string;
|
|
845
|
+
ord: number;
|
|
846
|
+
attempt: number;
|
|
847
|
+
at: number;
|
|
848
|
+
id: string;
|
|
849
|
+
state: 'started' | 'finished' | 'working';
|
|
850
|
+
kind: 'read' | 'search' | 'run' | 'test' | 'edit' | 'write' | 'skill' | 'task' | 'other' | 'working';
|
|
851
|
+
tool: string;
|
|
852
|
+
target: string | null;
|
|
853
|
+
ok: boolean | null;
|
|
854
|
+
durationMs: number | null;
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
/** `/ws` frame: new working notes from the power orchestrator's stream (bus `wicked.run.notes.recorded`): its
|
|
858
|
+
* approach when stated or restated, and each new decision with its reason. Crew writes them into the run's working
|
|
859
|
+
* document as `agent:<seat>`; they never steer. */
|
|
860
|
+
export type PowerWorkingNotesEvent = {
|
|
861
|
+
type: 'powerWorkingNotes';
|
|
862
|
+
session: string;
|
|
863
|
+
ord: number;
|
|
864
|
+
attempt: number;
|
|
865
|
+
turn: number;
|
|
866
|
+
seat: string;
|
|
867
|
+
at: number;
|
|
868
|
+
approach: string | null;
|
|
869
|
+
decisions: Array<{ text: string; why: string | null }>;
|
|
870
|
+
};
|
|
871
|
+
|
|
779
872
|
export type PowerEvent =
|
|
873
|
+
| ToolActivityEvent
|
|
874
|
+
| PowerWorkingNotesEvent
|
|
780
875
|
| PowerActivityEvent
|
|
781
876
|
| PowerIntakePlannedEvent
|
|
782
877
|
| RigorRescoredEvent
|
|
@@ -796,6 +891,10 @@ export type RunBusType =
|
|
|
796
891
|
| 'wicked.run.handoff.stepped'
|
|
797
892
|
| 'wicked.run.power.toggled'
|
|
798
893
|
| 'wicked.run.activity.recorded'
|
|
894
|
+
| 'wicked.run.tool.started'
|
|
895
|
+
| 'wicked.run.tool.finished'
|
|
896
|
+
| 'wicked.run.tool.working'
|
|
897
|
+
| 'wicked.run.notes.recorded'
|
|
799
898
|
| 'wicked.run.unit.started'
|
|
800
899
|
| 'wicked.run.unit.finished'
|
|
801
900
|
| 'wicked.run.checks.evaluated'
|
|
@@ -2366,6 +2465,20 @@ export interface GateDecision {
|
|
|
2366
2465
|
* `POST /runs/:id/resume` or `/reassign`.
|
|
2367
2466
|
*/
|
|
2368
2467
|
ord?: number;
|
|
2468
|
+
/**
|
|
2469
|
+
* (api-types 0.156.0, DES-VOICE) The person answered by voice: studio matched the spoken words to this
|
|
2470
|
+
* answer, showed it on screen and the person confirmed it, then the usual undo window ran. Recorded on the
|
|
2471
|
+
* `gate.decided` audit line and {@link DecidedGate.input}; it grants nothing a typed answer does not.
|
|
2472
|
+
*/
|
|
2473
|
+
input?: 'voice';
|
|
2474
|
+
/**
|
|
2475
|
+
* (api-types 0.160.0, program DES-LEARN §3.1) On a steering-author propose gate: the drafted rule ids
|
|
2476
|
+
* (`SteeringDraftResponse.rules[].id`) the person keeps. Only those land; the rest are declined
|
|
2477
|
+
* (`SteeringLandingResult.declinedIds`, audited `governance.steering.declined`). Absent = every drafted
|
|
2478
|
+
* rule lands. With a plain approve only (400 otherwise); **409** `no_draft` on a gate with no readable
|
|
2479
|
+
* draft, **409** `draft_changed` when an id is not in the draft as it reads now (the gate stays open).
|
|
2480
|
+
*/
|
|
2481
|
+
keepRules?: string[];
|
|
2369
2482
|
}
|
|
2370
2483
|
|
|
2371
2484
|
/**
|
|
@@ -2441,6 +2554,8 @@ export interface CoreEvent {
|
|
|
2441
2554
|
seat?: string;
|
|
2442
2555
|
/** `elicitationCreated`: an ordered set of valid responses; `null` / absent = free-text. */
|
|
2443
2556
|
options?: string[] | null;
|
|
2557
|
+
/** `elicitationCreated` (api-types 0.158.0): a multi-select's bounds (`propType: "array"`). Absent otherwise. */
|
|
2558
|
+
multi?: ElicitationMulti;
|
|
2444
2559
|
/**
|
|
2445
2560
|
* `elicitationCreated` (C3; wicked-core-ts >= 0.7.35, api-types 0.83.0): the index into `options`
|
|
2446
2561
|
* of the option the PRODUCER of the options recommends (the field's JSON Schema `default`).
|
|
@@ -2465,6 +2580,13 @@ export interface CoreEvent {
|
|
|
2465
2580
|
/** `awaitingHuman{gateKind: 'consent'}` (core#820): why no write targets are listed (no dry run
|
|
2466
2581
|
* ran before the gate, or it printed no plan); the gate is then a plain approve / reject. */
|
|
2467
2582
|
writeTargetsMissing?: string;
|
|
2583
|
+
/**
|
|
2584
|
+
* `awaitingHuman{gateKind: 'repeat'}` (api-types 0.163.0, domain-graph-3): a loop step's ask —
|
|
2585
|
+
* its command's progress line ("Mapping wicked-crew · 3% → 23% · target 80% · page 21 · budget
|
|
2586
|
+
* reached …"). The ask's answers ride `choices` (`consent:<id>`…, `reject` = stop, the run ends
|
|
2587
|
+
* and what it did is kept), `choiceLabels` and `recommended`, as on a consent gate.
|
|
2588
|
+
*/
|
|
2589
|
+
repeatLine?: string;
|
|
2468
2590
|
/** PTY terminal frames (`terminalOpened`/`terminalOutput`/`terminalExited`): the terminal id. */
|
|
2469
2591
|
id?: string;
|
|
2470
2592
|
/**
|
|
@@ -2872,6 +2994,24 @@ export interface CliUsageEvent {
|
|
|
2872
2994
|
costUsd: number | null;
|
|
2873
2995
|
}
|
|
2874
2996
|
|
|
2997
|
+
/**
|
|
2998
|
+
* (0.155.0) `/ws` frame (and logged with the run): a working seat's running token TOTAL for one unit attempt, live from
|
|
2999
|
+
* its own stream (wicked-core: claude per assistant message, pi per `message_end`, codex per `turn.completed`). Fresh +
|
|
3000
|
+
* cache input, as {@link CliUsageEvent} counts it; sent when it changed, at most one per 3 s. `costUsd` only where the
|
|
3001
|
+
* seat's stream states one (pi), else `null`. The attempt's `cliUsage` at its end stays the record.
|
|
3002
|
+
*/
|
|
3003
|
+
export interface UsageProgressEvent {
|
|
3004
|
+
type: 'usageProgress';
|
|
3005
|
+
session: string;
|
|
3006
|
+
ord: number;
|
|
3007
|
+
attempt: number;
|
|
3008
|
+
/** Unix ms. */
|
|
3009
|
+
at: number;
|
|
3010
|
+
inputTokens: number;
|
|
3011
|
+
outputTokens: number;
|
|
3012
|
+
costUsd: number | null;
|
|
3013
|
+
}
|
|
3014
|
+
|
|
2875
3015
|
/** §3 B4 — the data files a unit's CLI touched. */
|
|
2876
3016
|
export interface DataUsedEvent {
|
|
2877
3017
|
type: 'dataUsed';
|
|
@@ -4039,6 +4179,23 @@ export interface WorkflowSelectedEvent {
|
|
|
4039
4179
|
unitCount: number;
|
|
4040
4180
|
}
|
|
4041
4181
|
|
|
4182
|
+
/**
|
|
4183
|
+
* (api-types 0.163.0, domain-graph-3) A loop step sent the run back for another pass: every unit
|
|
4184
|
+
* from `fromOrd` through `ord` was re-armed at a fresh attempt and the run goes on from `fromOrd`.
|
|
4185
|
+
* `pass` counts the passes the loop has sent back (1 after the first); `line` is the step's own
|
|
4186
|
+
* progress line ("Mapping wicked-crew · 3% → 12% → 19% · target 80% · page 4 · about 2 h left"),
|
|
4187
|
+
* possibly empty. One per loop rewind: a page that reaches the target, or stops at a budget ask
|
|
4188
|
+
* (whose `awaitingHuman.repeatLine` carries the line), emits none.
|
|
4189
|
+
*/
|
|
4190
|
+
export type StepRepeatedEvent = {
|
|
4191
|
+
type: 'stepRepeated';
|
|
4192
|
+
session: string;
|
|
4193
|
+
ord: number;
|
|
4194
|
+
fromOrd: number;
|
|
4195
|
+
pass: number;
|
|
4196
|
+
line: string;
|
|
4197
|
+
};
|
|
4198
|
+
|
|
4042
4199
|
/** P2 — a human approved a gate with an amendment text that was injected into the unit's description
|
|
4043
4200
|
* before re-dispatch. Fires after the amendment is persisted, before Resumed. Only emitted when
|
|
4044
4201
|
* the amendment text is non-empty. The canonical record for the HITL paper trail. */
|
|
@@ -4223,6 +4380,28 @@ export interface WorkerMessageInjectedEvent {
|
|
|
4223
4380
|
message: string;
|
|
4224
4381
|
/** `"all"` or the cli_key that was targeted. */
|
|
4225
4382
|
target: string;
|
|
4383
|
+
/** (0.161.0, DES-VOICE) Stamped by crew when the note was sent with {@link InjectMessageRequest.input} `voice`
|
|
4384
|
+
* (on `/ws` and `GET /runs/:id/events`; also on the `workerMessageQueued` frame). Crew remembers spoken notes in
|
|
4385
|
+
* memory, so one sent before a daemon restart reads as typed here; its `run.injected` audit line keeps it. */
|
|
4386
|
+
input?: 'voice';
|
|
4387
|
+
}
|
|
4388
|
+
|
|
4389
|
+
/** `POST /runs/:id/cancel` (0.161.0): the body is optional; a bodiless cancel is unchanged. */
|
|
4390
|
+
export interface CancelRunRequest {
|
|
4391
|
+
/** Why the person stopped it (≤ 2000 characters), said or typed: kept on the `run.cancelled` audit line. */
|
|
4392
|
+
reason?: string;
|
|
4393
|
+
/** (DES-VOICE) The person said the stop and confirmed it on screen. A person's only (403 otherwise). */
|
|
4394
|
+
input?: 'voice';
|
|
4395
|
+
}
|
|
4396
|
+
|
|
4397
|
+
/** `POST /runs/:id/inject`: an operator note into the run's active worker(s). */
|
|
4398
|
+
export interface InjectMessageRequest {
|
|
4399
|
+
message: string;
|
|
4400
|
+
/** `"all"` (the default) or a CLI key. */
|
|
4401
|
+
target?: string;
|
|
4402
|
+
/** (0.161.0, DES-VOICE) The person said this note and confirmed it on screen. A person's only (403 for a worker or
|
|
4403
|
+
* plugin bearer); kept on the `run.injected` audit line and stamped on the note's frames. Grants nothing. */
|
|
4404
|
+
input?: 'voice';
|
|
4226
4405
|
}
|
|
4227
4406
|
|
|
4228
4407
|
/** A unit was stopped and re-dispatched to a different CLI (or re-routed via council). */
|
|
@@ -4484,6 +4663,91 @@ export interface SteeringLandingResult {
|
|
|
4484
4663
|
alreadyLanded?: boolean;
|
|
4485
4664
|
/** Present iff `outcome: "failed"` — the loud, operator-readable reason. */
|
|
4486
4665
|
error?: string;
|
|
4666
|
+
/** (api-types 0.160.0) The drafted rules the approve's `keepRules` left out: never landed. */
|
|
4667
|
+
declinedIds?: string[];
|
|
4668
|
+
}
|
|
4669
|
+
|
|
4670
|
+
/**
|
|
4671
|
+
* `GET /governance/steering/author/:runId/draft` (api-types 0.160.0, program DES-LEARN §3.1): a
|
|
4672
|
+
* steering-author run's drafted rules, normalized exactly as the landing lands them. `ready` is true once
|
|
4673
|
+
* the propose step has run and the run waits at a gate; until then `rules` may be empty. 404 for an
|
|
4674
|
+
* unknown run or one that is not steering-author (`code: "not_steering_author"`).
|
|
4675
|
+
*/
|
|
4676
|
+
export interface SteeringDraftResponse {
|
|
4677
|
+
runId: string;
|
|
4678
|
+
ready: boolean;
|
|
4679
|
+
rules: ConformanceRule[];
|
|
4680
|
+
source?: SteeringProposalSource;
|
|
4681
|
+
}
|
|
4682
|
+
|
|
4683
|
+
// ── Personality (api-types 0.160.0, program DES-LEARN §3.3) ──────────────────────────────────────
|
|
4684
|
+
|
|
4685
|
+
/** 0 = the left word, 2 = the right word: length short..thorough, warmth plain..warm, pushback goes
|
|
4686
|
+
* along..challenges, initiative asks first..just starts. */
|
|
4687
|
+
export type PersonaDial = 0 | 1 | 2;
|
|
4688
|
+
export type PersonaHabit = 'says-unchecked' | 'tables' | 'cites' | 'names';
|
|
4689
|
+
|
|
4690
|
+
/** `PUT /persona`'s `persona`: how the orchestrator talks. Tone only: never read by a gate, review, QE or rule. */
|
|
4691
|
+
export interface PersonaInput {
|
|
4692
|
+
/** 1..40 characters. */
|
|
4693
|
+
name: string;
|
|
4694
|
+
/** `#rrggbb`. */
|
|
4695
|
+
colour: string;
|
|
4696
|
+
dials: { length: PersonaDial; warmth: PersonaDial; pushback: PersonaDial; initiative: PersonaDial };
|
|
4697
|
+
habits: PersonaHabit[];
|
|
4698
|
+
/** At most 500 characters, about tone. */
|
|
4699
|
+
notes?: string;
|
|
4700
|
+
}
|
|
4701
|
+
|
|
4702
|
+
export interface Persona extends PersonaInput {
|
|
4703
|
+
/** 1 on the first save of a scope, one more on each save. */
|
|
4704
|
+
version: number;
|
|
4705
|
+
/** Unix ms. */
|
|
4706
|
+
updatedAt: number;
|
|
4707
|
+
}
|
|
4708
|
+
|
|
4709
|
+
/** `user`, or `project:<id>` for one project's override. */
|
|
4710
|
+
export type PersonaScope = 'user' | `project:${string}`;
|
|
4711
|
+
|
|
4712
|
+
/** `GET /persona`: the person's own, every project override, and the voice block each adds to what a chat
|
|
4713
|
+
* seat is told (the project's override, else the person's, rides every chat's scope statement). */
|
|
4714
|
+
export interface PersonaResponse {
|
|
4715
|
+
user: Persona | null;
|
|
4716
|
+
projects: Record<string, Persona>;
|
|
4717
|
+
voice: { user: string | null; projects: Record<string, string> };
|
|
4718
|
+
}
|
|
4719
|
+
|
|
4720
|
+
/** `PUT /persona` body: a person only (403 otherwise); 404 for an unknown project. */
|
|
4721
|
+
export interface PersonaPutBody {
|
|
4722
|
+
scope: PersonaScope;
|
|
4723
|
+
persona: PersonaInput;
|
|
4724
|
+
}
|
|
4725
|
+
|
|
4726
|
+
export interface PersonaSaved {
|
|
4727
|
+
scope: PersonaScope;
|
|
4728
|
+
persona: Persona;
|
|
4729
|
+
voice: string;
|
|
4730
|
+
}
|
|
4731
|
+
|
|
4732
|
+
/** `DELETE /persona?scope=project:<id>`: removes a project's override (a person only). */
|
|
4733
|
+
export interface PersonaRemoved {
|
|
4734
|
+
removed: true;
|
|
4735
|
+
scope: PersonaScope;
|
|
4736
|
+
}
|
|
4737
|
+
|
|
4738
|
+
// ── First run (api-types 0.160.0, program DES-LEARN §4) ──────────────────────────────────────────
|
|
4739
|
+
|
|
4740
|
+
/** `GET /setup/known` (operator trust): what studio shows before it asks. A fact that cannot be read is
|
|
4741
|
+
* `null` or empty, never guessed. */
|
|
4742
|
+
export interface SetupKnown {
|
|
4743
|
+
/** The global git identity; null when neither name nor email is set. */
|
|
4744
|
+
git: { name: string | null; email: string | null } | null;
|
|
4745
|
+
/** Tracked source files by language across the registered repositories (`git ls-files`), at most 6. */
|
|
4746
|
+
languages: Array<{ name: string; files: number; share: number }>;
|
|
4747
|
+
filesCounted: number;
|
|
4748
|
+
/** Git checkouts one level under the home's code folders and the registered repositories' folders,
|
|
4749
|
+
* not registered yet (at most 24). `path` is absolute: register with `POST /repos {name, rootPath}`. */
|
|
4750
|
+
nearby: Array<{ name: string; path: string }>;
|
|
4487
4751
|
}
|
|
4488
4752
|
|
|
4489
4753
|
// ── Skills — the daemon-owned garden plugin root, published as immutable snapshots (api-types 0.28.0) ──
|
|
@@ -6227,6 +6491,7 @@ export interface RepoGraphResponse {
|
|
|
6227
6491
|
finding?: RepoFinding;
|
|
6228
6492
|
}
|
|
6229
6493
|
|
|
6494
|
+
/** One row of `GET /repos/:id/git-history` (`?limit=` 1..500, default 20; newest first). */
|
|
6230
6495
|
export interface GitCommit {
|
|
6231
6496
|
sha: string;
|
|
6232
6497
|
shortSha: string;
|
|
@@ -6279,6 +6544,29 @@ export interface SystemSettings {
|
|
|
6279
6544
|
* Exported as `WICKED_COUNCIL_SPAWN_STAGGER_MS`, read per council. Absent = the default.
|
|
6280
6545
|
*/
|
|
6281
6546
|
councilSpawnStaggerMs?: number;
|
|
6547
|
+
/**
|
|
6548
|
+
* (api-types 0.159.0, operator ruling 2026-10-31) The requirements graph's minimum coverage:
|
|
6549
|
+
* `minCoveragePct`, a whole percentage 1..100, default 80. A repository's requirements graph is
|
|
6550
|
+
* built, and shown labelled with its share, once REAL requirements (0.164.0: placeholders never
|
|
6551
|
+
* count) reach this share of its behaviour-bearing product code; below it the
|
|
6552
|
+
* `domain-extraction` run says "N% real requirements, minimum M%" and keeps the mapping for the
|
|
6553
|
+
* next run. The daemon exports it as
|
|
6554
|
+
* `WICKED_REQUIREMENTS_MIN_COVERAGE_PCT` at boot and on every change. Absent = the default.
|
|
6555
|
+
*/
|
|
6556
|
+
requirementsGraph?: {
|
|
6557
|
+
minCoveragePct?: number;
|
|
6558
|
+
/**
|
|
6559
|
+
* (api-types 0.163.0, domain-graph-3) A domain-extraction run maps page after page until the
|
|
6560
|
+
* target; its budget per grant — `maxPages` (1..200, default 20) or `maxMinutes` (1..1440,
|
|
6561
|
+
* default 240), whichever is spent first — ends in an ask: map more, lower the target for the
|
|
6562
|
+
* repository, or stop. `pageSize` (50..2000, default 500) is how many behaviours one page
|
|
6563
|
+
* maps. Exported as `WICKED_DOMAIN_MAX_PAGES` / `WICKED_DOMAIN_MAX_MINUTES` /
|
|
6564
|
+
* `WICKED_DOMAIN_PAGE_SIZE`. Absent = the defaults.
|
|
6565
|
+
*/
|
|
6566
|
+
maxPages?: number;
|
|
6567
|
+
maxMinutes?: number;
|
|
6568
|
+
pageSize?: number;
|
|
6569
|
+
};
|
|
6282
6570
|
/*
|
|
6283
6571
|
* There is NO skills setting (skills keystone, api-types 0.28.0). The daemon-owned skills root is
|
|
6284
6572
|
* `<state home>/skills` — the directory holding `manifest.json`, `baseline/<hash>/`, `effective/`,
|
|
@@ -6472,6 +6760,74 @@ export interface SettingsResponse {
|
|
|
6472
6760
|
}
|
|
6473
6761
|
|
|
6474
6762
|
// ── Requirements management (server-side search + overrides; crew api/requirements.ts) ──
|
|
6763
|
+
/**
|
|
6764
|
+
* (0.159.0, operator ruling 2026-10-31 "validation by duplication") How many INDEPENDENT sources in
|
|
6765
|
+
* the repository support a requirement beyond the extractor's own statement, as `wicked-core
|
|
6766
|
+
* domain-graph` computed it: distinct callers (`callSites`), tests, docs that name it, and extractor
|
|
6767
|
+
* seats beyond the first. `validated` at 2 or more; otherwise `unconfirmed`, and `why` says what is
|
|
6768
|
+
* missing — show `why.text` on the item. `why.code` is one of `unindexed_file` (a file the code index
|
|
6769
|
+
* skipped names it, so its callers there are not counted), `dead_code`, `config_only`,
|
|
6770
|
+
* `single_caller`, `test_only`, `doc_only`, `extractors_only`.
|
|
6771
|
+
*/
|
|
6772
|
+
export interface RequirementCorroboration {
|
|
6773
|
+
status: 'validated' | 'unconfirmed';
|
|
6774
|
+
sources: number;
|
|
6775
|
+
callSites: number;
|
|
6776
|
+
tests: number;
|
|
6777
|
+
docs: number;
|
|
6778
|
+
extraExtractors: number;
|
|
6779
|
+
why?: { code: string; text: string };
|
|
6780
|
+
}
|
|
6781
|
+
|
|
6782
|
+
/**
|
|
6783
|
+
* (0.164.0, operator decision 2026-11-01, wicked-core#1233) How much of a repository's product code
|
|
6784
|
+
* is REAL requirements, and the minimum the graph is held to (`SystemSettings.requirementsGraph
|
|
6785
|
+
* .minCoveragePct`): label it "23% real requirements · 4397 placeholders · minimum 80%".
|
|
6786
|
+
*
|
|
6787
|
+
* - `realPct` is the one number the minimum is checked against: `floor(real * 100 /
|
|
6788
|
+
* behaviorBearing)`, floored so it never reads above the minimum it was compared to; 100 when
|
|
6789
|
+
* `behaviorBearing` is 0 (nothing in product code to map). `real + placeholders + unmapped ===
|
|
6790
|
+
* behaviorBearing`; a label that breaks either is not sent.
|
|
6791
|
+
* - `real`: behaviours resolved to a stated, sourced business rule.
|
|
6792
|
+
* - `placeholders`: behaviours carrying only a risk-flagged placeholder (an empty statement, a rule
|
|
6793
|
+
* under the confidence threshold, one written unconfirmed). Shown in the graph as unconfirmed,
|
|
6794
|
+
* NEVER counted toward the minimum.
|
|
6795
|
+
* - `unmapped`: behaviours with nothing recorded yet.
|
|
6796
|
+
* - `behaviorBearing`: the denominator, product code only. `notProduct` counts the behaviour-kind
|
|
6797
|
+
* nodes left out because their file is a test, data, manifest or document file.
|
|
6798
|
+
*
|
|
6799
|
+
* Replaces 0.159.0's `mappedPct` / `mapped` / `resolved`, which counted placeholders as mapped (a
|
|
6800
|
+
* repository with 3 real requirements and 117 placeholders read "100% mapped").
|
|
6801
|
+
*/
|
|
6802
|
+
export interface RequirementsCoverage {
|
|
6803
|
+
realPct: number;
|
|
6804
|
+
minPct: number;
|
|
6805
|
+
behaviorBearing: number;
|
|
6806
|
+
real: number;
|
|
6807
|
+
placeholders: number;
|
|
6808
|
+
unmapped: number;
|
|
6809
|
+
notProduct: number;
|
|
6810
|
+
}
|
|
6811
|
+
|
|
6812
|
+
/**
|
|
6813
|
+
* (0.165.0) The graph a requirements page lists, as it was built. When `behind`, the header (`coverage`, the store
|
|
6814
|
+
* now) does not count what the list holds: say so. When this `coverage.real` is below the header's: "2,202 real
|
|
6815
|
+
* requirements mapped since the last graph build; build the graph to list them". With `coverage` null: "built
|
|
6816
|
+
* before real requirements were counted; build the graph to list the N real requirements mapped now". Otherwise
|
|
6817
|
+
* (only another count moved, or `real` fell): "the repository changed since this graph was built".
|
|
6818
|
+
*/
|
|
6819
|
+
export interface RequirementsGraphBuild {
|
|
6820
|
+
/** The build's generation in the store (1 = the first build; 0 = a graph persisted before the engine kept a
|
|
6821
|
+
* build record). */
|
|
6822
|
+
generation: number;
|
|
6823
|
+
/** The label the build persisted; `null` when it carried none or an older engine's `mapped_pct` label. */
|
|
6824
|
+
coverage: RequirementsCoverage | null;
|
|
6825
|
+
/** True when any count of the build's label differs from the page's `coverage` (or the label is null), or
|
|
6826
|
+
* (0.167.0) when the engine judged every listed row and the counted rows' verdicts are not the header's real and
|
|
6827
|
+
* placeholders. False says the counts agree, not that every statement is unchanged. */
|
|
6828
|
+
behind: boolean;
|
|
6829
|
+
}
|
|
6830
|
+
|
|
6475
6831
|
export interface RequirementSummary {
|
|
6476
6832
|
key: string;
|
|
6477
6833
|
domain: string;
|
|
@@ -6483,6 +6839,20 @@ export interface RequirementSummary {
|
|
|
6483
6839
|
risk: boolean;
|
|
6484
6840
|
riskSource: 'operator' | 'data' | null;
|
|
6485
6841
|
edited: boolean;
|
|
6842
|
+
/** (0.159.0) Validated or unconfirmed (with why). `null` on a graph built before the field;
|
|
6843
|
+
* ABSENT from an older daemon. */
|
|
6844
|
+
corroboration?: RequirementCorroboration | null;
|
|
6845
|
+
/** (0.166.0) The engine would not count it a real requirement (a validated requirement, or a business rule at or
|
|
6846
|
+
* above the resolve threshold, 0.75): a placeholder, unconfirmed whatever its corroboration says. (0.167.0) The
|
|
6847
|
+
* engine's own verdict when it gives one, else read off the document. ABSENT from an older daemon. */
|
|
6848
|
+
placeholder?: boolean;
|
|
6849
|
+
/** (0.167.0) The coverage share does not count this row, and why: its unit is not a behaviour (`structural`, a
|
|
6850
|
+
* TypeScript shape or signature), is outside product code (`not_product`), or is no longer indexed (`unindexed`).
|
|
6851
|
+
* Such a row is neither a real requirement nor a placeholder of the header's (its `placeholder` says only whether
|
|
6852
|
+
* a rule was stated there), sorts after them, and carries
|
|
6853
|
+
* `corroboration: null` (a type has no callers; "dead code" would be wrong). `null` when it counts or the engine
|
|
6854
|
+
* does not say; ABSENT from an older daemon. */
|
|
6855
|
+
uncounted?: 'structural' | 'not_product' | 'unindexed' | null;
|
|
6486
6856
|
}
|
|
6487
6857
|
|
|
6488
6858
|
export interface RequirementDetail extends RequirementSummary {
|
|
@@ -6508,12 +6878,55 @@ export interface RequirementsPage {
|
|
|
6508
6878
|
source: 'store' | 'artifact';
|
|
6509
6879
|
/**
|
|
6510
6880
|
* Keys in `requirements_overrides.json` that matched NO requirement in the corpus. Operator
|
|
6511
|
-
* edits are keyed by
|
|
6512
|
-
*
|
|
6513
|
-
*
|
|
6514
|
-
*
|
|
6881
|
+
* edits are keyed by `domain::reqId` whatever the source (older daemons serving `'store'` keyed
|
|
6882
|
+
* them by SymbolId). The engine keeps a requirement's id across builds, so a key stops matching
|
|
6883
|
+
* when its requirement is retired or its domain regrouped. Non-zero means edits exist that no
|
|
6884
|
+
* row is showing — re-apply or delete the stale keys.
|
|
6515
6885
|
*/
|
|
6516
6886
|
orphanedOverrides?: number;
|
|
6887
|
+
/** (0.159.0; real requirements since 0.164.0) The graph's coverage label; `null` when absent, an
|
|
6888
|
+
* older engine's `mapped_pct` label, or one its counts do not support; ABSENT from an older
|
|
6889
|
+
* daemon. */
|
|
6890
|
+
coverage?: RequirementsCoverage | null;
|
|
6891
|
+
/**
|
|
6892
|
+
* (0.165.0) Which build the rows are. The list is the last graph BUILD; `coverage` counts the store NOW,
|
|
6893
|
+
* which moves on when a run maps more without building (stopped at its repeat ask, or below the minimum,
|
|
6894
|
+
* where the build refuses). `null` when the engine does not say; ABSENT from an older daemon.
|
|
6895
|
+
*/
|
|
6896
|
+
graphBuild?: RequirementsGraphBuild | null;
|
|
6897
|
+
/** (0.159.0) How many requirements of the whole corpus are validated / unconfirmed. (0.167.0) Rows the share does
|
|
6898
|
+
* not count are in neither. */
|
|
6899
|
+
corroboration?: { validated: number; unconfirmed: number };
|
|
6900
|
+
/**
|
|
6901
|
+
* (0.167.0) Rows of the whole corpus the coverage share does not count (items with `uncounted`), split stated /
|
|
6902
|
+
* placeholder: why the list holds more rows than the header. When this is not `null` and `graphBuild.behind` is
|
|
6903
|
+
* false, the rows that are neither placeholders nor uncounted number exactly `coverage.real`. `null` when the engine
|
|
6904
|
+
* did not judge every row (an older engine, a build before it recorded each row's unit, a malformed verdict): those
|
|
6905
|
+
* rows are read off the document, and there is no such claim. ABSENT from an older daemon.
|
|
6906
|
+
*/
|
|
6907
|
+
uncounted?: { stated: number; placeholders: number } | null;
|
|
6908
|
+
/** (0.167.0) How many rows of the whole corpus are in each category, so a client can leave out an empty filter.
|
|
6909
|
+
* ABSENT from an older daemon. */
|
|
6910
|
+
categories?: { functional: number; configData: number };
|
|
6911
|
+
}
|
|
6912
|
+
|
|
6913
|
+
/**
|
|
6914
|
+
* `GET /repos/:id/requirements` 404 when the repository's `requirements_graph.json` has not been
|
|
6915
|
+
* generated (0.154.0). A state, not a refusal: `code` is the discriminator a client matches on, and
|
|
6916
|
+
* `workflow` names the preset that generates the graph (its last step runs `wicked-core domain-graph`).
|
|
6917
|
+
* Any other 404 on the route (an unknown repo) carries no `code`.
|
|
6918
|
+
*/
|
|
6919
|
+
export interface RequirementsNotGenerated {
|
|
6920
|
+
error: string;
|
|
6921
|
+
code: 'notGenerated';
|
|
6922
|
+
workflow: string;
|
|
6923
|
+
/**
|
|
6924
|
+
* (api-types 0.163.0, domain-graph-3; real requirements since 0.164.0) How far the repository
|
|
6925
|
+
* is, against its target ("23% real requirements · 4397 placeholders · target 80%"): present
|
|
6926
|
+
* when the repository has a store to count.
|
|
6927
|
+
* `minPct` is the target in force (the repository's own when lowered, else the daemon's).
|
|
6928
|
+
*/
|
|
6929
|
+
coverage?: RequirementsCoverage;
|
|
6517
6930
|
}
|
|
6518
6931
|
|
|
6519
6932
|
export interface RequirementPatch {
|
|
@@ -6571,14 +6984,130 @@ export interface ElicitationInfo {
|
|
|
6571
6984
|
ord?: number;
|
|
6572
6985
|
attempt?: number;
|
|
6573
6986
|
seat?: string;
|
|
6987
|
+
/**
|
|
6988
|
+
* (api-types 0.158.0, guided asks) The person may pick SEVERAL of `options`: at least `min`, at most `max`
|
|
6989
|
+
* (both always set, `1 <= min <= max <= options.length`). Answer it with `content: {values}`; the engine records
|
|
6990
|
+
* the picks as a JSON array in `options` order. ABSENT on a single-choice or free-text question and on an older
|
|
6991
|
+
* daemon.
|
|
6992
|
+
*/
|
|
6993
|
+
multi?: ElicitationMulti;
|
|
6574
6994
|
receivedAt: string;
|
|
6575
6995
|
}
|
|
6576
6996
|
|
|
6577
|
-
/**
|
|
6997
|
+
/** (api-types 0.158.0) How many of a multi-select elicitation's options an answer picks. */
|
|
6998
|
+
export interface ElicitationMulti {
|
|
6999
|
+
min: number;
|
|
7000
|
+
max: number;
|
|
7001
|
+
}
|
|
7002
|
+
|
|
7003
|
+
/**
|
|
7004
|
+
* `POST /runs/:id/elicitation` body. `content` is required for accept, absent otherwise: `{response}` answers a
|
|
7005
|
+
* free-text or single-choice question (one of `options`); `{values}` (api-types 0.158.0) answers a multi-select one
|
|
7006
|
+
* ({@link ElicitationInfo.multi}): distinct entries of `options`, `min..=max` of them. Crew answers 400 to `values` on
|
|
7007
|
+
* a question that is not multi-select, and to `response` on one that is.
|
|
7008
|
+
*/
|
|
6578
7009
|
export interface ElicitationResponse {
|
|
6579
7010
|
elicitationId: string;
|
|
6580
7011
|
action: 'accept' | 'decline' | 'cancel';
|
|
6581
|
-
content?: { response: string };
|
|
7012
|
+
content?: { response: string } | { values: string[] };
|
|
7013
|
+
}
|
|
7014
|
+
|
|
7015
|
+
// ── Guided asks (api-types 0.158.0; design DES-GUIDED-CHAT) ─────────────────────────────────────────────────────
|
|
7016
|
+
//
|
|
7017
|
+
// ONE typed shape for every question a person answers inline: an engine gate, a seat's or MCP server's elicitation,
|
|
7018
|
+
// a power-mode pause, a plugin's proposal, a studio setup step. It is a RENDERING contract: the wire shapes that
|
|
7019
|
+
// exist stay as they are and map onto it (GateInfo.choices + recommended + gateKind → `choose`; ElicitationInfo
|
|
7020
|
+
// options/multi → `choose` / `pick` / `text`), and every answer still goes through its host's own route
|
|
7021
|
+
// (`POST /runs/:id/gate` with a GateDecision, `POST /runs/:id/elicitation`, …). Governance is the host's: an ask
|
|
7022
|
+
// never widens who may answer, and a gate's ask is always `answeredBy: 'person'`.
|
|
7023
|
+
|
|
7024
|
+
/** The six ways a person answers. */
|
|
7025
|
+
export type AskKind =
|
|
7026
|
+
/** Yes / no (two options; picking one is the answer). */
|
|
7027
|
+
| 'confirm'
|
|
7028
|
+
/** Choose one of 2..n options. */
|
|
7029
|
+
| 'choose'
|
|
7030
|
+
/** Pick several (`multi` bounds). */
|
|
7031
|
+
| 'pick'
|
|
7032
|
+
/** Short text. */
|
|
7033
|
+
| 'text'
|
|
7034
|
+
/** A point on a scale (named steps, or a number range). */
|
|
7035
|
+
| 'scale'
|
|
7036
|
+
/** Confirm, with a required reason (a danger move: stop, reject, skip QE, override). */
|
|
7037
|
+
| 'confirm_reason';
|
|
7038
|
+
|
|
7039
|
+
/** Which route answers the ask. */
|
|
7040
|
+
export type AskHost = 'gate' | 'elicitation' | 'chat' | 'learn' | 'plugin' | 'power';
|
|
7041
|
+
|
|
7042
|
+
/** One option of a `confirm` / `choose` / `pick` / `confirm_reason` ask. */
|
|
7043
|
+
export interface AskOption {
|
|
7044
|
+
/** Stable within the ask. */
|
|
7045
|
+
id: string;
|
|
7046
|
+
/** What the person reads (and the voice vocabulary). */
|
|
7047
|
+
label: string;
|
|
7048
|
+
/** One line under the label. */
|
|
7049
|
+
sub?: string;
|
|
7050
|
+
/** What happens if this option is taken, shown while it is hovered or selected ("If you choose this: …"). */
|
|
7051
|
+
consequence?: string;
|
|
7052
|
+
/** The wire answer: a gate action token, an elicitation option, a pause decision. */
|
|
7053
|
+
token: string;
|
|
7054
|
+
tone?: 'primary' | 'neutral' | 'danger';
|
|
7055
|
+
/** The engine's (or producer's) recommendation: marked, and preselected unless the host says otherwise. */
|
|
7056
|
+
recommended?: boolean;
|
|
7057
|
+
/** Taking it asks for a reason first (kept with the record). */
|
|
7058
|
+
needsReason?: boolean;
|
|
7059
|
+
/** Shown but not choosable; the string says why ("Frozen: nothing merges there"). */
|
|
7060
|
+
disabled?: string;
|
|
7061
|
+
/** A small tag ("default", "current release"). */
|
|
7062
|
+
meta?: string;
|
|
7063
|
+
}
|
|
7064
|
+
|
|
7065
|
+
/** A named-step scale, or a number range. */
|
|
7066
|
+
export type AskScale =
|
|
7067
|
+
| { steps: string[]; consequences?: string[] }
|
|
7068
|
+
| { min: number; max: number; step: number; labels: [string, string] };
|
|
7069
|
+
|
|
7070
|
+
export interface Ask {
|
|
7071
|
+
/** Gate: `<runId>:<ord>`; elicitation: its `elicitationId`; otherwise the host's own id. */
|
|
7072
|
+
id: string;
|
|
7073
|
+
host: AskHost;
|
|
7074
|
+
/** Who asks, in words ("Codex asks", "The engine asks"). */
|
|
7075
|
+
from: { kind: 'engine' | 'seat' | 'plugin' | 'studio'; id: string; label: string };
|
|
7076
|
+
/** One sentence, a question. */
|
|
7077
|
+
prompt: string;
|
|
7078
|
+
/** One line under the question. */
|
|
7079
|
+
detail?: string;
|
|
7080
|
+
kind: AskKind;
|
|
7081
|
+
options?: AskOption[];
|
|
7082
|
+
/** `pick`: how many (defaults: 1 and every option). */
|
|
7083
|
+
multi?: { min?: number; max?: number };
|
|
7084
|
+
/** Preselected: an option id (`choose` / `confirm`), option ids (`pick`), a step index or value (`scale`). */
|
|
7085
|
+
default?: string | string[] | number;
|
|
7086
|
+
scale?: AskScale;
|
|
7087
|
+
text?: { placeholder?: string; maxChars?: number; optional?: boolean };
|
|
7088
|
+
/** A follow-up shown in the same card once the first part is answered (pick the steps, then say what). */
|
|
7089
|
+
then?: Ask;
|
|
7090
|
+
/** A gate is always `'person'`. */
|
|
7091
|
+
answeredBy: 'person' | 'any';
|
|
7092
|
+
/** The answer waits this long, with Undo, before it is sent (a gate: 10 000). */
|
|
7093
|
+
undoMs?: number;
|
|
7094
|
+
/** The answered line: `{label}`, `{labels}` and `{text}` are filled ("You chose: {label}"). */
|
|
7095
|
+
record: string;
|
|
7096
|
+
}
|
|
7097
|
+
|
|
7098
|
+
/** What a person answered: the host turns it into its own wire body. */
|
|
7099
|
+
export interface AskAnswer {
|
|
7100
|
+
askId: string;
|
|
7101
|
+
/** `confirm` / `choose` / `confirm_reason`: the option taken. */
|
|
7102
|
+
option?: string;
|
|
7103
|
+
/** `pick`: the options picked, in the ask's order. */
|
|
7104
|
+
options?: string[];
|
|
7105
|
+
/** `text`, and a `then` text. */
|
|
7106
|
+
text?: string;
|
|
7107
|
+
/** `scale`: the step index or value. */
|
|
7108
|
+
value?: number;
|
|
7109
|
+
/** A `needsReason` option's reason. */
|
|
7110
|
+
reason?: string;
|
|
6582
7111
|
}
|
|
6583
7112
|
|
|
6584
7113
|
// ── Inventory claims (wicked-crew#721) — whether each enumerating step's list is complete ──
|
|
@@ -6611,6 +7140,116 @@ export interface RunInventoryUnit {
|
|
|
6611
7140
|
claims: InventoryClaim[];
|
|
6612
7141
|
}
|
|
6613
7142
|
|
|
7143
|
+
/**
|
|
7144
|
+
* `GET /runs/:id/learnings` — what a run proposed to the approve queue (run learnings, crew src/learnings).
|
|
7145
|
+
* Every learning is a `memory` proposal attributed to the run (`provenance.run_id`); nothing is used until a
|
|
7146
|
+
* person approves it on the Memory page. `distilling` is true while the run's distil seat (one cheap seat
|
|
7147
|
+
* that did not build the run) is still reading its evidence.
|
|
7148
|
+
*/
|
|
7149
|
+
export interface RunLearningsResponse {
|
|
7150
|
+
runId: string;
|
|
7151
|
+
proposed: number;
|
|
7152
|
+
pending: number;
|
|
7153
|
+
approved: number;
|
|
7154
|
+
rejected: number;
|
|
7155
|
+
distilling: boolean;
|
|
7156
|
+
items: Array<{
|
|
7157
|
+
/** The proposal id (approve or reject it through `/proposals/:id/*`). */
|
|
7158
|
+
id: string;
|
|
7159
|
+
state: string;
|
|
7160
|
+
/** `gotcha` | `decision` | `pattern` | `steering`, as filed. */
|
|
7161
|
+
capture: string | null;
|
|
7162
|
+
content: string;
|
|
7163
|
+
/** Who worded it: `crew` (from the run's record) or the distil seat. */
|
|
7164
|
+
agent: string | null;
|
|
7165
|
+
/** Unix seconds. */
|
|
7166
|
+
createdAt: number | null;
|
|
7167
|
+
}>;
|
|
7168
|
+
}
|
|
7169
|
+
|
|
7170
|
+
/** (0.155.0) The in-flight check's verdict on a working step. */
|
|
7171
|
+
export type UnitInspectVerdict = 'progressing' | 'looping' | 'stuck' | 'wasteful';
|
|
7172
|
+
/** (0.155.0) The one action a check recommends; the person chooses, nothing is done for them. */
|
|
7173
|
+
export type UnitInspectAction = 'let_run' | 'steer' | 'stop';
|
|
7174
|
+
|
|
7175
|
+
/** (0.155.0) Crew's own deterministic reading of a working step's newest attempt (crew src/inspect/reading.ts). */
|
|
7176
|
+
export interface UnitInspectReading {
|
|
7177
|
+
ord: number;
|
|
7178
|
+
attempt: number;
|
|
7179
|
+
startedAt: number | null;
|
|
7180
|
+
elapsedMs: number | null;
|
|
7181
|
+
calls: number;
|
|
7182
|
+
openCalls: Array<{ tool: string; target: string | null; forMs: number }>;
|
|
7183
|
+
byKind: Record<string, number>;
|
|
7184
|
+
edits: Array<{ path: string; count: number }>;
|
|
7185
|
+
said: { deltas: number; chars: number; lastAt: number | null; newest: string | null };
|
|
7186
|
+
usage: { inputTokens: number; outputTokens: number; costUsd: number | null; source: 'live' | 'final' } | null;
|
|
7187
|
+
lastSignAt: number | null;
|
|
7188
|
+
verdict: UnitInspectVerdict;
|
|
7189
|
+
evidence: string[];
|
|
7190
|
+
doing: string | null;
|
|
7191
|
+
action: UnitInspectAction;
|
|
7192
|
+
note: string | null;
|
|
7193
|
+
}
|
|
7194
|
+
|
|
7195
|
+
/**
|
|
7196
|
+
* (0.155.0) One "Is this going well?" check on a working step (`POST /runs/:id/units/:ord/inspect`). A seat that is not
|
|
7197
|
+
* the step's own reads the step's record (one read-only `inspect-unit` run, bounded by time and budget) and answers;
|
|
7198
|
+
* when none can, or it fails, times out or reaches its budget, `source: 'crew'` and `why` says so and the answer is
|
|
7199
|
+
* crew's own reading. It never steers, stops or edits the run it looks at.
|
|
7200
|
+
*/
|
|
7201
|
+
export interface UnitInspection {
|
|
7202
|
+
id: string;
|
|
7203
|
+
runId: string;
|
|
7204
|
+
ord: number;
|
|
7205
|
+
attempt: number;
|
|
7206
|
+
state: 'checking' | 'done';
|
|
7207
|
+
/** The actor id who asked. */
|
|
7208
|
+
requestedBy: string;
|
|
7209
|
+
/** Unix ms. */
|
|
7210
|
+
requestedAt: number;
|
|
7211
|
+
finishedAt: number | null;
|
|
7212
|
+
/** The step's own seat. */
|
|
7213
|
+
workerSeat: string | null;
|
|
7214
|
+
/** The seat that checked (never the step's own); null when none could. */
|
|
7215
|
+
seat: string | null;
|
|
7216
|
+
/** The check's own run (workflow `inspect-unit`); null when none was launched. */
|
|
7217
|
+
checkRunId: string | null;
|
|
7218
|
+
source: 'seat' | 'crew' | null;
|
|
7219
|
+
why: string | null;
|
|
7220
|
+
verdict: UnitInspectVerdict | null;
|
|
7221
|
+
/** What the step is doing, one sentence. */
|
|
7222
|
+
doing: string | null;
|
|
7223
|
+
/** Roughly how far along it is (the seat's estimate), one sentence. */
|
|
7224
|
+
progress: string | null;
|
|
7225
|
+
evidence: string[];
|
|
7226
|
+
action: UnitInspectAction | null;
|
|
7227
|
+
/** For `action: 'steer'`: the note it suggests sending the step's seat (the person may edit it before sending). */
|
|
7228
|
+
note: string | null;
|
|
7229
|
+
reading: UnitInspectReading;
|
|
7230
|
+
/** What the check itself spent, when its seat reported it. */
|
|
7231
|
+
cost: { inputTokens: number; outputTokens: number; costUsd: number | null } | null;
|
|
7232
|
+
}
|
|
7233
|
+
|
|
7234
|
+
/** (0.155.0) `POST /runs/:id/units/:ord/inspect` → 202. 403 for anyone but a human operator; 409 `not_working` when the
|
|
7235
|
+
* step is not working now. A check already running on the step is answered as it is. */
|
|
7236
|
+
export interface UnitInspectionResponse {
|
|
7237
|
+
inspection: UnitInspection;
|
|
7238
|
+
}
|
|
7239
|
+
|
|
7240
|
+
/** (0.155.0) `GET /runs/:id/units/:ord/inspections`: the step's checks, newest first. */
|
|
7241
|
+
export interface UnitInspectionsResponse {
|
|
7242
|
+
inspections: UnitInspection[];
|
|
7243
|
+
}
|
|
7244
|
+
|
|
7245
|
+
/** (0.155.0) `/ws` frame: a check started, its budget moved, or it answered. */
|
|
7246
|
+
export interface UnitInspectionEvent {
|
|
7247
|
+
type: 'unitInspection';
|
|
7248
|
+
session: string;
|
|
7249
|
+
ord: number;
|
|
7250
|
+
inspection: UnitInspection;
|
|
7251
|
+
}
|
|
7252
|
+
|
|
6614
7253
|
/**
|
|
6615
7254
|
* `GET /runs/:id/inventory` (404 for an unknown run). `complete` is true only when at least one
|
|
6616
7255
|
* unit claimed an inventory, every claim is `full` and every finished unit's output was readable;
|
|
@@ -6693,6 +7332,115 @@ export interface PresetResponse {
|
|
|
6693
7332
|
preset: Preset;
|
|
6694
7333
|
}
|
|
6695
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
|
+
|
|
6696
7444
|
// ── Projects (DES-PROJECT-001) — the experience-plane keystone ─────────────────
|
|
6697
7445
|
|
|
6698
7446
|
/** Project lifecycle: `active ⇄ archived`, no hard delete (ADR §1.3). */
|
|
@@ -7303,6 +8051,18 @@ export interface ChatOpenBody {
|
|
|
7303
8051
|
* engine without it is a 409. Send it only when `GET /health.capabilities.chatWorkflows` names it.
|
|
7304
8052
|
*/
|
|
7305
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;
|
|
7306
8066
|
}
|
|
7307
8067
|
|
|
7308
8068
|
/** The scope a `POST /chats` caller may name (api-types 0.39.0, studio#323 R4). */
|
|
@@ -7355,7 +8115,8 @@ export interface ChatScope {
|
|
|
7355
8115
|
* 0.35.0, F-2R2-008) names the UI action that would change a `bound: false` outcome, when one
|
|
7356
8116
|
* would: `projects.graph.refresh` = build the project graph from the project page. */
|
|
7357
8117
|
graph: { bound: boolean; reason: string; repoLabel?: string; action?: ProjectGraphAction };
|
|
7358
|
-
/** `crew.repo` members of the project whose registry record is gone — named, not readable.
|
|
8118
|
+
/** `crew.repo` members of the project whose registry record is gone — named, not readable. (0.155.0) Also
|
|
8119
|
+
* any repo in scope (project or `everything`) whose folder is missing (`repo_folder_missing`). */
|
|
7359
8120
|
dangling: string[];
|
|
7360
8121
|
}
|
|
7361
8122
|
|
|
@@ -7602,7 +8363,17 @@ export interface ChatUsage {
|
|
|
7602
8363
|
*/
|
|
7603
8364
|
export type ChatTranscriptRecord =
|
|
7604
8365
|
/** `attachments` (api-types 0.137.0): the files the message carried, ABSENT when none. */
|
|
7605
|
-
| {
|
|
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
|
+
}
|
|
7606
8377
|
| { at: number; turnId: string; kind: 'seat'; cliKey: string; text: string; ok: boolean; usage: ChatUsage | null }
|
|
7607
8378
|
/**
|
|
7608
8379
|
* The citation verdicts of the `seat` record with the same `turnId` + `cliKey` (api-types 0.68.0,
|
|
@@ -7635,7 +8406,218 @@ export type ChatTranscriptRecord =
|
|
|
7635
8406
|
* 0.85.0, DC-S7): the rules remembered since they last heard from crew. Disclosed here so the
|
|
7636
8407
|
* operator sees exactly what crew added; the `user` record keeps the operator's own words.
|
|
7637
8408
|
*/
|
|
7638
|
-
| { 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
|
+
};
|
|
7639
8621
|
|
|
7640
8622
|
// ── System chat: history, close, attachments (api-types 0.137.0, DES-SYSTEM-CHAT "Crew") ────────
|
|
7641
8623
|
//
|
|
@@ -7762,6 +8744,84 @@ export interface ChatMessageBody {
|
|
|
7762
8744
|
* file: a path it can open (images as images where the CLI reads them) plus, for text and pdf,
|
|
7763
8745
|
* the extracted text. Send only when `GET /health.capabilities.chatAttachments === true`. */
|
|
7764
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;
|
|
7765
8825
|
}
|
|
7766
8826
|
|
|
7767
8827
|
/** `GET /chats/:id` → 200. */
|
|
@@ -8436,8 +9496,26 @@ export interface DiagnosticsResponse {
|
|
|
8436
9496
|
* — see `DiagnosticsVault`. `null` on a route set booted without an engine adapter; ABSENT on an
|
|
8437
9497
|
* older daemon. */
|
|
8438
9498
|
vault?: DiagnosticsVault | null;
|
|
9499
|
+
/** (crew#1147) The engine's repo-checks floor cache usage (`Core.floorCacheUsage`): `path` is shown as
|
|
9500
|
+
* `~/...`, never a home path; `repos` is largest first. The engine walks the cache, so the daemon
|
|
9501
|
+
* caches this answer for 60 s. `{ error }` when the engine has no worker home; `null` on an addon
|
|
9502
|
+
* without the static; ABSENT on an older daemon. */
|
|
9503
|
+
floorCache?: DiagnosticsFloorCache | null;
|
|
8439
9504
|
}
|
|
8440
9505
|
|
|
9506
|
+
/** `DiagnosticsResponse.floorCache` (crew#1147). Every `path` is `~/...`. */
|
|
9507
|
+
export type DiagnosticsFloorCache =
|
|
9508
|
+
| {
|
|
9509
|
+
path: string;
|
|
9510
|
+
bytes: number;
|
|
9511
|
+
totalCapBytes: number;
|
|
9512
|
+
repoCapBytes: number;
|
|
9513
|
+
idleTtlSecs: number;
|
|
9514
|
+
repos: Array<{ name: string; bytes: number; leaves: number }>;
|
|
9515
|
+
logs: { path: string; bytes: number; capBytes: number };
|
|
9516
|
+
}
|
|
9517
|
+
| { error: string };
|
|
9518
|
+
|
|
8441
9519
|
/**
|
|
8442
9520
|
* (api-types 0.130.0, crew#1068) `DiagnosticsResponse.vault`: what the daemon exported to the engine
|
|
8443
9521
|
* as `WICKED_VAULT_BIN` at boot. `shipped` = crew's own `wicked-vault` dependency's bin (an absolute
|
|
@@ -8909,8 +9987,33 @@ export type SystemLevel = 'green' | 'yellow' | 'red';
|
|
|
8909
9987
|
/** The existing action an attention item or row offers (the snapshot itself is read-only):
|
|
8910
9988
|
* `sign_in` — the CLI's sign-in (`POST /seats/:cli/login…` / the Agents page); `recheck` — read
|
|
8911
9989
|
* the snapshot again (every probe runs fresh per read); `open_gate` — the run's open gate;
|
|
8912
|
-
* `open_run` — the run.
|
|
8913
|
-
|
|
9990
|
+
* `open_run` — the run. (0.162.0) `rebuild_seat_images` — `POST /system/seat-images/rebuild`
|
|
9991
|
+
* (the `seat_images` row: missing or unheld seat images); a skin that does not know a kind shows
|
|
9992
|
+
* the item without its button. */
|
|
9993
|
+
export type SystemActionKind = 'sign_in' | 'recheck' | 'open_gate' | 'open_run' | 'rebuild_seat_images';
|
|
9994
|
+
|
|
9995
|
+
/** (0.162.0) `POST /api/v1/system/seat-images/rebuild` (a person only: 403 `{ error }` for an agent
|
|
9996
|
+
* or plugin bearer) → 202 once the engine process started; 409 while a rebuild runs; 503 on the
|
|
9997
|
+
* host floor, when crew cannot reach or start the engine binary, when the engine's seat image
|
|
9998
|
+
* status does not answer, when the roster cannot be read, or when no roster seat has an engine seat
|
|
9999
|
+
* image (`started: false` with why). A running rebuild is 409 before anything else is asked. The rebuild runs `wicked-core seat-image build <roster seats>` in the background (minutes;
|
|
10000
|
+
* it also holds an operator's own image); its progress reads on the `seat_images` row
|
|
10001
|
+
* (`details.rebuild`). */
|
|
10002
|
+
export interface RebuildSeatImagesResponse {
|
|
10003
|
+
started: boolean;
|
|
10004
|
+
/** Why it did not start; absent when it did. */
|
|
10005
|
+
reason?: string;
|
|
10006
|
+
rebuild: {
|
|
10007
|
+
running: boolean;
|
|
10008
|
+
startedAt: string;
|
|
10009
|
+
finishedAt: string | null;
|
|
10010
|
+
rc: number | null;
|
|
10011
|
+
tail: string[];
|
|
10012
|
+
/** The last output line that reads as a failure; `null` when none. */
|
|
10013
|
+
error: string | null;
|
|
10014
|
+
clis: string[];
|
|
10015
|
+
} | null;
|
|
10016
|
+
}
|
|
8914
10017
|
|
|
8915
10018
|
/** Where an item points. A skin maps it to its own route; crew never spells a studio URL. */
|
|
8916
10019
|
export type SystemTarget =
|
|
@@ -9165,7 +10268,9 @@ export interface SystemRun {
|
|
|
9165
10268
|
liveness: SystemRunLiveness;
|
|
9166
10269
|
/** Plain-words why ("waiting on you: plan approval", "no event for 42 min"). */
|
|
9167
10270
|
reason: string;
|
|
9168
|
-
/** The cursor unit
|
|
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. */
|
|
9169
10274
|
phase: string | null;
|
|
9170
10275
|
/** The cursor unit's ord; `null` when none is in flight. */
|
|
9171
10276
|
unitOrd: number | null;
|
|
@@ -9203,7 +10308,21 @@ export type SystemInfraKey =
|
|
|
9203
10308
|
| 'stores'
|
|
9204
10309
|
| 'seat_floor'
|
|
9205
10310
|
| 'disk'
|
|
9206
|
-
| 'load'
|
|
10311
|
+
| 'load'
|
|
10312
|
+
/** (0.155.0) The registered repositories' folders: `down` while any is missing (moved or deleted),
|
|
10313
|
+
* naming each with its path; `details.missing` lists `{ id, name, path }`. ABSENT before. */
|
|
10314
|
+
| 'repos'
|
|
10315
|
+
/** (0.162.0) The container seats' images (wicked-core `seat-image status`): `down` when a missing
|
|
10316
|
+
* seat image cannot be built (the operator's base is gone with no recipe, or an operator image is
|
|
10317
|
+
* missing) or the runtime VM disk is at 92 % or more; `degraded` when roster images are missing
|
|
10318
|
+
* (the next unit builds each first), not yet held against a runtime's image cleanup, the base is
|
|
10319
|
+
* missing, or the VM disk is at 75 % or more (a kubelet deletes unheld images from 85 %);
|
|
10320
|
+
* `unknown` when the engine, the roster or the disk could not be read. `details`: `images`
|
|
10321
|
+
* (`base`, `baseRecipe`, `holdSupported`, `floor`, `seats[]` with `present`/`held`/
|
|
10322
|
+
* `operatorImage`), `disk` (`totalBytes`, `availBytes`, `usedPct`), `missing`, `unheld`,
|
|
10323
|
+
* `imageGcHighPct`, `rebuild` (a running or the last rebuild, its output's last lines live).
|
|
10324
|
+
* `off` on the host floor. ABSENT before. */
|
|
10325
|
+
| 'seat_images';
|
|
9207
10326
|
|
|
9208
10327
|
export interface SystemInfraRow {
|
|
9209
10328
|
key: SystemInfraKey;
|
|
@@ -11095,6 +12214,8 @@ export interface DecidedGate {
|
|
|
11095
12214
|
creator: { seat: string; phase: string | null; ord: number } | null;
|
|
11096
12215
|
/** A standing order could have approved this gate (a phase-review gate of a run that lands no doctrine). */
|
|
11097
12216
|
orderApprovable: boolean;
|
|
12217
|
+
/** (api-types 0.156.0) Answered by voice and confirmed on screen ({@link GateDecision.input}); absent otherwise. */
|
|
12218
|
+
input?: 'voice';
|
|
11098
12219
|
}
|
|
11099
12220
|
|
|
11100
12221
|
/** `GET /gates/decided`'s 200. A malformed `since` answers 400. */
|
|
@@ -12100,6 +13221,23 @@ export interface EditorControl {
|
|
|
12100
13221
|
maxChars?: number;
|
|
12101
13222
|
}
|
|
12102
13223
|
|
|
13224
|
+
/**
|
|
13225
|
+
* How an editor looks on studio's Plugins page (program DES-LEARN §2; api-types 0.157.0). Every image is a `data:` URL
|
|
13226
|
+
* (`image/svg+xml`, `image/png` or `image/webp`, base64) the registry read from the editor's own files, bounded (icon
|
|
13227
|
+
* 16 KB, preview 200 KB) and never through a link: no path and no remote URL is on the wire. Each field is optional;
|
|
13228
|
+
* a file that is missing, too big or not the image its name says is left out (the editor is still served).
|
|
13229
|
+
*/
|
|
13230
|
+
export interface EditorVisuals {
|
|
13231
|
+
/** Drawn on `color`, at about 18 px. */
|
|
13232
|
+
icon?: string;
|
|
13233
|
+
/** `#rrggbb`. */
|
|
13234
|
+
color?: string;
|
|
13235
|
+
/** A 16:9 picture of the editor at work; a `dark` one is used on a dark theme (else `light`). */
|
|
13236
|
+
preview?: { light?: string; dark?: string };
|
|
13237
|
+
/** The editor offers a live preview on its own sample (reserved: studio draws one for run plugins today). */
|
|
13238
|
+
live?: boolean;
|
|
13239
|
+
}
|
|
13240
|
+
|
|
12103
13241
|
/**
|
|
12104
13242
|
* One registered editor, as Settings → Editors renders it. No path is on the wire: the bundle is
|
|
12105
13243
|
* fetched at `entry_url` (`GET /editors/:id/:version/entry`, the §8.2 headers, re-hashed per serve).
|
|
@@ -12132,6 +13270,11 @@ export interface EditorView {
|
|
|
12132
13270
|
/** `studio-bundle`: first-party, shipped with studio. `pack`: a third-party pack the operator installed. */
|
|
12133
13271
|
source: 'studio-bundle' | 'pack';
|
|
12134
13272
|
entry_url: string;
|
|
13273
|
+
/** Its one line for the Plugins page (at most 160 characters). Absent when the manifest has none, and from a daemon
|
|
13274
|
+
* that predates the field (api-types 0.157.0). */
|
|
13275
|
+
description?: string;
|
|
13276
|
+
/** Its icon, colour and preview (api-types 0.157.0). Absent when it declares none that read. */
|
|
13277
|
+
visuals?: EditorVisuals;
|
|
12135
13278
|
}
|
|
12136
13279
|
|
|
12137
13280
|
/** `GET /editors` (operator+). */
|
|
@@ -13013,3 +14156,112 @@ export interface DefaultEvalDetail {
|
|
|
13013
14156
|
report: DefaultEvalReport;
|
|
13014
14157
|
cases: DefaultEvalCase[];
|
|
13015
14158
|
}
|
|
14159
|
+
|
|
14160
|
+
// ── Voice mode, phase 1 (program DES-VOICE; api-types 0.156.0) ─────────────────────────────────────────
|
|
14161
|
+
|
|
14162
|
+
/**
|
|
14163
|
+
* `GET /voice/status` (and the answer of `POST|DELETE /voice/model`). Speech to text runs on THIS machine:
|
|
14164
|
+
* whisper.cpp's CLI plus one model file. Every voice route is the human operator's alone, on loopback
|
|
14165
|
+
* (403 `human_operator_only` / `voice_loopback_only`).
|
|
14166
|
+
*/
|
|
14167
|
+
export interface VoiceStatus {
|
|
14168
|
+
/** Audio is transcribed on this machine and never sent anywhere. Always `true` in phase 1. */
|
|
14169
|
+
local: true;
|
|
14170
|
+
/** The engine and the model are both here: `POST /voice/transcribe` can run. */
|
|
14171
|
+
ready: boolean;
|
|
14172
|
+
engine: {
|
|
14173
|
+
name: 'whisper.cpp';
|
|
14174
|
+
found: boolean;
|
|
14175
|
+
/** Where the CLI was found; `null` when it was not. */
|
|
14176
|
+
path: string | null;
|
|
14177
|
+
/** How to install (or upgrade) it on this platform, when it is missing or too old; else `null`. */
|
|
14178
|
+
install: string | null;
|
|
14179
|
+
/** (api-types 0.158.0) The version it reports (`--version`); `null` when not found, or too old to report one. */
|
|
14180
|
+
version: string | null;
|
|
14181
|
+
/** (api-types 0.158.0) New enough for voice (1.8.0 or later, reporting `--version`): a stdin transcription prints
|
|
14182
|
+
* its text and writes no file. An older engine is refused with 409 `voice_engine_outdated`, before any audio. */
|
|
14183
|
+
supported: boolean;
|
|
14184
|
+
};
|
|
14185
|
+
model: {
|
|
14186
|
+
/** `base.en`. */
|
|
14187
|
+
name: string;
|
|
14188
|
+
present: boolean;
|
|
14189
|
+
/** The model file's size; `null` when absent. */
|
|
14190
|
+
bytes: number | null;
|
|
14191
|
+
/** What the consent says before anything is fetched. */
|
|
14192
|
+
approxBytes: number;
|
|
14193
|
+
/** Where it is fetched from (`huggingface.co/ggerganov/whisper.cpp`). */
|
|
14194
|
+
source: string;
|
|
14195
|
+
/** A download in progress, or the last one's failure; `null` when none. */
|
|
14196
|
+
download: {
|
|
14197
|
+
state: 'running' | 'failed';
|
|
14198
|
+
receivedBytes: number;
|
|
14199
|
+
totalBytes: number | null;
|
|
14200
|
+
startedAt: string;
|
|
14201
|
+
error: string | null;
|
|
14202
|
+
} | null;
|
|
14203
|
+
};
|
|
14204
|
+
}
|
|
14205
|
+
|
|
14206
|
+
/** `POST /voice/model`: the person's consent to fetch the model (202 = started; 200 = already here; 409
|
|
14207
|
+
* `voice_download_running`). Audited `voice.model.download_started`. `DELETE /voice/model` removes it. */
|
|
14208
|
+
export interface PostVoiceModelBody {
|
|
14209
|
+
consent: true;
|
|
14210
|
+
}
|
|
14211
|
+
|
|
14212
|
+
/**
|
|
14213
|
+
* `POST /voice/transcribe` with an `audio/wav` body (16 kHz mono 16-bit, at most 8 MiB). The audio is held in
|
|
14214
|
+
* memory for the call and dropped: never stored, logged or audited. Errors carry `code`:
|
|
14215
|
+
* `voice_engine_missing` / `voice_engine_outdated` / `voice_model_missing` (409), `voice_audio_invalid` (400/415),
|
|
14216
|
+
* `voice_audio_too_large` (413), `voice_busy` (429: one runs and one waits), `voice_timeout` (504), `voice_failed` (500).
|
|
14217
|
+
*/
|
|
14218
|
+
export interface VoiceTranscribeResponse {
|
|
14219
|
+
/** The words, one line; empty when nothing was said. */
|
|
14220
|
+
text: string;
|
|
14221
|
+
ms: number;
|
|
14222
|
+
model: string;
|
|
14223
|
+
}
|
|
14224
|
+
|
|
14225
|
+
/** A section a widget registers in the `voice-dashboard` panel slot (the `panels[]` shape of a run plugin). */
|
|
14226
|
+
export interface VoicePanelDecl {
|
|
14227
|
+
slot: 'voice-dashboard';
|
|
14228
|
+
id: string;
|
|
14229
|
+
title: string;
|
|
14230
|
+
/** 1-99, lower first. */
|
|
14231
|
+
order: number;
|
|
14232
|
+
}
|
|
14233
|
+
|
|
14234
|
+
/**
|
|
14235
|
+
* A USER-MADE dashboard widget: a declarative plugin (no code, nothing framed) that shows one field of
|
|
14236
|
+
* `GET /system` or `GET /diagnostics` as a number or a chart. `metric.path` is a field path:
|
|
14237
|
+
* `infra[key=load].details.load1`, `runs.length`, `toReview`.
|
|
14238
|
+
*/
|
|
14239
|
+
export interface VoiceWidgetManifest {
|
|
14240
|
+
/** `user.<slug>`. */
|
|
14241
|
+
id: string;
|
|
14242
|
+
title: string;
|
|
14243
|
+
version: 1;
|
|
14244
|
+
kind: 'metric';
|
|
14245
|
+
panels: [VoicePanelDecl];
|
|
14246
|
+
metric: {
|
|
14247
|
+
source: 'system' | 'diagnostics';
|
|
14248
|
+
path: string;
|
|
14249
|
+
display: 'number' | 'chart';
|
|
14250
|
+
unit?: string;
|
|
14251
|
+
};
|
|
14252
|
+
createdAt?: string;
|
|
14253
|
+
}
|
|
14254
|
+
|
|
14255
|
+
/** `GET /voice/dashboard`: this person's dashboard (keyed by actor id). `layout: null` = never saved. */
|
|
14256
|
+
export interface VoiceDashboard {
|
|
14257
|
+
/** Widget ids in order: `builtin.<id>` or a user widget's `user.<slug>`. */
|
|
14258
|
+
layout: string[] | null;
|
|
14259
|
+
widgets: VoiceWidgetManifest[];
|
|
14260
|
+
updatedAt: string | null;
|
|
14261
|
+
}
|
|
14262
|
+
|
|
14263
|
+
/** `PUT /voice/dashboard` (at most 24 on the layout, 16 user widgets; every `user.*` on the layout is in `widgets`). */
|
|
14264
|
+
export interface PutVoiceDashboardBody {
|
|
14265
|
+
layout: string[];
|
|
14266
|
+
widgets: VoiceWidgetManifest[];
|
|
14267
|
+
}
|