wicked-crew-api-types 0.33.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.d.ts +175 -12
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -426,9 +426,61 @@ export interface RosterSeat {
426
426
  * unknown seat keys, or a daemon predating the field).
427
427
  */
428
428
  signed_in?: boolean | null;
429
+ /**
430
+ * What `signed_in` MEANS for this seat (api-types 0.35.0, F-2R2-009): `signed_in` — a credential
431
+ * artifact is observable; `signed_out` — none is and the seat needs one (a council benches it on
432
+ * its first ballot; a chat refuses it up front); `not_required` — none is, but the seat answers
433
+ * on a free tier with no account (`free_tier` names it); `unknown` — the probe cannot tell
434
+ * cheaply (keychain-backed seats, unknown seat keys). Absent on a daemon predating the field.
435
+ */
436
+ auth?: SeatAuth;
437
+ /** Present when `auth` is `not_required`: the free tier the seat answers on. */
438
+ free_tier?: string;
439
+ /**
440
+ * Where the `not_required` reading came from: `registry` when the CLI's own record declared the
441
+ * credential requirement, `crew-heuristic` when the daemon's per-CLI table did (today's only
442
+ * source — the engine's `AgenticCli` declares none; a wicked-core follow-up). A reader can show
443
+ * the heuristic as such.
444
+ */
445
+ free_tier_source?: 'registry' | 'crew-heuristic';
446
+ /**
447
+ * Whether a council would seat AND keep this seat as far as the daemon can tell: enabled for
448
+ * council, runtime `health` active, `auth` not `signed_out`. The daemon's PREDICTION from its
449
+ * own records — the engine still convenes whatever roster it is handed and benches a seat only
450
+ * after it fails. Chat admission (`POST /chats` defaults) reads the same auth predicate.
451
+ */
452
+ council_eligible?: boolean;
453
+ /** Present when `council_eligible` is false: the one reason, in the operator's words. */
454
+ council_ineligible_reason?: string;
455
+ /**
456
+ * Present when THIS daemon's recent councils benched the seat: the engine's own
457
+ * `councilSeatFailed` evidence (`non_zero_exit` / `timed_out`, the derivative `benched` kind
458
+ * excluded), folded over a bounded window (`window_ms`) and cleared by the seat's next ok unit
459
+ * output. `council_eligible` is false while it is present.
460
+ */
461
+ council_bench?: RosterSeatCouncilBench;
429
462
  [k: string]: unknown;
430
463
  }
431
464
 
465
+ /** `RosterSeat.council_bench` (api-types 0.35.0). */
466
+ export interface RosterSeatCouncilBench {
467
+ /** Primary ballot failures inside the window. */
468
+ failures: number;
469
+ /** The last failure's `councilSeatFailed.kind`. */
470
+ last_kind: string;
471
+ /** ISO-8601 of the last failure. */
472
+ last_at: string;
473
+ /** The run the last failure happened in, when the frame named one. */
474
+ last_run?: string;
475
+ /** A bounded excerpt of the last failure's detail / stderr, when there was one. */
476
+ last_detail?: string;
477
+ /** The rolling window the failures were counted over, ms. */
478
+ window_ms: number;
479
+ }
480
+
481
+ /** A seat's auth reading (`RosterSeat.auth`; api-types 0.35.0). */
482
+ export type SeatAuth = 'signed_in' | 'signed_out' | 'not_required' | 'unknown';
483
+
432
484
  /** Body for `POST /open` — open a file/folder with the OS default application (crew#273). */
