wicked-crew-api-types 0.148.0 → 0.167.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 +1234 -13
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -346,6 +346,19 @@ export interface HealthCapabilities {
|
|
|
346
346
|
* and `POST /runs/:id/working-doc/versions` ({@link WorkingDocView}). ABSENT on an older daemon — read as `false`.
|
|
347
347
|
*/
|
|
348
348
|
workingDoc?: boolean;
|
|
349
|
+
/**
|
|
350
|
+
* (api-types 0.149.0, power mode) The engine runs POWER MODE: `LaunchRunBody.power`, `GET|POST /runs/:id/power`,
|
|
351
|
+
* `POST /runs/:id/rigor`, `POST /runs/:id/power/pause`, `GET /runs/:id/bus` ({@link RunBusPage}),
|
|
352
|
+
* `AgentSession.power` ({@link PowerState}) and the power frames ({@link PowerEvent}).
|
|
353
|
+
* ABSENT on an older daemon: read as `false` and hide the switch.
|
|
354
|
+
*/
|
|
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;
|
|
349
362
|
}
|
|
350
363
|
|
|
351
364
|
// ── A run's working document (program DES-POWER-MODE §8.3, §9; api-types 0.148.0) ──────────────────
|
|
@@ -353,10 +366,12 @@ export interface HealthCapabilities {
|
|
|
353
366
|
/** The working document's sections, in order. */
|
|
354
367
|
export type WorkingDocSectionId = 'goal' | 'approach' | 'decisions' | 'constraints' | 'questions' | 'next';
|
|
355
368
|
|
|
356
|
-
/** Who wrote a version: a person (the operator), a plugin's own generated lines,
|
|
369
|
+
/** Who wrote a version: a person (the operator), a plugin's own generated lines, the power orchestrator's own notes
|
|
370
|
+
* (`agent`, id `agent:<seat>`: Approach and Decisions only, never a steer), or crew (the first version). */
|
|
357
371
|
export type WorkingDocAuthor =
|
|
358
372
|
| { kind: 'human'; id: string }
|
|
359
373
|
| { kind: 'plugin'; id: string }
|
|
374
|
+
| { kind: 'agent'; id: string }
|
|
360
375
|
| { kind: 'system'; id: 'crew' };
|
|
361
376
|
|
|
362
377
|
/** One version of the working document, as crew attributed it. */
|
|
@@ -394,6 +409,9 @@ export interface WorkingDocSteer {
|
|
|
394
409
|
error: string | null;
|
|
395
410
|
supersededBy?: string | null;
|
|
396
411
|
renewals?: number;
|
|
412
|
+
/** (0.161.0, DES-VOICE) The person said the edit and confirmed it on screen: the thread says "You (by voice)".
|
|
413
|
+
* ABSENT on a typed edit (and on an older daemon). It grants nothing. */
|
|
414
|
+
input?: 'voice';
|
|
397
415
|
}
|
|
398
416
|
|
|
399
417
|
/** `GET /runs/:id/working-doc` (and the body of `POST /runs/:id/working-doc`). */
|
|
@@ -405,15 +423,23 @@ export interface WorkingDocView {
|
|
|
405
423
|
labels: Record<WorkingDocSectionId, string>;
|
|
406
424
|
trail: WorkingDocTrailEntry[];
|
|
407
425
|
steers: WorkingDocSteer[];
|
|
426
|
+
/** (0.151.0) `true` when crew itself writes the document's event-derived lines (Decisions answered, Open questions,
|
|
427
|
+
* Next) from the run's own log, as `plugin:wicked-phase-report@…`: a host plugin then writes none of its own and
|
|
428
|
+
* only renders and takes a person's edits. ABSENT on an older daemon — read as `false` (the plugin keeps writing). */
|
|
429
|
+
eventLines?: boolean;
|
|
408
430
|
}
|
|
409
431
|
|
|
410
432
|
/** `POST /runs/:id/working-doc/versions`. `author: 'operator'` only from a person; `author: 'plugin'` writes only the
|
|
411
|
-
* plugin's own
|
|
433
|
+
* plugin's own lines, under `decisions`, `questions` and `next` (never `goal`, `approach` or `constraints`: 403). A
|
|
434
|
+
* plugin's write never steers, in any section (`steer` is null). 409 `{head}` when the document moved since `base`. */
|
|
412
435
|
export interface ProposeWorkingDocRequest {
|
|
413
436
|
base: number;
|
|
414
437
|
sections: Partial<Record<WorkingDocSectionId, string>>;
|
|
415
438
|
author: 'operator' | 'plugin';
|
|
416
439
|
plugin?: { id: string; version: string };
|
|
440
|
+
/** (0.161.0, DES-VOICE) The person said this edit and confirmed it on screen. On `author: 'operator'` only (400
|
|
441
|
+
* otherwise); kept on the steer ({@link WorkingDocSteer.input}) and the `run.steered.doc` audit line. */
|
|
442
|
+
input?: 'voice';
|
|
417
443
|
}
|
|
418
444
|
|
|
419
445
|
export interface ProposeWorkingDocResponse {
|
|
@@ -431,6 +457,437 @@ export interface WorkingDocChangedEvent {
|
|
|
431
457
|
head: number | null;
|
|
432
458
|
}
|
|
433
459
|
|
|
460
|
+
// ── Power mode (program DES-POWER-MODE; api-types 0.149.0) ──────────────────────────────────────────
|
|
461
|
+
//
|
|
462
|
+
// One orchestrator seat session builds the whole change in many turns; rigor is sized at intake, re-scored at
|
|
463
|
+
// checkpoints from the actual diff, and applied once at hand-off. The ENGINE computes every rigor value: nothing on a
|
|
464
|
+
// request or a plugin can lower it. Field names are camelCase on every surface (session, route, frame, bus row).
|
|
465
|
+
|
|
466
|
+
/** The operator's word for the engine's floor band (core `review_scale` bands): light 0-19, standard 20-39,
|
|
467
|
+
* high 40-69, highest 70-100 (or destructive). */
|
|
468
|
+
export type Rigor = 'light' | 'standard' | 'high' | 'highest';
|
|
469
|
+
|
|
470
|
+
/** What re-scored the run. `intake` is the QE plan; `commit` / `turn` / `timer` / `pre_handoff` are checkpoints;
|
|
471
|
+
* `operator` / `plugin` / `doc_edit` are raises; `toggle` records a power switch flip. */
|
|
472
|
+
export type RigorTrigger =
|
|
473
|
+
| 'intake' | 'commit' | 'turn' | 'timer' | 'pre_handoff'
|
|
474
|
+
| 'operator' | 'plugin' | 'doc_edit' | 'toggle';
|
|
475
|
+
|
|
476
|
+
/** A level rigor can never go below, and who set it. */
|
|
477
|
+
export interface RigorFloor {
|
|
478
|
+
rigor: Rigor;
|
|
479
|
+
/** `policy` (the assurance contract / required phases), `compliance` (a steering rule), `qe_plan`, `operator`,
|
|
480
|
+
* `plugin`, `doc_edit`. */
|
|
481
|
+
by: 'policy' | 'compliance' | 'qe_plan' | 'operator' | 'plugin' | 'doc_edit';
|
|
482
|
+
why: string;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/** What hand-off will apply, as the current rigor sizes it. */
|
|
486
|
+
export interface HandoffRequirements {
|
|
487
|
+
/** `targeted`: the floor runs the change's targeted tests; `full`: the repo's full suite. */
|
|
488
|
+
tests: 'targeted' | 'full';
|
|
489
|
+
/** Reviews on a seat distinct from the orchestrator (never the builder, nor its subagents). `design` is not a
|
|
490
|
+
* separate step: the `review` step ({@link HandoffStep}) also judges the orchestrator's approach and counts as the
|
|
491
|
+
* band's `design` phase (operator ruling 2026-10-29); it is listed so the card can say so. */
|
|
492
|
+
reviews: Array<{ kind: 'distinct_seat' | 'design' | 'security'; why: string }>;
|
|
493
|
+
qeAcceptance: { required: boolean; why: string };
|
|
494
|
+
/** Named checks beyond the repo's floor (QE plan / plugin added), in order. */
|
|
495
|
+
checks: string[];
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/** The intake QE plan's rigor record (`wicked.run.intake.planned`). The band is the engine's intent score of the
|
|
499
|
+
* declared scope; the QE plan (garden qe-risk-assessor + qe-test-strategist) can only RAISE it. */
|
|
500
|
+
export interface RigorPlan {
|
|
501
|
+
rigor: Rigor;
|
|
502
|
+
/** The engine's 0-100 intent score and its band (`"20-39"`). */
|
|
503
|
+
score: number;
|
|
504
|
+
band: string;
|
|
505
|
+
highRisk: boolean;
|
|
506
|
+
/** Plain reasons for the band (the scorer's, then the QE plan's). */
|
|
507
|
+
reasons: string[];
|
|
508
|
+
handoff: HandoffRequirements;
|
|
509
|
+
/** Phases that stay phased even in power mode (policy, a steering rule, or the QE plan), with why. */
|
|
510
|
+
mandatoryPhases: Array<{ phase: string; why: string }>;
|
|
511
|
+
/** Non-null when power mode is refused for this run (policy or the plan requires phased), in one line. */
|
|
512
|
+
phasedRequired: string | null;
|
|
513
|
+
/** The QE plan's time estimate for the build, minutes; null when it gave none. */
|
|
514
|
+
estimateMinutes: number | null;
|
|
515
|
+
/** The QE plan's risks and planned test scenarios (pass 1), plain lines. */
|
|
516
|
+
risks: string[];
|
|
517
|
+
scenarios: string[];
|
|
518
|
+
/** What rigor can never go below. */
|
|
519
|
+
floors: RigorFloor[];
|
|
520
|
+
/** The seat that planned (the intake unit's seat), and when (unix millis). */
|
|
521
|
+
plannedBy: string;
|
|
522
|
+
at: number;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/** The signals one checkpoint read from the actual diff. */
|
|
526
|
+
export interface RigorSignals {
|
|
527
|
+
files: number;
|
|
528
|
+
lines: number;
|
|
529
|
+
/** Graph dependents within the scorer's hops; null when the graph could not be read. */
|
|
530
|
+
dependents: number | null;
|
|
531
|
+
/** Products (top-level areas) the diff spans. */
|
|
532
|
+
spread: number;
|
|
533
|
+
newDependencies: number;
|
|
534
|
+
/** Sensitive areas touched: critical-path markers and steering-rule areas, plain words. */
|
|
535
|
+
sensitive: string[];
|
|
536
|
+
struggle: {
|
|
537
|
+
failedRuns: number;
|
|
538
|
+
reverts: number;
|
|
539
|
+
turns: number;
|
|
540
|
+
elapsedMinutes: number;
|
|
541
|
+
estimateMinutes: number | null;
|
|
542
|
+
/** 0-100; at or over the struggle line pauses the session. */
|
|
543
|
+
score: number;
|
|
544
|
+
};
|
|
545
|
+
/** Planned scenarios with no test yet, or new surfaces the plan did not cover. */
|
|
546
|
+
planGaps: string[];
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/** One rigor-history row (`wicked.run.rigor.rescored`), written EVERY time the run is re-scored, raised, lowered or
|
|
550
|
+
* toggled — also when nothing changed (`direction: 'same'`). */
|
|
551
|
+
export interface RigorChange {
|
|
552
|
+
/** 1-based, per run. */
|
|
553
|
+
seq: number;
|
|
554
|
+
at: number;
|
|
555
|
+
trigger: RigorTrigger;
|
|
556
|
+
/** Rigor before and after. The `intake` row has `from === to` (the planned rigor). Null only on a `toggle` row
|
|
557
|
+
* written before intake planned anything. */
|
|
558
|
+
from: Rigor | null;
|
|
559
|
+
to: Rigor | null;
|
|
560
|
+
direction: 'up' | 'down' | 'same';
|
|
561
|
+
/** The intake score, the score now, and `actual - planned`. */
|
|
562
|
+
planned: number;
|
|
563
|
+
actual: number;
|
|
564
|
+
delta: number;
|
|
565
|
+
reasons: string[];
|
|
566
|
+
signals: RigorSignals | null;
|
|
567
|
+
/** `engine`, a person's actor id, or `plugin:<id>@<version>`. */
|
|
568
|
+
by: string;
|
|
569
|
+
/** What held rigor up when a lowering was capped (empty otherwise). */
|
|
570
|
+
floors: RigorFloor[];
|
|
571
|
+
/** The checkpoint ordinal (1-based) and the orchestrator turn, when a checkpoint wrote it. */
|
|
572
|
+
checkpoint: number | null;
|
|
573
|
+
turn: number | null;
|
|
574
|
+
/** This checkpoint paused the session ("suddenly complex"); see {@link PowerPause}. */
|
|
575
|
+
paused: boolean;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/** One flip of the power switch. */
|
|
579
|
+
export interface PowerToggle {
|
|
580
|
+
at: number;
|
|
581
|
+
on: boolean;
|
|
582
|
+
by: string;
|
|
583
|
+
reason: string | null;
|
|
584
|
+
/** The phases that stay phased after an Off -> On flip (the plan mandates them). */
|
|
585
|
+
stayPhased: string[];
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/** The session is paused at a checkpoint: a two-band jump, a destructive marker, spread into another product, a new
|
|
589
|
+
* dependency in a sensitive area, or struggle past its line. The orchestrator waits at its turn end (the run stays
|
|
590
|
+
* `executing`; no engine gate opens under an in-flight unit) until `POST /runs/:id/power/pause`
|
|
591
|
+
* ({@link PowerPauseRequest}) answers. */
|
|
592
|
+
export interface PowerPause {
|
|
593
|
+
at: number;
|
|
594
|
+
checkpoint: number;
|
|
595
|
+
reasons: string[];
|
|
596
|
+
/** `split` is recommended when the diff spans two or more products. */
|
|
597
|
+
recommended: 'split' | 'switch_phased' | 'continue_high' | 'stop';
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/** One hand-off step as it ran. */
|
|
601
|
+
export interface HandoffStep {
|
|
602
|
+
step: 'rescore' | 'checks' | 'review' | 'security' | 'qe' | 'compliance';
|
|
603
|
+
/** The hand-off round this row belongs to (1-based): a failed round's rows stay, the next round adds its own. */
|
|
604
|
+
round: number;
|
|
605
|
+
ord: number | null;
|
|
606
|
+
status: 'pending' | 'running' | 'passed' | 'failed' | 'skipped';
|
|
607
|
+
/** The seat that ran it (never the orchestrator for a review / QE). */
|
|
608
|
+
seat: string | null;
|
|
609
|
+
summary: string | null;
|
|
610
|
+
at: number;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/** A run's power-mode state: `AgentSession.power`, and the body of `GET /runs/:id/power`. */
|
|
614
|
+
export interface PowerState {
|
|
615
|
+
/** The switch, now. */
|
|
616
|
+
on: boolean;
|
|
617
|
+
/** False when policy or the plan requires phased; {@link refusedReason} says why. */
|
|
618
|
+
available: boolean;
|
|
619
|
+
refusedReason: string | null;
|
|
620
|
+
/** Current rigor (null before intake has planned). */
|
|
621
|
+
rigor: Rigor | null;
|
|
622
|
+
plan: RigorPlan | null;
|
|
623
|
+
history: RigorChange[];
|
|
624
|
+
toggles: PowerToggle[];
|
|
625
|
+
/** The orchestrator seat session: its seat, the build unit, turns so far, and whether it is in a turn now. */
|
|
626
|
+
orchestrator: { cli: string | null; ord: number | null; turns: number; inTurn: boolean; sessionRestarts: number };
|
|
627
|
+
/** Every orchestrator turn so far, oldest first (at most the last 50). */
|
|
628
|
+
turnLog: PowerTurnRecord[];
|
|
629
|
+
checkpoints: number;
|
|
630
|
+
/** The hand-off as it runs: round 1 is the first hand-off; a failure goes back to the SAME session as a new turn
|
|
631
|
+
* and starts the next round. After `maxRounds` the run asks the operator. */
|
|
632
|
+
handoff: { round: number; maxRounds: number; steps: HandoffStep[] } | null;
|
|
633
|
+
pause: PowerPause | null;
|
|
634
|
+
/** The insights row for planned vs actual (written when the run ends). */
|
|
635
|
+
outcome: PowerOutcome | null;
|
|
636
|
+
/** Floors set after launch (an operator's raise), kept whether or not intake planned anything; the intake plan's own
|
|
637
|
+
* are on `plan.floors`. Rigor never goes below any of them. */
|
|
638
|
+
floors: RigorFloor[];
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/** One orchestrator turn as recorded. */
|
|
642
|
+
export interface PowerTurnRecord {
|
|
643
|
+
turn: number;
|
|
644
|
+
attempt: number;
|
|
645
|
+
cli: string;
|
|
646
|
+
startedAt: number;
|
|
647
|
+
endedAt: number | null;
|
|
648
|
+
outcome: 'checkpoint' | 'handoff' | 'paused' | 'failed' | 'cap' | null;
|
|
649
|
+
summary: string | null;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/** Planned vs actual, recorded when a power run ends (the insights calibration input). */
|
|
653
|
+
export interface PowerOutcome {
|
|
654
|
+
plannedRigor: Rigor;
|
|
655
|
+
finalRigor: Rigor;
|
|
656
|
+
plannedScore: number;
|
|
657
|
+
finalScore: number;
|
|
658
|
+
estimateMinutes: number | null;
|
|
659
|
+
actualMinutes: number;
|
|
660
|
+
turns: number;
|
|
661
|
+
checkpoints: number;
|
|
662
|
+
handoffRounds: number;
|
|
663
|
+
operatorGates: number;
|
|
664
|
+
outcome: 'delivered' | 'completed' | 'failed' | 'cancelled';
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/** `GET /runs/:id/power` (404 for an unknown run; a run launched phased answers `on: false`). */
|
|
668
|
+
export interface PowerView extends PowerState {
|
|
669
|
+
runId: string;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/** `POST /runs/:id/power`: flip the switch; 200 answers {@link PowerView}. On -> Off is always allowed (adds rigor;
|
|
673
|
+
* the remaining work goes phased). Off -> On is allowed only for phases the plan does not mandate; a phased-required
|
|
674
|
+
* run answers 409 {@link PowerConflict}. Human actors only; audited `run.power_mode.toggled`. */
|
|
675
|
+
export interface PowerToggleRequest {
|
|
676
|
+
on: boolean;
|
|
677
|
+
reason?: string | null | undefined;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/** `POST /runs/:id/rigor`: raise rigor; 200 answers {@link PowerView}. Never lowers: a lower or equal `atLeast` is
|
|
681
|
+
* 409 {@link PowerConflict}. The raise becomes a floor. Human actors only; audited `run.rigor.raised`. */
|
|
682
|
+
export interface RigorRaiseRequest {
|
|
683
|
+
atLeast: Rigor;
|
|
684
|
+
reason: string;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/** `POST /runs/:id/power/pause`: answer a checkpoint pause ({@link PowerPause}); 200 answers {@link PowerView}.
|
|
688
|
+
* `continue_high` raises rigor to at least high (an operator floor), `continue` goes on (the `note`, if any, is the
|
|
689
|
+
* next turn's steer), `switch_phased` flips the switch off (the build hands off as it stands), `stop` cancels the
|
|
690
|
+
* run. 409 {@link PowerConflict} when the run is not paused. Human actors only; audited `run.power_mode.paused`. */
|
|
691
|
+
export interface PowerPauseRequest {
|
|
692
|
+
decision: 'continue_high' | 'continue' | 'switch_phased' | 'stop';
|
|
693
|
+
note?: string | null | undefined;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/** The 409 (and 422) body of the power routes. */
|
|
697
|
+
export interface PowerConflict {
|
|
698
|
+
error: string;
|
|
699
|
+
reason: string;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/** `/ws` frame: intake planned the run's rigor (bus `wicked.run.intake.planned`). */
|
|
703
|
+
export type PowerIntakePlannedEvent = {
|
|
704
|
+
type: 'powerIntakePlanned';
|
|
705
|
+
session: string;
|
|
706
|
+
ord: number;
|
|
707
|
+
plan: RigorPlan;
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
/** `/ws` frame: the run was re-scored, raised, lowered or toggled (bus `wicked.run.rigor.rescored`). */
|
|
711
|
+
export type RigorRescoredEvent = {
|
|
712
|
+
type: 'rigorRescored';
|
|
713
|
+
session: string;
|
|
714
|
+
change: RigorChange;
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
/** `/ws` frame: a checkpoint ran (bus `wicked.run.checkpoint.reached`). `picked` = the operator messages and doc
|
|
718
|
+
* steers the next turn's prompt carries. */
|
|
719
|
+
export type PowerCheckpointEvent = {
|
|
720
|
+
type: 'powerCheckpointReached';
|
|
721
|
+
session: string;
|
|
722
|
+
ord: number;
|
|
723
|
+
checkpoint: number;
|
|
724
|
+
turn: number;
|
|
725
|
+
trigger: 'commit' | 'turn' | 'timer' | 'pre_handoff';
|
|
726
|
+
/** The worktree HEAD at the checkpoint (short sha), null before the first commit. */
|
|
727
|
+
head: string | null;
|
|
728
|
+
picked: number;
|
|
729
|
+
rigor: Rigor;
|
|
730
|
+
paused: boolean;
|
|
731
|
+
/** The pause this checkpoint opened (also on `PowerState.pause`), else null. */
|
|
732
|
+
pause: PowerPause | null;
|
|
733
|
+
at: number;
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
/** `/ws` frame: an orchestrator turn started (bus `wicked.run.turn.started`). */
|
|
737
|
+
export type PowerTurnStartedEvent = {
|
|
738
|
+
type: 'powerTurnStarted';
|
|
739
|
+
session: string;
|
|
740
|
+
ord: number;
|
|
741
|
+
attempt: number;
|
|
742
|
+
turn: number;
|
|
743
|
+
cli: string;
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
/** `/ws` frame: an orchestrator turn ended (bus `wicked.run.turn.completed`). `outcome`: `checkpoint` (more turns
|
|
747
|
+
* follow), `handoff` (the orchestrator declared hand-off), `paused`, `failed`, `cap` (the turn cap; handed off). */
|
|
748
|
+
export type PowerTurnCompletedEvent = {
|
|
749
|
+
type: 'powerTurnCompleted';
|
|
750
|
+
session: string;
|
|
751
|
+
ord: number;
|
|
752
|
+
attempt: number;
|
|
753
|
+
turn: number;
|
|
754
|
+
cli: string;
|
|
755
|
+
outcome: 'checkpoint' | 'handoff' | 'paused' | 'failed' | 'cap';
|
|
756
|
+
/** The orchestrator's one-line summary, or null. */
|
|
757
|
+
summary: string | null;
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
export type PowerTurnEvent = PowerTurnStartedEvent | PowerTurnCompletedEvent;
|
|
761
|
+
|
|
762
|
+
/** `/ws` frame: a hand-off step changed (bus `wicked.run.handoff.stepped`). */
|
|
763
|
+
export type PowerHandoffEvent = {
|
|
764
|
+
type: 'powerHandoffStepped';
|
|
765
|
+
session: string;
|
|
766
|
+
round: number;
|
|
767
|
+
maxRounds: number;
|
|
768
|
+
step: HandoffStep;
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
/** `/ws` frame: the power switch flipped (bus `wicked.run.power.toggled`). */
|
|
772
|
+
export type PowerToggledEvent = {
|
|
773
|
+
type: 'powerToggled';
|
|
774
|
+
session: string;
|
|
775
|
+
toggle: PowerToggle;
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
/** `/ws` frame: what the orchestrator did in the worktree, read off git by the engine (bus
|
|
779
|
+
* `wicked.run.activity.recorded`). Polled about once a minute during a turn and at its end, so rows arrive in
|
|
780
|
+
* batches, not keystroke by keystroke. `edit`: a file whose +/- against the run's base changed since the last look
|
|
781
|
+
* (`path`, `added`, `removed`: the file's totals against the base, not the delta). `commit`: a new commit (`sha`
|
|
782
|
+
* short, `subject`, `added`, `removed` of that commit). Test runs are NOT reported (the headless carrier records
|
|
783
|
+
* no exit codes); the hand-off's `checks` step and `repoChecksEvaluated` carry the test results. */
|
|
784
|
+
export type PowerActivityEvent = {
|
|
785
|
+
type: 'powerActivity';
|
|
786
|
+
session: string;
|
|
787
|
+
ord: number;
|
|
788
|
+
turn: number;
|
|
789
|
+
at: number;
|
|
790
|
+
kind: 'edit' | 'commit';
|
|
791
|
+
path: string | null;
|
|
792
|
+
added: number | null;
|
|
793
|
+
removed: number | null;
|
|
794
|
+
sha: string | null;
|
|
795
|
+
subject: string | null;
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
/** `/ws` frame: a seat's tool call started or finished, live from its stream as it happens (bus
|
|
799
|
+
* `wicked.run.tool.started` / `wicked.run.tool.finished`). Sent for claude, codex (`exec --json` items) and pi
|
|
800
|
+
* (`--mode json` tool executions); at most 24 frames per 2 s and 4000 per attempt, and a call shown starting is
|
|
801
|
+
* always shown finishing. `target` is a repo-relative path, a search, or a command with secrets cut, at most 160
|
|
802
|
+
* characters. (0.151.0) `state: 'working'` (bus `wicked.run.tool.working`) is a quiet seat's heartbeat, any seat,
|
|
803
|
+
* copilot included: after 15 s with no frame, one per 15 s while it stays quiet, `id` `working-<attempt>` (update one
|
|
804
|
+
* row), `kind: 'working'`, `tool` the seat, `target` `last output N s ago`, `durationMs` that silence. */
|
|
805
|
+
export type ToolActivityEvent = {
|
|
806
|
+
type: 'toolActivity';
|
|
807
|
+
session: string;
|
|
808
|
+
ord: number;
|
|
809
|
+
attempt: number;
|
|
810
|
+
at: number;
|
|
811
|
+
id: string;
|
|
812
|
+
state: 'started' | 'finished' | 'working';
|
|
813
|
+
kind: 'read' | 'search' | 'run' | 'test' | 'edit' | 'write' | 'skill' | 'task' | 'other' | 'working';
|
|
814
|
+
tool: string;
|
|
815
|
+
target: string | null;
|
|
816
|
+
ok: boolean | null;
|
|
817
|
+
durationMs: number | null;
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
/** `/ws` frame: new working notes from the power orchestrator's stream (bus `wicked.run.notes.recorded`): its
|
|
821
|
+
* approach when stated or restated, and each new decision with its reason. Crew writes them into the run's working
|
|
822
|
+
* document as `agent:<seat>`; they never steer. */
|
|
823
|
+
export type PowerWorkingNotesEvent = {
|
|
824
|
+
type: 'powerWorkingNotes';
|
|
825
|
+
session: string;
|
|
826
|
+
ord: number;
|
|
827
|
+
attempt: number;
|
|
828
|
+
turn: number;
|
|
829
|
+
seat: string;
|
|
830
|
+
at: number;
|
|
831
|
+
approach: string | null;
|
|
832
|
+
decisions: Array<{ text: string; why: string | null }>;
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
export type PowerEvent =
|
|
836
|
+
| ToolActivityEvent
|
|
837
|
+
| PowerWorkingNotesEvent
|
|
838
|
+
| PowerActivityEvent
|
|
839
|
+
| PowerIntakePlannedEvent
|
|
840
|
+
| RigorRescoredEvent
|
|
841
|
+
| PowerCheckpointEvent
|
|
842
|
+
| PowerTurnEvent
|
|
843
|
+
| PowerHandoffEvent
|
|
844
|
+
| PowerToggledEvent;
|
|
845
|
+
|
|
846
|
+
/** The engine's bus mirror of the power frames (and the first `wicked.run.*` lifecycle set, DES-PLUGIN-EVENTS §3.1),
|
|
847
|
+
* 4-segment `wicked.<domain>.<noun>.<verb>`, `domain=wicked-core`. */
|
|
848
|
+
export type RunBusType =
|
|
849
|
+
| 'wicked.run.intake.planned'
|
|
850
|
+
| 'wicked.run.rigor.rescored'
|
|
851
|
+
| 'wicked.run.checkpoint.reached'
|
|
852
|
+
| 'wicked.run.turn.started'
|
|
853
|
+
| 'wicked.run.turn.completed'
|
|
854
|
+
| 'wicked.run.handoff.stepped'
|
|
855
|
+
| 'wicked.run.power.toggled'
|
|
856
|
+
| 'wicked.run.activity.recorded'
|
|
857
|
+
| 'wicked.run.tool.started'
|
|
858
|
+
| 'wicked.run.tool.finished'
|
|
859
|
+
| 'wicked.run.tool.working'
|
|
860
|
+
| 'wicked.run.notes.recorded'
|
|
861
|
+
| 'wicked.run.unit.started'
|
|
862
|
+
| 'wicked.run.unit.finished'
|
|
863
|
+
| 'wicked.run.checks.evaluated'
|
|
864
|
+
| 'wicked.run.human.awaited'
|
|
865
|
+
| 'wicked.run.qe.decided'
|
|
866
|
+
| 'wicked.run.steer.queued'
|
|
867
|
+
| 'wicked.run.steer.delivered';
|
|
868
|
+
|
|
869
|
+
/** One mirrored row as a plugin feed or `GET /runs/:id/bus` serves it. `eventId` is the bus row id (ordered,
|
|
870
|
+
* at-least-once: dedupe on it). `seq` is the durable run log's `seq` of the event the row mirrors: a correlation and
|
|
871
|
+
* ordering value, strictly increasing within a run but WITH GAPS (the log counter is process-wide and most events
|
|
872
|
+
* are not mirrored) — never a continuity check. `payload` is the matching `/ws` frame without `type` and `session`
|
|
873
|
+
* (bulky `output` / `log` fields dropped), plus `runId`, `seq` and `at`. */
|
|
874
|
+
export interface RunBusRow {
|
|
875
|
+
eventId: number;
|
|
876
|
+
seq: number;
|
|
877
|
+
type: RunBusType;
|
|
878
|
+
runId: string;
|
|
879
|
+
at: number;
|
|
880
|
+
payload: Record<string, unknown>;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/** `GET /runs/:id/bus?after=<eventId>&limit=<n>`: the run's mirrored rows after a cursor, oldest first. `cursor` is
|
|
884
|
+
* the last row's `eventId` (pass it back as `after`); `rows` is empty and `cursor === after` when there are none.
|
|
885
|
+
* 503 when the daemon has no bus. */
|
|
886
|
+
export interface RunBusPage {
|
|
887
|
+
rows: RunBusRow[];
|
|
888
|
+
cursor: number;
|
|
889
|
+
}
|
|
890
|
+
|
|
434
891
|
/** One `GET /health.warnings[]` entry (additive; wicked-core#411 / wicked-crew#497). */
|
|
435
892
|
export interface HealthWarning {
|
|
436
893
|
/** `state-home.unregistered` today; open for later kinds (e.g. `seat.work_default`,
|
|
@@ -446,6 +903,11 @@ export interface AgentSession {
|
|
|
446
903
|
id: string;
|
|
447
904
|
workflow_id: string;
|
|
448
905
|
problem: string;
|
|
906
|
+
/**
|
|
907
|
+
* (api-types 0.149.0) The run's power-mode state ({@link PowerState}); ABSENT or `null` on a run launched phased
|
|
908
|
+
* before power mode existed, or on an older engine. camelCase inside, unlike the session's own fields.
|
|
909
|
+
*/
|
|
910
|
+
power?: PowerState | null | undefined;
|
|
449
911
|
/**
|
|
450
912
|
* (api-types 0.113.0; operator ruling 2026-10-12) The run's SHORT JOB TITLE, derived by the daemon
|
|
451
913
|
* at DTO assembly on `GET /runs` and `GET /runs/:id` from {@link problem} — deterministic, at most
|
|
@@ -1966,6 +2428,20 @@ export interface GateDecision {
|
|
|
1966
2428
|
* `POST /runs/:id/resume` or `/reassign`.
|
|
1967
2429
|
*/
|
|
1968
2430
|
ord?: number;
|
|
2431
|
+
/**
|
|
2432
|
+
* (api-types 0.156.0, DES-VOICE) The person answered by voice: studio matched the spoken words to this
|
|
2433
|
+
* answer, showed it on screen and the person confirmed it, then the usual undo window ran. Recorded on the
|
|
2434
|
+
* `gate.decided` audit line and {@link DecidedGate.input}; it grants nothing a typed answer does not.
|
|
2435
|
+
*/
|
|
2436
|
+
input?: 'voice';
|
|
2437
|
+
/**
|
|
2438
|
+
* (api-types 0.160.0, program DES-LEARN §3.1) On a steering-author propose gate: the drafted rule ids
|
|
2439
|
+
* (`SteeringDraftResponse.rules[].id`) the person keeps. Only those land; the rest are declined
|
|
2440
|
+
* (`SteeringLandingResult.declinedIds`, audited `governance.steering.declined`). Absent = every drafted
|
|
2441
|
+
* rule lands. With a plain approve only (400 otherwise); **409** `no_draft` on a gate with no readable
|
|
2442
|
+
* draft, **409** `draft_changed` when an id is not in the draft as it reads now (the gate stays open).
|
|
2443
|
+
*/
|
|
2444
|
+
keepRules?: string[];
|
|
1969
2445
|
}
|
|
1970
2446
|
|
|
1971
2447
|
/**
|
|
@@ -2041,6 +2517,8 @@ export interface CoreEvent {
|
|
|
2041
2517
|
seat?: string;
|
|
2042
2518
|
/** `elicitationCreated`: an ordered set of valid responses; `null` / absent = free-text. */
|
|
2043
2519
|
options?: string[] | null;
|
|
2520
|
+
/** `elicitationCreated` (api-types 0.158.0): a multi-select's bounds (`propType: "array"`). Absent otherwise. */
|
|
2521
|
+
multi?: ElicitationMulti;
|
|
2044
2522
|
/**
|
|
2045
2523
|
* `elicitationCreated` (C3; wicked-core-ts >= 0.7.35, api-types 0.83.0): the index into `options`
|
|
2046
2524
|
* of the option the PRODUCER of the options recommends (the field's JSON Schema `default`).
|
|
@@ -2065,6 +2543,13 @@ export interface CoreEvent {
|
|
|
2065
2543
|
/** `awaitingHuman{gateKind: 'consent'}` (core#820): why no write targets are listed (no dry run
|
|
2066
2544
|
* ran before the gate, or it printed no plan); the gate is then a plain approve / reject. */
|
|
2067
2545
|
writeTargetsMissing?: string;
|
|
2546
|
+
/**
|
|
2547
|
+
* `awaitingHuman{gateKind: 'repeat'}` (api-types 0.163.0, domain-graph-3): a loop step's ask —
|
|
2548
|
+
* its command's progress line ("Mapping wicked-crew · 3% → 23% · target 80% · page 21 · budget
|
|
2549
|
+
* reached …"). The ask's answers ride `choices` (`consent:<id>`…, `reject` = stop, the run ends
|
|
2550
|
+
* and what it did is kept), `choiceLabels` and `recommended`, as on a consent gate.
|
|
2551
|
+
*/
|
|
2552
|
+
repeatLine?: string;
|
|
2068
2553
|
/** PTY terminal frames (`terminalOpened`/`terminalOutput`/`terminalExited`): the terminal id. */
|
|
2069
2554
|
id?: string;
|
|
2070
2555
|
/**
|
|
@@ -2472,6 +2957,24 @@ export interface CliUsageEvent {
|
|
|
2472
2957
|
costUsd: number | null;
|
|
2473
2958
|
}
|
|
2474
2959
|
|
|
2960
|
+
/**
|
|
2961
|
+
* (0.155.0) `/ws` frame (and logged with the run): a working seat's running token TOTAL for one unit attempt, live from
|
|
2962
|
+
* its own stream (wicked-core: claude per assistant message, pi per `message_end`, codex per `turn.completed`). Fresh +
|
|
2963
|
+
* cache input, as {@link CliUsageEvent} counts it; sent when it changed, at most one per 3 s. `costUsd` only where the
|
|
2964
|
+
* seat's stream states one (pi), else `null`. The attempt's `cliUsage` at its end stays the record.
|
|
2965
|
+
*/
|
|
2966
|
+
export interface UsageProgressEvent {
|
|
2967
|
+
type: 'usageProgress';
|
|
2968
|
+
session: string;
|
|
2969
|
+
ord: number;
|
|
2970
|
+
attempt: number;
|
|
2971
|
+
/** Unix ms. */
|
|
2972
|
+
at: number;
|
|
2973
|
+
inputTokens: number;
|
|
2974
|
+
outputTokens: number;
|
|
2975
|
+
costUsd: number | null;
|
|
2976
|
+
}
|
|
2977
|
+
|
|
2475
2978
|
/** §3 B4 — the data files a unit's CLI touched. */
|
|
2476
2979
|
export interface DataUsedEvent {
|
|
2477
2980
|
type: 'dataUsed';
|
|
@@ -3639,6 +4142,23 @@ export interface WorkflowSelectedEvent {
|
|
|
3639
4142
|
unitCount: number;
|
|
3640
4143
|
}
|
|
3641
4144
|
|
|
4145
|
+
/**
|
|
4146
|
+
* (api-types 0.163.0, domain-graph-3) A loop step sent the run back for another pass: every unit
|
|
4147
|
+
* from `fromOrd` through `ord` was re-armed at a fresh attempt and the run goes on from `fromOrd`.
|
|
4148
|
+
* `pass` counts the passes the loop has sent back (1 after the first); `line` is the step's own
|
|
4149
|
+
* progress line ("Mapping wicked-crew · 3% → 12% → 19% · target 80% · page 4 · about 2 h left"),
|
|
4150
|
+
* possibly empty. One per loop rewind: a page that reaches the target, or stops at a budget ask
|
|
4151
|
+
* (whose `awaitingHuman.repeatLine` carries the line), emits none.
|
|
4152
|
+
*/
|
|
4153
|
+
export type StepRepeatedEvent = {
|
|
4154
|
+
type: 'stepRepeated';
|
|
4155
|
+
session: string;
|
|
4156
|
+
ord: number;
|
|
4157
|
+
fromOrd: number;
|
|
4158
|
+
pass: number;
|
|
4159
|
+
line: string;
|
|
4160
|
+
};
|
|
4161
|
+
|
|
3642
4162
|
/** P2 — a human approved a gate with an amendment text that was injected into the unit's description
|
|
3643
4163
|
* before re-dispatch. Fires after the amendment is persisted, before Resumed. Only emitted when
|
|
3644
4164
|
* the amendment text is non-empty. The canonical record for the HITL paper trail. */
|
|
@@ -3823,6 +4343,28 @@ export interface WorkerMessageInjectedEvent {
|
|
|
3823
4343
|
message: string;
|
|
3824
4344
|
/** `"all"` or the cli_key that was targeted. */
|
|
3825
4345
|
target: string;
|
|
4346
|
+
/** (0.161.0, DES-VOICE) Stamped by crew when the note was sent with {@link InjectMessageRequest.input} `voice`
|
|
4347
|
+
* (on `/ws` and `GET /runs/:id/events`; also on the `workerMessageQueued` frame). Crew remembers spoken notes in
|
|
4348
|
+
* memory, so one sent before a daemon restart reads as typed here; its `run.injected` audit line keeps it. */
|
|
4349
|
+
input?: 'voice';
|
|
4350
|
+
}
|
|
4351
|
+
|
|
4352
|
+
/** `POST /runs/:id/cancel` (0.161.0): the body is optional; a bodiless cancel is unchanged. */
|
|
4353
|
+
export interface CancelRunRequest {
|
|
4354
|
+
/** Why the person stopped it (≤ 2000 characters), said or typed: kept on the `run.cancelled` audit line. */
|
|
4355
|
+
reason?: string;
|
|
4356
|
+
/** (DES-VOICE) The person said the stop and confirmed it on screen. A person's only (403 otherwise). */
|
|
4357
|
+
input?: 'voice';
|
|
4358
|
+
}
|
|
4359
|
+
|
|
4360
|
+
/** `POST /runs/:id/inject`: an operator note into the run's active worker(s). */
|
|
4361
|
+
export interface InjectMessageRequest {
|
|
4362
|
+
message: string;
|
|
4363
|
+
/** `"all"` (the default) or a CLI key. */
|
|
4364
|
+
target?: string;
|
|
4365
|
+
/** (0.161.0, DES-VOICE) The person said this note and confirmed it on screen. A person's only (403 for a worker or
|
|
4366
|
+
* plugin bearer); kept on the `run.injected` audit line and stamped on the note's frames. Grants nothing. */
|
|
4367
|
+
input?: 'voice';
|
|
3826
4368
|
}
|
|
3827
4369
|
|
|
3828
4370
|
/** A unit was stopped and re-dispatched to a different CLI (or re-routed via council). */
|
|
@@ -4084,6 +4626,91 @@ export interface SteeringLandingResult {
|
|
|
4084
4626
|
alreadyLanded?: boolean;
|
|
4085
4627
|
/** Present iff `outcome: "failed"` — the loud, operator-readable reason. */
|
|
4086
4628
|
error?: string;
|
|
4629
|
+
/** (api-types 0.160.0) The drafted rules the approve's `keepRules` left out: never landed. */
|
|
4630
|
+
declinedIds?: string[];
|
|
4631
|
+
}
|
|
4632
|
+
|
|
4633
|
+
/**
|
|
4634
|
+
* `GET /governance/steering/author/:runId/draft` (api-types 0.160.0, program DES-LEARN §3.1): a
|
|
4635
|
+
* steering-author run's drafted rules, normalized exactly as the landing lands them. `ready` is true once
|
|
4636
|
+
* the propose step has run and the run waits at a gate; until then `rules` may be empty. 404 for an
|
|
4637
|
+
* unknown run or one that is not steering-author (`code: "not_steering_author"`).
|
|
4638
|
+
*/
|
|
4639
|
+
export interface SteeringDraftResponse {
|
|
4640
|
+
runId: string;
|
|
4641
|
+
ready: boolean;
|
|
4642
|
+
rules: ConformanceRule[];
|
|
4643
|
+
source?: SteeringProposalSource;
|
|
4644
|
+
}
|
|
4645
|
+
|
|
4646
|
+
// ── Personality (api-types 0.160.0, program DES-LEARN §3.3) ──────────────────────────────────────
|
|
4647
|
+
|
|
4648
|
+
/** 0 = the left word, 2 = the right word: length short..thorough, warmth plain..warm, pushback goes
|
|
4649
|
+
* along..challenges, initiative asks first..just starts. */
|
|
4650
|
+
export type PersonaDial = 0 | 1 | 2;
|
|
4651
|
+
export type PersonaHabit = 'says-unchecked' | 'tables' | 'cites' | 'names';
|
|
4652
|
+
|
|
4653
|
+
/** `PUT /persona`'s `persona`: how the orchestrator talks. Tone only: never read by a gate, review, QE or rule. */
|
|
4654
|
+
export interface PersonaInput {
|
|
4655
|
+
/** 1..40 characters. */
|
|
4656
|
+
name: string;
|
|
4657
|
+
/** `#rrggbb`. */
|
|
4658
|
+
colour: string;
|
|
4659
|
+
dials: { length: PersonaDial; warmth: PersonaDial; pushback: PersonaDial; initiative: PersonaDial };
|
|
4660
|
+
habits: PersonaHabit[];
|
|
4661
|
+
/** At most 500 characters, about tone. */
|
|
4662
|
+
notes?: string;
|
|
4663
|
+
}
|
|
4664
|
+
|
|
4665
|
+
export interface Persona extends PersonaInput {
|
|
4666
|
+
/** 1 on the first save of a scope, one more on each save. */
|
|
4667
|
+
version: number;
|
|
4668
|
+
/** Unix ms. */
|
|
4669
|
+
updatedAt: number;
|
|
4670
|
+
}
|
|
4671
|
+
|
|
4672
|
+
/** `user`, or `project:<id>` for one project's override. */
|
|
4673
|
+
export type PersonaScope = 'user' | `project:${string}`;
|
|
4674
|
+
|
|
4675
|
+
/** `GET /persona`: the person's own, every project override, and the voice block each adds to what a chat
|
|
4676
|
+
* seat is told (the project's override, else the person's, rides every chat's scope statement). */
|
|
4677
|
+
export interface PersonaResponse {
|
|
4678
|
+
user: Persona | null;
|
|
4679
|
+
projects: Record<string, Persona>;
|
|
4680
|
+
voice: { user: string | null; projects: Record<string, string> };
|
|
4681
|
+
}
|
|
4682
|
+
|
|
4683
|
+
/** `PUT /persona` body: a person only (403 otherwise); 404 for an unknown project. */
|
|
4684
|
+
export interface PersonaPutBody {
|
|
4685
|
+
scope: PersonaScope;
|
|
4686
|
+
persona: PersonaInput;
|
|
4687
|
+
}
|
|
4688
|
+
|
|
4689
|
+
export interface PersonaSaved {
|
|
4690
|
+
scope: PersonaScope;
|
|
4691
|
+
persona: Persona;
|
|
4692
|
+
voice: string;
|
|
4693
|
+
}
|
|
4694
|
+
|
|
4695
|
+
/** `DELETE /persona?scope=project:<id>`: removes a project's override (a person only). */
|
|
4696
|
+
export interface PersonaRemoved {
|
|
4697
|
+
removed: true;
|
|
4698
|
+
scope: PersonaScope;
|
|
4699
|
+
}
|
|
4700
|
+
|
|
4701
|
+
// ── First run (api-types 0.160.0, program DES-LEARN §4) ──────────────────────────────────────────
|
|
4702
|
+
|
|
4703
|
+
/** `GET /setup/known` (operator trust): what studio shows before it asks. A fact that cannot be read is
|
|
4704
|
+
* `null` or empty, never guessed. */
|
|
4705
|
+
export interface SetupKnown {
|
|
4706
|
+
/** The global git identity; null when neither name nor email is set. */
|
|
4707
|
+
git: { name: string | null; email: string | null } | null;
|
|
4708
|
+
/** Tracked source files by language across the registered repositories (`git ls-files`), at most 6. */
|
|
4709
|
+
languages: Array<{ name: string; files: number; share: number }>;
|
|
4710
|
+
filesCounted: number;
|
|
4711
|
+
/** Git checkouts one level under the home's code folders and the registered repositories' folders,
|
|
4712
|
+
* not registered yet (at most 24). `path` is absolute: register with `POST /repos {name, rootPath}`. */
|
|
4713
|
+
nearby: Array<{ name: string; path: string }>;
|
|
4087
4714
|
}
|
|
4088
4715
|
|
|
4089
4716
|
// ── Skills — the daemon-owned garden plugin root, published as immutable snapshots (api-types 0.28.0) ──
|
|
@@ -5143,6 +5770,15 @@ export interface GovernanceClaim {
|
|
|
5143
5770
|
/** The launch-run request body (`POST /runs`). */
|
|
5144
5771
|
export interface LaunchRunBody {
|
|
5145
5772
|
problem: string;
|
|
5773
|
+
/**
|
|
5774
|
+
* (api-types 0.149.0) Run in POWER MODE: one orchestrator session (the `primary` seat, Claude Code by default)
|
|
5775
|
+
* builds the change in many turns, rigor is sized by an intake QE plan and applied at hand-off, and the only human
|
|
5776
|
+
* gate is deliver (plus what policy requires). ABSENT: the daemon's Settings default
|
|
5777
|
+
* ({@link SystemSettings.powerModeDefault}, on when unset). `false` launches phased. Ignored (phased) when the
|
|
5778
|
+
* engine lacks it (`capabilities.powerMode` false). A power launch runs without plan approval (`humanConfirm`
|
|
5779
|
+
* is forced to `none`); a high-risk plan still holds at its gate (policy).
|
|
5780
|
+
*/
|
|
5781
|
+
power?: boolean | undefined;
|
|
5146
5782
|
sessionId?: string;
|
|
5147
5783
|
clisJson?: string;
|
|
5148
5784
|
/**
|
|
@@ -5382,6 +6018,10 @@ export interface LaunchRunResponse {
|
|
|
5382
6018
|
/** (crew ≥ 0.9.0; wicked-core#850) PRESENT when a full-assurance launch's usable seats are all one
|
|
5383
6019
|
* CLI: the run will wait at a gate for a distinct seat. ABSENT otherwise. */
|
|
5384
6020
|
assuranceNotice?: LaunchAssuranceNotice;
|
|
6021
|
+
/** (api-types 0.149.0) PRESENT (`true`) when the run launched in power mode; absent means phased. */
|
|
6022
|
+
power?: boolean | undefined;
|
|
6023
|
+
/** (api-types 0.149.0) Power mode was wanted (the launch or the setting) but the run is phased: why, in one line. */
|
|
6024
|
+
powerNotice?: string | undefined;
|
|
5385
6025
|
}
|
|
5386
6026
|
|
|
5387
6027
|
/**
|
|
@@ -5814,6 +6454,7 @@ export interface RepoGraphResponse {
|
|
|
5814
6454
|
finding?: RepoFinding;
|
|
5815
6455
|
}
|
|
5816
6456
|
|
|
6457
|
+
/** One row of `GET /repos/:id/git-history` (`?limit=` 1..500, default 20; newest first). */
|
|
5817
6458
|
export interface GitCommit {
|
|
5818
6459
|
sha: string;
|
|
5819
6460
|
shortSha: string;
|
|
@@ -5832,6 +6473,11 @@ export interface GitContributor {
|
|
|
5832
6473
|
export interface SystemSettings {
|
|
5833
6474
|
/** Max nodes returned by wicked-estate graph-view (default 150). */
|
|
5834
6475
|
graphNodeLimit: number;
|
|
6476
|
+
/**
|
|
6477
|
+
* (api-types 0.149.0) "Power mode for new jobs": the default of `LaunchRunBody.power` when a launch omits it.
|
|
6478
|
+
* ABSENT = `true` (the shipped default is on). Human actors only.
|
|
6479
|
+
*/
|
|
6480
|
+
powerModeDefault?: boolean | undefined;
|
|
5835
6481
|
/**
|
|
5836
6482
|
* The watch registry's operator settings (TR-W5a, api-types 0.73.0): only `enabled` and
|
|
5837
6483
|
* `threshold` of a shipped entry, and the LLM lane switch. A `watch` patch needs a human actor
|
|
@@ -5861,6 +6507,29 @@ export interface SystemSettings {
|
|
|
5861
6507
|
* Exported as `WICKED_COUNCIL_SPAWN_STAGGER_MS`, read per council. Absent = the default.
|
|
5862
6508
|
*/
|
|
5863
6509
|
councilSpawnStaggerMs?: number;
|
|
6510
|
+
/**
|
|
6511
|
+
* (api-types 0.159.0, operator ruling 2026-10-31) The requirements graph's minimum coverage:
|
|
6512
|
+
* `minCoveragePct`, a whole percentage 1..100, default 80. A repository's requirements graph is
|
|
6513
|
+
* built, and shown labelled with its share, once REAL requirements (0.164.0: placeholders never
|
|
6514
|
+
* count) reach this share of its behaviour-bearing product code; below it the
|
|
6515
|
+
* `domain-extraction` run says "N% real requirements, minimum M%" and keeps the mapping for the
|
|
6516
|
+
* next run. The daemon exports it as
|
|
6517
|
+
* `WICKED_REQUIREMENTS_MIN_COVERAGE_PCT` at boot and on every change. Absent = the default.
|
|
6518
|
+
*/
|
|
6519
|
+
requirementsGraph?: {
|
|
6520
|
+
minCoveragePct?: number;
|
|
6521
|
+
/**
|
|
6522
|
+
* (api-types 0.163.0, domain-graph-3) A domain-extraction run maps page after page until the
|
|
6523
|
+
* target; its budget per grant — `maxPages` (1..200, default 20) or `maxMinutes` (1..1440,
|
|
6524
|
+
* default 240), whichever is spent first — ends in an ask: map more, lower the target for the
|
|
6525
|
+
* repository, or stop. `pageSize` (50..2000, default 500) is how many behaviours one page
|
|
6526
|
+
* maps. Exported as `WICKED_DOMAIN_MAX_PAGES` / `WICKED_DOMAIN_MAX_MINUTES` /
|
|
6527
|
+
* `WICKED_DOMAIN_PAGE_SIZE`. Absent = the defaults.
|
|
6528
|
+
*/
|
|
6529
|
+
maxPages?: number;
|
|
6530
|
+
maxMinutes?: number;
|
|
6531
|
+
pageSize?: number;
|
|
6532
|
+
};
|
|
5864
6533
|
/*
|
|
5865
6534
|
* There is NO skills setting (skills keystone, api-types 0.28.0). The daemon-owned skills root is
|
|
5866
6535
|
* `<state home>/skills` — the directory holding `manifest.json`, `baseline/<hash>/`, `effective/`,
|
|
@@ -6054,6 +6723,74 @@ export interface SettingsResponse {
|
|
|
6054
6723
|
}
|
|
6055
6724
|
|
|
6056
6725
|
// ── Requirements management (server-side search + overrides; crew api/requirements.ts) ──
|
|
6726
|
+
/**
|
|
6727
|
+
* (0.159.0, operator ruling 2026-10-31 "validation by duplication") How many INDEPENDENT sources in
|
|
6728
|
+
* the repository support a requirement beyond the extractor's own statement, as `wicked-core
|
|
6729
|
+
* domain-graph` computed it: distinct callers (`callSites`), tests, docs that name it, and extractor
|
|
6730
|
+
* seats beyond the first. `validated` at 2 or more; otherwise `unconfirmed`, and `why` says what is
|
|
6731
|
+
* missing — show `why.text` on the item. `why.code` is one of `unindexed_file` (a file the code index
|
|
6732
|
+
* skipped names it, so its callers there are not counted), `dead_code`, `config_only`,
|
|
6733
|
+
* `single_caller`, `test_only`, `doc_only`, `extractors_only`.
|
|
6734
|
+
*/
|
|
6735
|
+
export interface RequirementCorroboration {
|
|
6736
|
+
status: 'validated' | 'unconfirmed';
|
|
6737
|
+
sources: number;
|
|
6738
|
+
callSites: number;
|
|
6739
|
+
tests: number;
|
|
6740
|
+
docs: number;
|
|
6741
|
+
extraExtractors: number;
|
|
6742
|
+
why?: { code: string; text: string };
|
|
6743
|
+
}
|
|
6744
|
+
|
|
6745
|
+
/**
|
|
6746
|
+
* (0.164.0, operator decision 2026-11-01, wicked-core#1233) How much of a repository's product code
|
|
6747
|
+
* is REAL requirements, and the minimum the graph is held to (`SystemSettings.requirementsGraph
|
|
6748
|
+
* .minCoveragePct`): label it "23% real requirements · 4397 placeholders · minimum 80%".
|
|
6749
|
+
*
|
|
6750
|
+
* - `realPct` is the one number the minimum is checked against: `floor(real * 100 /
|
|
6751
|
+
* behaviorBearing)`, floored so it never reads above the minimum it was compared to; 100 when
|
|
6752
|
+
* `behaviorBearing` is 0 (nothing in product code to map). `real + placeholders + unmapped ===
|
|
6753
|
+
* behaviorBearing`; a label that breaks either is not sent.
|
|
6754
|
+
* - `real`: behaviours resolved to a stated, sourced business rule.
|
|
6755
|
+
* - `placeholders`: behaviours carrying only a risk-flagged placeholder (an empty statement, a rule
|
|
6756
|
+
* under the confidence threshold, one written unconfirmed). Shown in the graph as unconfirmed,
|
|
6757
|
+
* NEVER counted toward the minimum.
|
|
6758
|
+
* - `unmapped`: behaviours with nothing recorded yet.
|
|
6759
|
+
* - `behaviorBearing`: the denominator, product code only. `notProduct` counts the behaviour-kind
|
|
6760
|
+
* nodes left out because their file is a test, data, manifest or document file.
|
|
6761
|
+
*
|
|
6762
|
+
* Replaces 0.159.0's `mappedPct` / `mapped` / `resolved`, which counted placeholders as mapped (a
|
|
6763
|
+
* repository with 3 real requirements and 117 placeholders read "100% mapped").
|
|
6764
|
+
*/
|
|
6765
|
+
export interface RequirementsCoverage {
|
|
6766
|
+
realPct: number;
|
|
6767
|
+
minPct: number;
|
|
6768
|
+
behaviorBearing: number;
|
|
6769
|
+
real: number;
|
|
6770
|
+
placeholders: number;
|
|
6771
|
+
unmapped: number;
|
|
6772
|
+
notProduct: number;
|
|
6773
|
+
}
|
|
6774
|
+
|
|
6775
|
+
/**
|
|
6776
|
+
* (0.165.0) The graph a requirements page lists, as it was built. When `behind`, the header (`coverage`, the store
|
|
6777
|
+
* now) does not count what the list holds: say so. When this `coverage.real` is below the header's: "2,202 real
|
|
6778
|
+
* requirements mapped since the last graph build; build the graph to list them". With `coverage` null: "built
|
|
6779
|
+
* before real requirements were counted; build the graph to list the N real requirements mapped now". Otherwise
|
|
6780
|
+
* (only another count moved, or `real` fell): "the repository changed since this graph was built".
|
|
6781
|
+
*/
|
|
6782
|
+
export interface RequirementsGraphBuild {
|
|
6783
|
+
/** The build's generation in the store (1 = the first build; 0 = a graph persisted before the engine kept a
|
|
6784
|
+
* build record). */
|
|
6785
|
+
generation: number;
|
|
6786
|
+
/** The label the build persisted; `null` when it carried none or an older engine's `mapped_pct` label. */
|
|
6787
|
+
coverage: RequirementsCoverage | null;
|
|
6788
|
+
/** True when any count of the build's label differs from the page's `coverage` (or the label is null), or
|
|
6789
|
+
* (0.167.0) when the engine judged every listed row and the counted rows' verdicts are not the header's real and
|
|
6790
|
+
* placeholders. False says the counts agree, not that every statement is unchanged. */
|
|
6791
|
+
behind: boolean;
|
|
6792
|
+
}
|
|
6793
|
+
|
|
6057
6794
|
export interface RequirementSummary {
|
|
6058
6795
|
key: string;
|
|
6059
6796
|
domain: string;
|
|
@@ -6065,6 +6802,20 @@ export interface RequirementSummary {
|
|
|
6065
6802
|
risk: boolean;
|
|
6066
6803
|
riskSource: 'operator' | 'data' | null;
|
|
6067
6804
|
edited: boolean;
|
|
6805
|
+
/** (0.159.0) Validated or unconfirmed (with why). `null` on a graph built before the field;
|
|
6806
|
+
* ABSENT from an older daemon. */
|
|
6807
|
+
corroboration?: RequirementCorroboration | null;
|
|
6808
|
+
/** (0.166.0) The engine would not count it a real requirement (a validated requirement, or a business rule at or
|
|
6809
|
+
* above the resolve threshold, 0.75): a placeholder, unconfirmed whatever its corroboration says. (0.167.0) The
|
|
6810
|
+
* engine's own verdict when it gives one, else read off the document. ABSENT from an older daemon. */
|
|
6811
|
+
placeholder?: boolean;
|
|
6812
|
+
/** (0.167.0) The coverage share does not count this row, and why: its unit is not a behaviour (`structural`, a
|
|
6813
|
+
* TypeScript shape or signature), is outside product code (`not_product`), or is no longer indexed (`unindexed`).
|
|
6814
|
+
* Such a row is neither a real requirement nor a placeholder of the header's (its `placeholder` says only whether
|
|
6815
|
+
* a rule was stated there), sorts after them, and carries
|
|
6816
|
+
* `corroboration: null` (a type has no callers; "dead code" would be wrong). `null` when it counts or the engine
|
|
6817
|
+
* does not say; ABSENT from an older daemon. */
|
|
6818
|
+
uncounted?: 'structural' | 'not_product' | 'unindexed' | null;
|
|
6068
6819
|
}
|
|
6069
6820
|
|
|
6070
6821
|
export interface RequirementDetail extends RequirementSummary {
|
|
@@ -6090,12 +6841,55 @@ export interface RequirementsPage {
|
|
|
6090
6841
|
source: 'store' | 'artifact';
|
|
6091
6842
|
/**
|
|
6092
6843
|
* Keys in `requirements_overrides.json` that matched NO requirement in the corpus. Operator
|
|
6093
|
-
* edits are keyed by
|
|
6094
|
-
*
|
|
6095
|
-
*
|
|
6096
|
-
*
|
|
6844
|
+
* edits are keyed by `domain::reqId` whatever the source (older daemons serving `'store'` keyed
|
|
6845
|
+
* them by SymbolId). The engine keeps a requirement's id across builds, so a key stops matching
|
|
6846
|
+
* when its requirement is retired or its domain regrouped. Non-zero means edits exist that no
|
|
6847
|
+
* row is showing — re-apply or delete the stale keys.
|
|
6097
6848
|
*/
|
|
6098
6849
|
orphanedOverrides?: number;
|
|
6850
|
+
/** (0.159.0; real requirements since 0.164.0) The graph's coverage label; `null` when absent, an
|
|
6851
|
+
* older engine's `mapped_pct` label, or one its counts do not support; ABSENT from an older
|
|
6852
|
+
* daemon. */
|
|
6853
|
+
coverage?: RequirementsCoverage | null;
|
|
6854
|
+
/**
|
|
6855
|
+
* (0.165.0) Which build the rows are. The list is the last graph BUILD; `coverage` counts the store NOW,
|
|
6856
|
+
* which moves on when a run maps more without building (stopped at its repeat ask, or below the minimum,
|
|
6857
|
+
* where the build refuses). `null` when the engine does not say; ABSENT from an older daemon.
|
|
6858
|
+
*/
|
|
6859
|
+
graphBuild?: RequirementsGraphBuild | null;
|
|
6860
|
+
/** (0.159.0) How many requirements of the whole corpus are validated / unconfirmed. (0.167.0) Rows the share does
|
|
6861
|
+
* not count are in neither. */
|
|
6862
|
+
corroboration?: { validated: number; unconfirmed: number };
|
|
6863
|
+
/**
|
|
6864
|
+
* (0.167.0) Rows of the whole corpus the coverage share does not count (items with `uncounted`), split stated /
|
|
6865
|
+
* placeholder: why the list holds more rows than the header. When this is not `null` and `graphBuild.behind` is
|
|
6866
|
+
* false, the rows that are neither placeholders nor uncounted number exactly `coverage.real`. `null` when the engine
|
|
6867
|
+
* did not judge every row (an older engine, a build before it recorded each row's unit, a malformed verdict): those
|
|
6868
|
+
* rows are read off the document, and there is no such claim. ABSENT from an older daemon.
|
|
6869
|
+
*/
|
|
6870
|
+
uncounted?: { stated: number; placeholders: number } | null;
|
|
6871
|
+
/** (0.167.0) How many rows of the whole corpus are in each category, so a client can leave out an empty filter.
|
|
6872
|
+
* ABSENT from an older daemon. */
|
|
6873
|
+
categories?: { functional: number; configData: number };
|
|
6874
|
+
}
|
|
6875
|
+
|
|
6876
|
+
/**
|
|
6877
|
+
* `GET /repos/:id/requirements` 404 when the repository's `requirements_graph.json` has not been
|
|
6878
|
+
* generated (0.154.0). A state, not a refusal: `code` is the discriminator a client matches on, and
|
|
6879
|
+
* `workflow` names the preset that generates the graph (its last step runs `wicked-core domain-graph`).
|
|
6880
|
+
* Any other 404 on the route (an unknown repo) carries no `code`.
|
|
6881
|
+
*/
|
|
6882
|
+
export interface RequirementsNotGenerated {
|
|
6883
|
+
error: string;
|
|
6884
|
+
code: 'notGenerated';
|
|
6885
|
+
workflow: string;
|
|
6886
|
+
/**
|
|
6887
|
+
* (api-types 0.163.0, domain-graph-3; real requirements since 0.164.0) How far the repository
|
|
6888
|
+
* is, against its target ("23% real requirements · 4397 placeholders · target 80%"): present
|
|
6889
|
+
* when the repository has a store to count.
|
|
6890
|
+
* `minPct` is the target in force (the repository's own when lowered, else the daemon's).
|
|
6891
|
+
*/
|
|
6892
|
+
coverage?: RequirementsCoverage;
|
|
6099
6893
|
}
|
|
6100
6894
|
|
|
6101
6895
|
export interface RequirementPatch {
|
|
@@ -6153,14 +6947,130 @@ export interface ElicitationInfo {
|
|
|
6153
6947
|
ord?: number;
|
|
6154
6948
|
attempt?: number;
|
|
6155
6949
|
seat?: string;
|
|
6950
|
+
/**
|
|
6951
|
+
* (api-types 0.158.0, guided asks) The person may pick SEVERAL of `options`: at least `min`, at most `max`
|
|
6952
|
+
* (both always set, `1 <= min <= max <= options.length`). Answer it with `content: {values}`; the engine records
|
|
6953
|
+
* the picks as a JSON array in `options` order. ABSENT on a single-choice or free-text question and on an older
|
|
6954
|
+
* daemon.
|
|
6955
|
+
*/
|
|
6956
|
+
multi?: ElicitationMulti;
|
|
6156
6957
|
receivedAt: string;
|
|
6157
6958
|
}
|
|
6158
6959
|
|
|
6159
|
-
/**
|
|
6960
|
+
/** (api-types 0.158.0) How many of a multi-select elicitation's options an answer picks. */
|
|
6961
|
+
export interface ElicitationMulti {
|
|
6962
|
+
min: number;
|
|
6963
|
+
max: number;
|
|
6964
|
+
}
|
|
6965
|
+
|
|
6966
|
+
/**
|
|
6967
|
+
* `POST /runs/:id/elicitation` body. `content` is required for accept, absent otherwise: `{response}` answers a
|
|
6968
|
+
* free-text or single-choice question (one of `options`); `{values}` (api-types 0.158.0) answers a multi-select one
|
|
6969
|
+
* ({@link ElicitationInfo.multi}): distinct entries of `options`, `min..=max` of them. Crew answers 400 to `values` on
|
|
6970
|
+
* a question that is not multi-select, and to `response` on one that is.
|
|
6971
|
+
*/
|
|
6160
6972
|
export interface ElicitationResponse {
|
|
6161
6973
|
elicitationId: string;
|
|
6162
6974
|
action: 'accept' | 'decline' | 'cancel';
|
|
6163
|
-
content?: { response: string };
|
|
6975
|
+
content?: { response: string } | { values: string[] };
|
|
6976
|
+
}
|
|
6977
|
+
|
|
6978
|
+
// ── Guided asks (api-types 0.158.0; design DES-GUIDED-CHAT) ─────────────────────────────────────────────────────
|
|
6979
|
+
//
|
|
6980
|
+
// ONE typed shape for every question a person answers inline: an engine gate, a seat's or MCP server's elicitation,
|
|
6981
|
+
// a power-mode pause, a plugin's proposal, a studio setup step. It is a RENDERING contract: the wire shapes that
|
|
6982
|
+
// exist stay as they are and map onto it (GateInfo.choices + recommended + gateKind → `choose`; ElicitationInfo
|
|
6983
|
+
// options/multi → `choose` / `pick` / `text`), and every answer still goes through its host's own route
|
|
6984
|
+
// (`POST /runs/:id/gate` with a GateDecision, `POST /runs/:id/elicitation`, …). Governance is the host's: an ask
|
|
6985
|
+
// never widens who may answer, and a gate's ask is always `answeredBy: 'person'`.
|
|
6986
|
+
|
|
6987
|
+
/** The six ways a person answers. */
|
|
6988
|
+
export type AskKind =
|
|
6989
|
+
/** Yes / no (two options; picking one is the answer). */
|
|
6990
|
+
| 'confirm'
|
|
6991
|
+
/** Choose one of 2..n options. */
|
|
6992
|
+
| 'choose'
|
|
6993
|
+
/** Pick several (`multi` bounds). */
|
|
6994
|
+
| 'pick'
|
|
6995
|
+
/** Short text. */
|
|
6996
|
+
| 'text'
|
|
6997
|
+
/** A point on a scale (named steps, or a number range). */
|
|
6998
|
+
| 'scale'
|
|
6999
|
+
/** Confirm, with a required reason (a danger move: stop, reject, skip QE, override). */
|
|
7000
|
+
| 'confirm_reason';
|
|
7001
|
+
|
|
7002
|
+
/** Which route answers the ask. */
|
|
7003
|
+
export type AskHost = 'gate' | 'elicitation' | 'chat' | 'learn' | 'plugin' | 'power';
|
|
7004
|
+
|
|
7005
|
+
/** One option of a `confirm` / `choose` / `pick` / `confirm_reason` ask. */
|
|
7006
|
+
export interface AskOption {
|
|
7007
|
+
/** Stable within the ask. */
|
|
7008
|
+
id: string;
|
|
7009
|
+
/** What the person reads (and the voice vocabulary). */
|
|
7010
|
+
label: string;
|
|
7011
|
+
/** One line under the label. */
|
|
7012
|
+
sub?: string;
|
|
7013
|
+
/** What happens if this option is taken, shown while it is hovered or selected ("If you choose this: …"). */
|
|
7014
|
+
consequence?: string;
|
|
7015
|
+
/** The wire answer: a gate action token, an elicitation option, a pause decision. */
|
|
7016
|
+
token: string;
|
|
7017
|
+
tone?: 'primary' | 'neutral' | 'danger';
|
|
7018
|
+
/** The engine's (or producer's) recommendation: marked, and preselected unless the host says otherwise. */
|
|
7019
|
+
recommended?: boolean;
|
|
7020
|
+
/** Taking it asks for a reason first (kept with the record). */
|
|
7021
|
+
needsReason?: boolean;
|
|
7022
|
+
/** Shown but not choosable; the string says why ("Frozen: nothing merges there"). */
|
|
7023
|
+
disabled?: string;
|
|
7024
|
+
/** A small tag ("default", "current release"). */
|
|
7025
|
+
meta?: string;
|
|
7026
|
+
}
|
|
7027
|
+
|
|
7028
|
+
/** A named-step scale, or a number range. */
|
|
7029
|
+
export type AskScale =
|
|
7030
|
+
| { steps: string[]; consequences?: string[] }
|
|
7031
|
+
| { min: number; max: number; step: number; labels: [string, string] };
|
|
7032
|
+
|
|
7033
|
+
export interface Ask {
|
|
7034
|
+
/** Gate: `<runId>:<ord>`; elicitation: its `elicitationId`; otherwise the host's own id. */
|
|
7035
|
+
id: string;
|
|
7036
|
+
host: AskHost;
|
|
7037
|
+
/** Who asks, in words ("Codex asks", "The engine asks"). */
|
|
7038
|
+
from: { kind: 'engine' | 'seat' | 'plugin' | 'studio'; id: string; label: string };
|
|
7039
|
+
/** One sentence, a question. */
|
|
7040
|
+
prompt: string;
|
|
7041
|
+
/** One line under the question. */
|
|
7042
|
+
detail?: string;
|
|
7043
|
+
kind: AskKind;
|
|
7044
|
+
options?: AskOption[];
|
|
7045
|
+
/** `pick`: how many (defaults: 1 and every option). */
|
|
7046
|
+
multi?: { min?: number; max?: number };
|
|
7047
|
+
/** Preselected: an option id (`choose` / `confirm`), option ids (`pick`), a step index or value (`scale`). */
|
|
7048
|
+
default?: string | string[] | number;
|
|
7049
|
+
scale?: AskScale;
|
|
7050
|
+
text?: { placeholder?: string; maxChars?: number; optional?: boolean };
|
|
7051
|
+
/** A follow-up shown in the same card once the first part is answered (pick the steps, then say what). */
|
|
7052
|
+
then?: Ask;
|
|
7053
|
+
/** A gate is always `'person'`. */
|
|
7054
|
+
answeredBy: 'person' | 'any';
|
|
7055
|
+
/** The answer waits this long, with Undo, before it is sent (a gate: 10 000). */
|
|
7056
|
+
undoMs?: number;
|
|
7057
|
+
/** The answered line: `{label}`, `{labels}` and `{text}` are filled ("You chose: {label}"). */
|
|
7058
|
+
record: string;
|
|
7059
|
+
}
|
|
7060
|
+
|
|
7061
|
+
/** What a person answered: the host turns it into its own wire body. */
|
|
7062
|
+
export interface AskAnswer {
|
|
7063
|
+
askId: string;
|
|
7064
|
+
/** `confirm` / `choose` / `confirm_reason`: the option taken. */
|
|
7065
|
+
option?: string;
|
|
7066
|
+
/** `pick`: the options picked, in the ask's order. */
|
|
7067
|
+
options?: string[];
|
|
7068
|
+
/** `text`, and a `then` text. */
|
|
7069
|
+
text?: string;
|
|
7070
|
+
/** `scale`: the step index or value. */
|
|
7071
|
+
value?: number;
|
|
7072
|
+
/** A `needsReason` option's reason. */
|
|
7073
|
+
reason?: string;
|
|
6164
7074
|
}
|
|
6165
7075
|
|
|
6166
7076
|
// ── Inventory claims (wicked-crew#721) — whether each enumerating step's list is complete ──
|
|
@@ -6193,6 +7103,116 @@ export interface RunInventoryUnit {
|
|
|
6193
7103
|
claims: InventoryClaim[];
|
|
6194
7104
|
}
|
|
6195
7105
|
|
|
7106
|
+
/**
|
|
7107
|
+
* `GET /runs/:id/learnings` — what a run proposed to the approve queue (run learnings, crew src/learnings).
|
|
7108
|
+
* Every learning is a `memory` proposal attributed to the run (`provenance.run_id`); nothing is used until a
|
|
7109
|
+
* person approves it on the Memory page. `distilling` is true while the run's distil seat (one cheap seat
|
|
7110
|
+
* that did not build the run) is still reading its evidence.
|
|
7111
|
+
*/
|
|
7112
|
+
export interface RunLearningsResponse {
|
|
7113
|
+
runId: string;
|
|
7114
|
+
proposed: number;
|
|
7115
|
+
pending: number;
|
|
7116
|
+
approved: number;
|
|
7117
|
+
rejected: number;
|
|
7118
|
+
distilling: boolean;
|
|
7119
|
+
items: Array<{
|
|
7120
|
+
/** The proposal id (approve or reject it through `/proposals/:id/*`). */
|
|
7121
|
+
id: string;
|
|
7122
|
+
state: string;
|
|
7123
|
+
/** `gotcha` | `decision` | `pattern` | `steering`, as filed. */
|
|
7124
|
+
capture: string | null;
|
|
7125
|
+
content: string;
|
|
7126
|
+
/** Who worded it: `crew` (from the run's record) or the distil seat. */
|
|
7127
|
+
agent: string | null;
|
|
7128
|
+
/** Unix seconds. */
|
|
7129
|
+
createdAt: number | null;
|
|
7130
|
+
}>;
|
|
7131
|
+
}
|
|
7132
|
+
|
|
7133
|
+
/** (0.155.0) The in-flight check's verdict on a working step. */
|
|
7134
|
+
export type UnitInspectVerdict = 'progressing' | 'looping' | 'stuck' | 'wasteful';
|
|
7135
|
+
/** (0.155.0) The one action a check recommends; the person chooses, nothing is done for them. */
|
|
7136
|
+
export type UnitInspectAction = 'let_run' | 'steer' | 'stop';
|
|
7137
|
+
|
|
7138
|
+
/** (0.155.0) Crew's own deterministic reading of a working step's newest attempt (crew src/inspect/reading.ts). */
|
|
7139
|
+
export interface UnitInspectReading {
|
|
7140
|
+
ord: number;
|
|
7141
|
+
attempt: number;
|
|
7142
|
+
startedAt: number | null;
|
|
7143
|
+
elapsedMs: number | null;
|
|
7144
|
+
calls: number;
|
|
7145
|
+
openCalls: Array<{ tool: string; target: string | null; forMs: number }>;
|
|
7146
|
+
byKind: Record<string, number>;
|
|
7147
|
+
edits: Array<{ path: string; count: number }>;
|
|
7148
|
+
said: { deltas: number; chars: number; lastAt: number | null; newest: string | null };
|
|
7149
|
+
usage: { inputTokens: number; outputTokens: number; costUsd: number | null; source: 'live' | 'final' } | null;
|
|
7150
|
+
lastSignAt: number | null;
|
|
7151
|
+
verdict: UnitInspectVerdict;
|
|
7152
|
+
evidence: string[];
|
|
7153
|
+
doing: string | null;
|
|
7154
|
+
action: UnitInspectAction;
|
|
7155
|
+
note: string | null;
|
|
7156
|
+
}
|
|
7157
|
+
|
|
7158
|
+
/**
|
|
7159
|
+
* (0.155.0) One "Is this going well?" check on a working step (`POST /runs/:id/units/:ord/inspect`). A seat that is not
|
|
7160
|
+
* the step's own reads the step's record (one read-only `inspect-unit` run, bounded by time and budget) and answers;
|
|
7161
|
+
* when none can, or it fails, times out or reaches its budget, `source: 'crew'` and `why` says so and the answer is
|
|
7162
|
+
* crew's own reading. It never steers, stops or edits the run it looks at.
|
|
7163
|
+
*/
|
|
7164
|
+
export interface UnitInspection {
|
|
7165
|
+
id: string;
|
|
7166
|
+
runId: string;
|
|
7167
|
+
ord: number;
|
|
7168
|
+
attempt: number;
|
|
7169
|
+
state: 'checking' | 'done';
|
|
7170
|
+
/** The actor id who asked. */
|
|
7171
|
+
requestedBy: string;
|
|
7172
|
+
/** Unix ms. */
|
|
7173
|
+
requestedAt: number;
|
|
7174
|
+
finishedAt: number | null;
|
|
7175
|
+
/** The step's own seat. */
|
|
7176
|
+
workerSeat: string | null;
|
|
7177
|
+
/** The seat that checked (never the step's own); null when none could. */
|
|
7178
|
+
seat: string | null;
|
|
7179
|
+
/** The check's own run (workflow `inspect-unit`); null when none was launched. */
|
|
7180
|
+
checkRunId: string | null;
|
|
7181
|
+
source: 'seat' | 'crew' | null;
|
|
7182
|
+
why: string | null;
|
|
7183
|
+
verdict: UnitInspectVerdict | null;
|
|
7184
|
+
/** What the step is doing, one sentence. */
|
|
7185
|
+
doing: string | null;
|
|
7186
|
+
/** Roughly how far along it is (the seat's estimate), one sentence. */
|
|
7187
|
+
progress: string | null;
|
|
7188
|
+
evidence: string[];
|
|
7189
|
+
action: UnitInspectAction | null;
|
|
7190
|
+
/** For `action: 'steer'`: the note it suggests sending the step's seat (the person may edit it before sending). */
|
|
7191
|
+
note: string | null;
|
|
7192
|
+
reading: UnitInspectReading;
|
|
7193
|
+
/** What the check itself spent, when its seat reported it. */
|
|
7194
|
+
cost: { inputTokens: number; outputTokens: number; costUsd: number | null } | null;
|
|
7195
|
+
}
|
|
7196
|
+
|
|
7197
|
+
/** (0.155.0) `POST /runs/:id/units/:ord/inspect` → 202. 403 for anyone but a human operator; 409 `not_working` when the
|
|
7198
|
+
* step is not working now. A check already running on the step is answered as it is. */
|
|
7199
|
+
export interface UnitInspectionResponse {
|
|
7200
|
+
inspection: UnitInspection;
|
|
7201
|
+
}
|
|
7202
|
+
|
|
7203
|
+
/** (0.155.0) `GET /runs/:id/units/:ord/inspections`: the step's checks, newest first. */
|
|
7204
|
+
export interface UnitInspectionsResponse {
|
|
7205
|
+
inspections: UnitInspection[];
|
|
7206
|
+
}
|
|
7207
|
+
|
|
7208
|
+
/** (0.155.0) `/ws` frame: a check started, its budget moved, or it answered. */
|
|
7209
|
+
export interface UnitInspectionEvent {
|
|
7210
|
+
type: 'unitInspection';
|
|
7211
|
+
session: string;
|
|
7212
|
+
ord: number;
|
|
7213
|
+
inspection: UnitInspection;
|
|
7214
|
+
}
|
|
7215
|
+
|
|
6196
7216
|
/**
|
|
6197
7217
|
* `GET /runs/:id/inventory` (404 for an unknown run). `complete` is true only when at least one
|
|
6198
7218
|
* unit claimed an inventory, every claim is `full` and every finished unit's output was readable;
|
|
@@ -6937,7 +7957,8 @@ export interface ChatScope {
|
|
|
6937
7957
|
* 0.35.0, F-2R2-008) names the UI action that would change a `bound: false` outcome, when one
|
|
6938
7958
|
* would: `projects.graph.refresh` = build the project graph from the project page. */
|
|
6939
7959
|
graph: { bound: boolean; reason: string; repoLabel?: string; action?: ProjectGraphAction };
|
|
6940
|
-
/** `crew.repo` members of the project whose registry record is gone — named, not readable.
|
|
7960
|
+
/** `crew.repo` members of the project whose registry record is gone — named, not readable. (0.155.0) Also
|
|
7961
|
+
* any repo in scope (project or `everything`) whose folder is missing (`repo_folder_missing`). */
|
|
6941
7962
|
dangling: string[];
|
|
6942
7963
|
}
|
|
6943
7964
|
|
|
@@ -8018,8 +9039,26 @@ export interface DiagnosticsResponse {
|
|
|
8018
9039
|
* — see `DiagnosticsVault`. `null` on a route set booted without an engine adapter; ABSENT on an
|
|
8019
9040
|
* older daemon. */
|
|
8020
9041
|
vault?: DiagnosticsVault | null;
|
|
9042
|
+
/** (crew#1147) The engine's repo-checks floor cache usage (`Core.floorCacheUsage`): `path` is shown as
|
|
9043
|
+
* `~/...`, never a home path; `repos` is largest first. The engine walks the cache, so the daemon
|
|
9044
|
+
* caches this answer for 60 s. `{ error }` when the engine has no worker home; `null` on an addon
|
|
9045
|
+
* without the static; ABSENT on an older daemon. */
|
|
9046
|
+
floorCache?: DiagnosticsFloorCache | null;
|
|
8021
9047
|
}
|
|
8022
9048
|
|
|
9049
|
+
/** `DiagnosticsResponse.floorCache` (crew#1147). Every `path` is `~/...`. */
|
|
9050
|
+
export type DiagnosticsFloorCache =
|
|
9051
|
+
| {
|
|
9052
|
+
path: string;
|
|
9053
|
+
bytes: number;
|
|
9054
|
+
totalCapBytes: number;
|
|
9055
|
+
repoCapBytes: number;
|
|
9056
|
+
idleTtlSecs: number;
|
|
9057
|
+
repos: Array<{ name: string; bytes: number; leaves: number }>;
|
|
9058
|
+
logs: { path: string; bytes: number; capBytes: number };
|
|
9059
|
+
}
|
|
9060
|
+
| { error: string };
|
|
9061
|
+
|
|
8023
9062
|
/**
|
|
8024
9063
|
* (api-types 0.130.0, crew#1068) `DiagnosticsResponse.vault`: what the daemon exported to the engine
|
|
8025
9064
|
* as `WICKED_VAULT_BIN` at boot. `shipped` = crew's own `wicked-vault` dependency's bin (an absolute
|
|
@@ -8491,8 +9530,33 @@ export type SystemLevel = 'green' | 'yellow' | 'red';
|
|
|
8491
9530
|
/** The existing action an attention item or row offers (the snapshot itself is read-only):
|
|
8492
9531
|
* `sign_in` — the CLI's sign-in (`POST /seats/:cli/login…` / the Agents page); `recheck` — read
|
|
8493
9532
|
* the snapshot again (every probe runs fresh per read); `open_gate` — the run's open gate;
|
|
8494
|
-
* `open_run` — the run.
|
|
8495
|
-
|
|
9533
|
+
* `open_run` — the run. (0.162.0) `rebuild_seat_images` — `POST /system/seat-images/rebuild`
|
|
9534
|
+
* (the `seat_images` row: missing or unheld seat images); a skin that does not know a kind shows
|
|
9535
|
+
* the item without its button. */
|
|
9536
|
+
export type SystemActionKind = 'sign_in' | 'recheck' | 'open_gate' | 'open_run' | 'rebuild_seat_images';
|
|
9537
|
+
|
|
9538
|
+
/** (0.162.0) `POST /api/v1/system/seat-images/rebuild` (a person only: 403 `{ error }` for an agent
|
|
9539
|
+
* or plugin bearer) → 202 once the engine process started; 409 while a rebuild runs; 503 on the
|
|
9540
|
+
* host floor, when crew cannot reach or start the engine binary, when the engine's seat image
|
|
9541
|
+
* status does not answer, when the roster cannot be read, or when no roster seat has an engine seat
|
|
9542
|
+
* 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;
|
|
9543
|
+
* it also holds an operator's own image); its progress reads on the `seat_images` row
|
|
9544
|
+
* (`details.rebuild`). */
|
|
9545
|
+
export interface RebuildSeatImagesResponse {
|
|
9546
|
+
started: boolean;
|
|
9547
|
+
/** Why it did not start; absent when it did. */
|
|
9548
|
+
reason?: string;
|
|
9549
|
+
rebuild: {
|
|
9550
|
+
running: boolean;
|
|
9551
|
+
startedAt: string;
|
|
9552
|
+
finishedAt: string | null;
|
|
9553
|
+
rc: number | null;
|
|
9554
|
+
tail: string[];
|
|
9555
|
+
/** The last output line that reads as a failure; `null` when none. */
|
|
9556
|
+
error: string | null;
|
|
9557
|
+
clis: string[];
|
|
9558
|
+
} | null;
|
|
9559
|
+
}
|
|
8496
9560
|
|
|
8497
9561
|
/** Where an item points. A skin maps it to its own route; crew never spells a studio URL. */
|
|
8498
9562
|
export type SystemTarget =
|
|
@@ -8785,7 +9849,21 @@ export type SystemInfraKey =
|
|
|
8785
9849
|
| 'stores'
|
|
8786
9850
|
| 'seat_floor'
|
|
8787
9851
|
| 'disk'
|
|
8788
|
-
| 'load'
|
|
9852
|
+
| 'load'
|
|
9853
|
+
/** (0.155.0) The registered repositories' folders: `down` while any is missing (moved or deleted),
|
|
9854
|
+
* naming each with its path; `details.missing` lists `{ id, name, path }`. ABSENT before. */
|
|
9855
|
+
| 'repos'
|
|
9856
|
+
/** (0.162.0) The container seats' images (wicked-core `seat-image status`): `down` when a missing
|
|
9857
|
+
* seat image cannot be built (the operator's base is gone with no recipe, or an operator image is
|
|
9858
|
+
* missing) or the runtime VM disk is at 92 % or more; `degraded` when roster images are missing
|
|
9859
|
+
* (the next unit builds each first), not yet held against a runtime's image cleanup, the base is
|
|
9860
|
+
* missing, or the VM disk is at 75 % or more (a kubelet deletes unheld images from 85 %);
|
|
9861
|
+
* `unknown` when the engine, the roster or the disk could not be read. `details`: `images`
|
|
9862
|
+
* (`base`, `baseRecipe`, `holdSupported`, `floor`, `seats[]` with `present`/`held`/
|
|
9863
|
+
* `operatorImage`), `disk` (`totalBytes`, `availBytes`, `usedPct`), `missing`, `unheld`,
|
|
9864
|
+
* `imageGcHighPct`, `rebuild` (a running or the last rebuild, its output's last lines live).
|
|
9865
|
+
* `off` on the host floor. ABSENT before. */
|
|
9866
|
+
| 'seat_images';
|
|
8789
9867
|
|
|
8790
9868
|
export interface SystemInfraRow {
|
|
8791
9869
|
key: SystemInfraKey;
|
|
@@ -10677,6 +11755,8 @@ export interface DecidedGate {
|
|
|
10677
11755
|
creator: { seat: string; phase: string | null; ord: number } | null;
|
|
10678
11756
|
/** A standing order could have approved this gate (a phase-review gate of a run that lands no doctrine). */
|
|
10679
11757
|
orderApprovable: boolean;
|
|
11758
|
+
/** (api-types 0.156.0) Answered by voice and confirmed on screen ({@link GateDecision.input}); absent otherwise. */
|
|
11759
|
+
input?: 'voice';
|
|
10680
11760
|
}
|
|
10681
11761
|
|
|
10682
11762
|
/** `GET /gates/decided`'s 200. A malformed `since` answers 400. */
|
|
@@ -11682,6 +12762,23 @@ export interface EditorControl {
|
|
|
11682
12762
|
maxChars?: number;
|
|
11683
12763
|
}
|
|
11684
12764
|
|
|
12765
|
+
/**
|
|
12766
|
+
* How an editor looks on studio's Plugins page (program DES-LEARN §2; api-types 0.157.0). Every image is a `data:` URL
|
|
12767
|
+
* (`image/svg+xml`, `image/png` or `image/webp`, base64) the registry read from the editor's own files, bounded (icon
|
|
12768
|
+
* 16 KB, preview 200 KB) and never through a link: no path and no remote URL is on the wire. Each field is optional;
|
|
12769
|
+
* a file that is missing, too big or not the image its name says is left out (the editor is still served).
|
|
12770
|
+
*/
|
|
12771
|
+
export interface EditorVisuals {
|
|
12772
|
+
/** Drawn on `color`, at about 18 px. */
|
|
12773
|
+
icon?: string;
|
|
12774
|
+
/** `#rrggbb`. */
|
|
12775
|
+
color?: string;
|
|
12776
|
+
/** A 16:9 picture of the editor at work; a `dark` one is used on a dark theme (else `light`). */
|
|
12777
|
+
preview?: { light?: string; dark?: string };
|
|
12778
|
+
/** The editor offers a live preview on its own sample (reserved: studio draws one for run plugins today). */
|
|
12779
|
+
live?: boolean;
|
|
12780
|
+
}
|
|
12781
|
+
|
|
11685
12782
|
/**
|
|
11686
12783
|
* One registered editor, as Settings → Editors renders it. No path is on the wire: the bundle is
|
|
11687
12784
|
* fetched at `entry_url` (`GET /editors/:id/:version/entry`, the §8.2 headers, re-hashed per serve).
|
|
@@ -11714,6 +12811,11 @@ export interface EditorView {
|
|
|
11714
12811
|
/** `studio-bundle`: first-party, shipped with studio. `pack`: a third-party pack the operator installed. */
|
|
11715
12812
|
source: 'studio-bundle' | 'pack';
|
|
11716
12813
|
entry_url: string;
|
|
12814
|
+
/** Its one line for the Plugins page (at most 160 characters). Absent when the manifest has none, and from a daemon
|
|
12815
|
+
* that predates the field (api-types 0.157.0). */
|
|
12816
|
+
description?: string;
|
|
12817
|
+
/** Its icon, colour and preview (api-types 0.157.0). Absent when it declares none that read. */
|
|
12818
|
+
visuals?: EditorVisuals;
|
|
11717
12819
|
}
|
|
11718
12820
|
|
|
11719
12821
|
/** `GET /editors` (operator+). */
|
|
@@ -12068,7 +13170,17 @@ export interface ScheduleRunResponse {
|
|
|
12068
13170
|
schedule: WorkflowSchedule;
|
|
12069
13171
|
}
|
|
12070
13172
|
|
|
12071
|
-
export type InsightsMetricId =
|
|
13173
|
+
export type InsightsMetricId =
|
|
13174
|
+
| 'pass_rate'
|
|
13175
|
+
| 'override_rate'
|
|
13176
|
+
| 'unresolved_rate'
|
|
13177
|
+
| 'time_to_pr'
|
|
13178
|
+
| 'floor_minutes'
|
|
13179
|
+
| 'wait_on_people'
|
|
13180
|
+
| 'spend'
|
|
13181
|
+
| 'retries'
|
|
13182
|
+
/** (api-types 0.149.0, power mode) Power runs whose rigor rose after their intake QE plan sized them. */
|
|
13183
|
+
| 'rigor_raised';
|
|
12072
13184
|
/** `too-few` = below the minimum sample (n < 5) in the window or the baseline: no trend is called. */
|
|
12073
13185
|
export type InsightsVerdict = 'too-few' | 'no-change' | 'improved' | 'regressed';
|
|
12074
13186
|
export type InsightsRecommendationKind = 'steering-rule' | 'memory' | 'setting' | 'issue' | 'resolve-stale';
|
|
@@ -12585,3 +13697,112 @@ export interface DefaultEvalDetail {
|
|
|
12585
13697
|
report: DefaultEvalReport;
|
|
12586
13698
|
cases: DefaultEvalCase[];
|
|
12587
13699
|
}
|
|
13700
|
+
|
|
13701
|
+
// ── Voice mode, phase 1 (program DES-VOICE; api-types 0.156.0) ─────────────────────────────────────────
|
|
13702
|
+
|
|
13703
|
+
/**
|
|
13704
|
+
* `GET /voice/status` (and the answer of `POST|DELETE /voice/model`). Speech to text runs on THIS machine:
|
|
13705
|
+
* whisper.cpp's CLI plus one model file. Every voice route is the human operator's alone, on loopback
|
|
13706
|
+
* (403 `human_operator_only` / `voice_loopback_only`).
|
|
13707
|
+
*/
|
|
13708
|
+
export interface VoiceStatus {
|
|
13709
|
+
/** Audio is transcribed on this machine and never sent anywhere. Always `true` in phase 1. */
|
|
13710
|
+
local: true;
|
|
13711
|
+
/** The engine and the model are both here: `POST /voice/transcribe` can run. */
|
|
13712
|
+
ready: boolean;
|
|
13713
|
+
engine: {
|
|
13714
|
+
name: 'whisper.cpp';
|
|
13715
|
+
found: boolean;
|
|
13716
|
+
/** Where the CLI was found; `null` when it was not. */
|
|
13717
|
+
path: string | null;
|
|
13718
|
+
/** How to install (or upgrade) it on this platform, when it is missing or too old; else `null`. */
|
|
13719
|
+
install: string | null;
|
|
13720
|
+
/** (api-types 0.158.0) The version it reports (`--version`); `null` when not found, or too old to report one. */
|
|
13721
|
+
version: string | null;
|
|
13722
|
+
/** (api-types 0.158.0) New enough for voice (1.8.0 or later, reporting `--version`): a stdin transcription prints
|
|
13723
|
+
* its text and writes no file. An older engine is refused with 409 `voice_engine_outdated`, before any audio. */
|
|
13724
|
+
supported: boolean;
|
|
13725
|
+
};
|
|
13726
|
+
model: {
|
|
13727
|
+
/** `base.en`. */
|
|
13728
|
+
name: string;
|
|
13729
|
+
present: boolean;
|
|
13730
|
+
/** The model file's size; `null` when absent. */
|
|
13731
|
+
bytes: number | null;
|
|
13732
|
+
/** What the consent says before anything is fetched. */
|
|
13733
|
+
approxBytes: number;
|
|
13734
|
+
/** Where it is fetched from (`huggingface.co/ggerganov/whisper.cpp`). */
|
|
13735
|
+
source: string;
|
|
13736
|
+
/** A download in progress, or the last one's failure; `null` when none. */
|
|
13737
|
+
download: {
|
|
13738
|
+
state: 'running' | 'failed';
|
|
13739
|
+
receivedBytes: number;
|
|
13740
|
+
totalBytes: number | null;
|
|
13741
|
+
startedAt: string;
|
|
13742
|
+
error: string | null;
|
|
13743
|
+
} | null;
|
|
13744
|
+
};
|
|
13745
|
+
}
|
|
13746
|
+
|
|
13747
|
+
/** `POST /voice/model`: the person's consent to fetch the model (202 = started; 200 = already here; 409
|
|
13748
|
+
* `voice_download_running`). Audited `voice.model.download_started`. `DELETE /voice/model` removes it. */
|
|
13749
|
+
export interface PostVoiceModelBody {
|
|
13750
|
+
consent: true;
|
|
13751
|
+
}
|
|
13752
|
+
|
|
13753
|
+
/**
|
|
13754
|
+
* `POST /voice/transcribe` with an `audio/wav` body (16 kHz mono 16-bit, at most 8 MiB). The audio is held in
|
|
13755
|
+
* memory for the call and dropped: never stored, logged or audited. Errors carry `code`:
|
|
13756
|
+
* `voice_engine_missing` / `voice_engine_outdated` / `voice_model_missing` (409), `voice_audio_invalid` (400/415),
|
|
13757
|
+
* `voice_audio_too_large` (413), `voice_busy` (429: one runs and one waits), `voice_timeout` (504), `voice_failed` (500).
|
|
13758
|
+
*/
|
|
13759
|
+
export interface VoiceTranscribeResponse {
|
|
13760
|
+
/** The words, one line; empty when nothing was said. */
|
|
13761
|
+
text: string;
|
|
13762
|
+
ms: number;
|
|
13763
|
+
model: string;
|
|
13764
|
+
}
|
|
13765
|
+
|
|
13766
|
+
/** A section a widget registers in the `voice-dashboard` panel slot (the `panels[]` shape of a run plugin). */
|
|
13767
|
+
export interface VoicePanelDecl {
|
|
13768
|
+
slot: 'voice-dashboard';
|
|
13769
|
+
id: string;
|
|
13770
|
+
title: string;
|
|
13771
|
+
/** 1-99, lower first. */
|
|
13772
|
+
order: number;
|
|
13773
|
+
}
|
|
13774
|
+
|
|
13775
|
+
/**
|
|
13776
|
+
* A USER-MADE dashboard widget: a declarative plugin (no code, nothing framed) that shows one field of
|
|
13777
|
+
* `GET /system` or `GET /diagnostics` as a number or a chart. `metric.path` is a field path:
|
|
13778
|
+
* `infra[key=load].details.load1`, `runs.length`, `toReview`.
|
|
13779
|
+
*/
|
|
13780
|
+
export interface VoiceWidgetManifest {
|
|
13781
|
+
/** `user.<slug>`. */
|
|
13782
|
+
id: string;
|
|
13783
|
+
title: string;
|
|
13784
|
+
version: 1;
|
|
13785
|
+
kind: 'metric';
|
|
13786
|
+
panels: [VoicePanelDecl];
|
|
13787
|
+
metric: {
|
|
13788
|
+
source: 'system' | 'diagnostics';
|
|
13789
|
+
path: string;
|
|
13790
|
+
display: 'number' | 'chart';
|
|
13791
|
+
unit?: string;
|
|
13792
|
+
};
|
|
13793
|
+
createdAt?: string;
|
|
13794
|
+
}
|
|
13795
|
+
|
|
13796
|
+
/** `GET /voice/dashboard`: this person's dashboard (keyed by actor id). `layout: null` = never saved. */
|
|
13797
|
+
export interface VoiceDashboard {
|
|
13798
|
+
/** Widget ids in order: `builtin.<id>` or a user widget's `user.<slug>`. */
|
|
13799
|
+
layout: string[] | null;
|
|
13800
|
+
widgets: VoiceWidgetManifest[];
|
|
13801
|
+
updatedAt: string | null;
|
|
13802
|
+
}
|
|
13803
|
+
|
|
13804
|
+
/** `PUT /voice/dashboard` (at most 24 on the layout, 16 user widgets; every `user.*` on the layout is in `widgets`). */
|
|
13805
|
+
export interface PutVoiceDashboardBody {
|
|
13806
|
+
layout: string[];
|
|
13807
|
+
widgets: VoiceWidgetManifest[];
|
|
13808
|
+
}
|