433
485
  export interface OpenPathBody {
434
486
  /**
@@ -1785,6 +1837,40 @@ export interface SkillBaselineRecord {
1785
1837
  venv: SkillVenvState;
1786
1838
  }
1787
1839
 
1840
+ /**
1841
+ * Why a skill's text cannot be followed on a non-Claude CLI (F-079, api-types 0.34.0; design W4
1842
+ * §5.1 — the same tokens wicked-garden's own lint reports):
1843
+ *
1844
+ * - `plugin-root` — the text contains `${CLAUDE_PLUGIN_ROOT}` (only Claude Code substitutes it);
1845
+ * - `skill-dir-var` — the text contains `${CLAUDE_SKILL_DIR}` (likewise Claude-only);
1846
+ * - `cwd-script` — an interpreter invokes a plugin script by a path relative to the worktree cwd
1847
+ * (`python3 scripts/domain/extract_loop.py`) instead of the `wicked-garden run …` launcher;
1848
+ * - `relative-link` — a `../` link whose target exists in the bundle (the flat `<name>/SKILL.md`
1849
+ * layout of every non-Claude install cannot follow it);
1850
+ * - `cross-skill-path` — a path (plugin-root or `../`) that lands in ANOTHER skill's directory;
1851
+ * the portable form names that skill (`wicked-garden-<x>`) instead;
1852
+ * - `requires-harness:claude` — the author declared `metadata.requires-harness: claude` in the
1853
+ * frontmatter: the skill genuinely needs the Claude harness (not an authoring defect).
1854
+ */
1855
+ export type SkillPortabilityReason =
1856
+ | 'plugin-root'
1857
+ | 'skill-dir-var'
1858
+ | 'cwd-script'
1859
+ | 'relative-link'
1860
+ | 'cross-skill-path'
1861
+ | 'requires-harness:claude';
1862
+
1863
+ /** Per-reason portability of a skill (F-079, api-types 0.34.0) — reported beside `portable`. */
1864
+ export interface SkillPortability {
1865
+ /** The same value as `SkillEntry.portable`: `reasons.length === 0`. */
1866
+ portable: boolean;
1867
+ /** Sorted, unique. Empty when portable. */
1868
+ reasons: SkillPortabilityReason[];
1869
+ /** Up to five anchors, `<plugin-relative file>:<line>`, one per hit in file order — where the
1870
+ * offending text sits (the drawer's "why" and the operator's path to the line). */
1871
+ evidence?: string[];
1872
+ }
1873
+
1788
1874
  export interface SkillEntry {
1789
1875
  /** Plugin-relative directory, nested layout preserved (`skills/engineering/frontend`). Never
1790
1876
  * renamed — sibling `../` links depend on it. */
@@ -1794,11 +1880,17 @@ export interface SkillEntry {
1794
1880
  * daemon knows (core drop-ins, crew-generated, user-registered) or a skill one of those names in
1795
1881
  * its SKILL.md (repo-learn → search, mem). Disabling or renaming it is blocking. */
1796
1882
  core: boolean;
1797
- /** `false` when the skill's files resolve `${CLAUDE_PLUGIN_ROOT}`, invoke a script relative to
1798
- * the cwd (`python3 -u scripts/x.py`, `./scripts/x`, …), or link `../` — Claude-only by nature:
1799
- * excluded from the snapshot's `views/copilot/` and from the per-launch skill lists core builds
1800
- * for the other CLIs. `portable` is the admission key for every non-Claude view (design v3.2). */
1883
+ /** `false` when the skill's files carry any `SkillPortabilityReason` — Claude-only: excluded from
1884
+ * the snapshot's `views/copilot/` and from the per-launch skill lists core builds for the other
1885
+ * CLIs. `portable` is the admission key for every non-Claude view (design v3.2); the reasons
1886
+ * are reported per token in `portability` (api-types 0.34.0). wicked-garden ≥ 12.33 authors
1887
+ * every skill portably, so a non-portable row there is either an older garden or a skill that
1888
+ * declares `requires-harness: claude`. */
1801
1889
  portable: boolean;
1890
+ /** Per-reason portability (F-079, api-types 0.34.0): `portable` again, the sorted unique
1891
+ * `reasons`, and up to five `file:line` anchors. Absent on manifests written by a daemon older
1892
+ * than 0.7.30 — treat absence as "reasons unknown". */
1893
+ portability?: SkillPortability;
1802
1894
  /** Manifest state, orthogonal to content: a disabled skill's files stay in `effective/` and are
1803
1895
  * excluded from the next published snapshot. Reset never flips it. */
1804
1896
  enabled: boolean;
@@ -1917,6 +2009,9 @@ export type SkillFindingKind =
1917
2009
  | 'core-rename'
1918
2010
  | 'core-missing'
1919
2011
  | 'support-file-edit'
2012
+ /** A write made (or would make) the skill non-portable — a WARNING, one finding PER REASON per
2013
+ * file (api-types 0.34.0), anchored `file:line` at the first hit and carrying the token in
2014
+ * `portabilityReason`. The skill leaves every non-Claude delivery view. */
1920
2015
  | 'non-portable'
1921
2016
  /** A `${CLAUDE_PLUGIN_ROOT}/<p>` or `../<p>` reference in an enabled skill's files that does not
1922
2017
  * resolve inside the would-be snapshot. Severity follows the TARGET (design v3.4 §1): a reference
@@ -2002,6 +2097,9 @@ export interface SkillConflictFinding {
2002
2097
  evidence: string;
2003
2098
  /** Why it matters. */
2004
2099
  explanation: string;
2100
+ /** On a `non-portable` finding: WHICH reason this finding reports (one finding per reason per
2101
+ * file). Absent on every other kind (api-types 0.34.0). */
2102
+ portabilityReason?: SkillPortabilityReason;
2005
2103
  }
2006
2104
 
2007
2105
  /** `POST /skills/analyze` 200 body (a PURE dry run of the publish validation: nothing persisted,
@@ -2779,6 +2877,20 @@ export interface CodeGraphData {
2779
2877
  stats: { nodeCount: number; edgeCount: number; fileCount: number };
2780
2878
  }
2781
2879
 
2880
+ /**
2881
+ * `GET /repos/:id/graph` → 200 (api-types 0.35.0, F-2R2-005). `graph: null` = the repo's code
2882
+ * graph has not been built (nothing at its registered graph path) — and `reason` says WHY, so a
2883
+ * consumer of this route alone can tell "not indexed" from "empty": the same finding text the
2884
+ * repos wire carries when the engine has one (`finding` — e.g. `in_tree_code_graph_ignored`: a
2885
+ * checkout's in-tree graph is ignored and no live graph exists yet; re-run onboarding), else the
2886
+ * daemon's own sentence. Both absent when `graph` is present.
2887
+ */
2888
+ export interface RepoGraphResponse {
2889
+ graph: CodeGraphData | null;
2890
+ reason?: string;
2891
+ finding?: RepoFinding;
2892
+ }
2893
+
2782
2894
  export interface GitCommit {
2783
2895
  sha: string;
2784
2896
  shortSha: string;
@@ -3357,8 +3469,10 @@ export interface ChatScope {
3357
3469
  cwd: string;
3358
3470
  /** Whether a READ-ONLY estate MCP over a code graph is attached, and why / why not. `repoLabel`
3359
3471
  * is the estate label the project graph indexes the (single) scoped repo under, when the
3360
- * binding was repo-bound — informational; the engine binds by graph path. */
3361
- graph: { bound: boolean; reason: string; repoLabel?: string };
3472
+ * binding was repo-bound — informational; the engine binds by graph path. `action` (api-types
3473
+ * 0.35.0, F-2R2-008) names the UI action that would change a `bound: false` outcome, when one
3474
+ * would: `projects.graph.refresh` = build the project graph from the project page. */
3475
+ graph: { bound: boolean; reason: string; repoLabel?: string; action?: ProjectGraphAction };
3362
3476
  /** `crew.repo` members of the project whose registry record is gone — named, not readable. */
3363
3477
  dangling: string[];
3364
3478
  }
@@ -3370,6 +3484,18 @@ export interface ChatSeatOutcome {
3370
3484
  error?: string;
3371
3485
  }
3372
3486
 
3487
+ /**
3488
+ * One seat a `POST /chats` did NOT seat, and why (api-types 0.35.0, F-2R2-007): a DEFAULT seat the
3489
+ * daemon's admission dropped before the engine saw it (signed out; not admissible to a scoped chat
3490
+ * — its ACP adapter asks no permissions and arms no sandbox, or it has no ACP adapter), or a
3491
+ * REQUESTED seat (`clis`) the engine refused (`ChatSeatOutcome.ok: false`, its `error` repeated
3492
+ * here as `reason`). One list for the scope card and the thread to read.
3493
+ */
3494
+ export interface ChatSeatRefusal {
3495
+ cliKey: string;
3496
+ reason: string;
3497
+ }
3498
+
3373
3499
  /** `POST /chats` → 201. */
3374
3500
  export interface ChatOpenResponse {
3375
3501
  chatId: string;
@@ -3378,8 +3504,27 @@ export interface ChatOpenResponse {
3378
3504
  scope: ChatScope;
3379
3505
  /** Present when the chat opened but its `crew.chat` filing into `projectId` failed. */
3380
3506
  projectAttachError?: string;
3507
+ /** Every seat that was asked for or defaulted and is NOT in `seats` as warm, with its reason
3508
+ * (api-types 0.35.0). Empty when every seat warmed; absent on a daemon predating the field. */
3509
+ refused?: ChatSeatRefusal[];
3381
3510
  }
3382
3511
 
3512
+ /**
3513
+ * A seat refused at `POST /chats` (api-types 0.35.0, F-2R2-007). DAEMON-SYNTHETIC: broadcast
3514
+ * straight to `/ws` once per refused seat, right after the open, so the chat thread can say why a
3515
+ * seat is missing (the studio's `chat-scope-admission` copy) — the engine emits nothing for a seat
3516
+ * it never saw. `chat` names the chat the way the engine's `chatClosed` does; `project_id` rides
3517
+ * along when the chat was filed. An anonymous object type on purpose, like the stall frames, so it
3518
+ * flows through `CoreEvent`-typed seams.
3519
+ */
3520
+ export type ChatSeatRefusedFrame = {
3521
+ type: 'chatSeatRefused';
3522
+ chat: string;
3523
+ cliKey: string;
3524
+ reason: string;
3525
+ project_id?: string;
3526
+ };
3527
+
3383
3528
  /** One live chat on `GET /chats` (FINDING-027 gap 4; scope fields with crew#502). */
3384
3529
  export interface ChatSummary {
3385
3530
  chatId: string;
@@ -3476,11 +3621,21 @@ export interface ProjectGraphRepo {
3476
3621
  }
3477
3622
 
3478
3623
  /** `GET /projects/:id/graph` — what the project graph holds and what it cannot answer. */
3624
+ /** The UI action that resolves a project-graph state or a declined binding (api-types 0.35.0):
3625
+ * `projects.graph.refresh` = `POST /projects/:id/graph/refresh`, surfaced as the project page's
3626
+ * build/refresh control. */
3627
+ export type ProjectGraphAction = 'projects.graph.refresh';
3628
+
3479
3629
  export interface ProjectGraphStatus {
3480
3630
  projectId: string;
3481
3631
  state: ProjectGraphState;
3482
- /** One sentence naming the state's cause and its remedy. Always present, never empty. */
3632
+ /** One sentence naming the state's cause and its remedy, in the operator's words — never a raw
3633
+ * route (F-2R2-008); the route rides on `action`. Always present, never empty. */
3483
3634
  detail: string;
3635
+ /** Present when one UI action resolves the state (today: `not-indexed` with registered members
3636
+ * → `projects.graph.refresh`). Absent when no single action does (dangling-only members, no
3637
+ * members, or a graph that is already built). api-types 0.35.0. */
3638
+ action?: ProjectGraphAction;
3484
3639
  /** Absolute path of the co-located database; `null` when there is none to point at. */
3485
3640
  dbPath: string | null;
3486
3641
  repos: ProjectGraphRepo[];
@@ -4036,16 +4191,24 @@ export interface DiagnosticsGovernanceDeadletters {
4036
4191
  /** `true` when the fold stopped at its byte cap — `count` is then a floor. */
4037
4192
  truncated: boolean;
4038
4193
  /** The pre-fix outbox under HOME (`~/.something-wicked/wicked-apps/emit-outbox.ndjson`) when it exists and is
4039
- * non-empty — events earlier daemons on this host spooled there; `null` otherwise. Reported, never written. */
4040
- legacyOutbox: { path: string; bytes: number } | null;
4194
+ * non-empty — events earlier daemons on this host spooled there; `null` otherwise. Reported, never written.
4195
+ * `scope` (api-types 0.35.0, F-2R2-006): `own` = this daemon runs in that HOME's default state home, so the
4196
+ * file is its own earlier versions' outbox (the finding is a warning with the replay recipe); `host` = this
4197
+ * daemon's state home is isolated, so the file — shared by every daemon on the host — cannot be attributed
4198
+ * to it (an `info` finding with a read-only `--dry-run` inspect recipe and no replay). REQUIRED, deliberately:
4199
+ * the daemon always attributes the file it reports, so a `legacyOutbox` object without `scope` never leaves a
4200
+ * daemon shipping this contract; a skin that talks to an OLDER daemon must treat the whole `legacyOutbox`
4201
+ * object as best-effort (it predates the attribution), not the field alone. */
4202
+ legacyOutbox: { path: string; bytes: number; scope: 'own' | 'host' } | null;
4041
4203
  }
4042
4204
 
4043
4205
  /** One governance finding. `governance.store` (error) = no store resolved, every emit dead-letters;
4044
- * `governance.deadletter` (error) = the outbox holds entries; `governance.legacy-outbox` (warning) =
4045
- * the pre-fix HOME outbox exists. Every message names the replay command. */
4206
+ * `governance.deadletter` (error) = the outbox holds entries; `governance.legacy-outbox` = the pre-fix
4207
+ * HOME outbox exists — `warning` with the replay command when it is this daemon's own, `info` with none
4208
+ * when it is shared across the host's daemons and not this one's (api-types 0.35.0). */
4046
4209
  export interface DiagnosticsGovernanceFinding {
4047
4210
  kind: 'governance.store' | 'governance.deadletter' | 'governance.legacy-outbox';
4048
- severity: 'warning' | 'error';
4211
+ severity: 'info' | 'warning' | 'error';
4049
4212
  message: string;
4050
4213
  }
4051
4214
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-crew-api-types",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "description": "The wire contract of the wicked-crew daemon's /api/v1 REST surface and /ws CoreEvent frames \u2014 types only, zero runtime",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",