@qontinui/shared-types 0.13.0 → 1.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qontinui/shared-types",
3
- "version": "0.13.0",
3
+ "version": "1.0.0",
4
4
  "description": "Shared TypeScript types for the Qontinui ecosystem",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,110 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * This file was automatically generated.
4
+ * DO NOT MODIFY IT BY HAND. Regenerate with `just generate-types` or
5
+ * `qontinui-runner/src-tauri/scripts/generate_types.sh`.
6
+ */
7
+
8
+ /**
9
+ * One embedded default as the **runner binary** ships it, on its way to the
10
+ * account so there is a baseline to diff an override against.
11
+ *
12
+ * ## Why this exists as a third layer
13
+ *
14
+ * [`AgentTextUnit`]'s resolution chain is
15
+ * `account override → fleet default → embedded default (runner binary)`, and
16
+ * the store holds rows for the first two only — the binary's copy has never
17
+ * had a row anywhere. That is the gap this type closes. A user who overrode
18
+ * `/implement-plan` can diff their versions against each other but not
19
+ * against what actually ships, and `ResetToDefaultDialog` cannot preview the
20
+ * text it is about to restore, because there is no baseline to put on the
21
+ * left-hand side.
22
+ *
23
+ * Plan `2026-08-31-runner-publishes-embedded-command-defaults`; the deferral
24
+ * it discharges is recorded in the code at qontinui-web's
25
+ * `settings/agent-commands/_components/VersionDiff.tsx`.
26
+ *
27
+ * ## What it is NOT
28
+ *
29
+ * * **Not an [`AgentTextUnit`].** There is no `id`, no version chain, and no
30
+ * `is_shared` — a published default is content plus provenance, not a
31
+ * corpus row with an edit history. It is the *input* to a row.
32
+ * * **Not fleet-scoped.** `organization_id` is deliberately absent from the
33
+ * wire: the runner publishes with the operator's own user bearer, so the
34
+ * server assigns the org from that credential. A client-supplied org — or
35
+ * the fleet layer's `organization_id IS NULL` — would let any signed-in
36
+ * user rewrite another tenant's baseline, or silently clobber an
37
+ * operator's deliberate fleet default.
38
+ * * **Not authoritative for provisioning.** The runner keeps resolving
39
+ * `fresh fetch → disk cache → embedded default`; this is a *display*
40
+ * baseline. Publishing it must never put the network on the
41
+ * out-of-the-box path.
42
+ *
43
+ * ## The checksum is the files-map digest, not the single-body one
44
+ *
45
+ * [`checksum`](Self::checksum) is [`agent_text_unit_files_checksum`] — the
46
+ * same digest [`AgentTextUnit::checksum`] and [`AgentTextUnitVersion`] carry,
47
+ * so a published default and the override it is diffed against are
48
+ * comparable. It is **not**
49
+ * [`crate::agent_commands::agent_command_checksum`], which digests a single
50
+ * body and is what the legacy `/agent-commands` wire still carries. Those two
51
+ * deliberately disagree even for a one-entry map, so a default digested with
52
+ * the wrong one would never compare equal to its override — an always-drifted
53
+ * baseline, which is strictly worse than the honest "baseline unavailable"
54
+ * state it would replace.
55
+ */
56
+ export interface AgentTextUnitDefault {
57
+ /**
58
+ * Canonical digest over [`files`](Self::files), from
59
+ * [`agent_text_unit_files_checksum`].
60
+ *
61
+ * Required, unlike [`AgentTextUnit::checksum`] — that one is optional only
62
+ * to describe rows written before a checksum was computed, whereas a
63
+ * publish is always freshly computed. The receiving store **recomputes it
64
+ * and rejects a mismatch**: a client-asserted digest is not evidence.
65
+ * [`checksum_matches`](Self::checksum_matches) is that check.
66
+ */
67
+ checksum: string;
68
+ /**
69
+ * The embedded content: **relative path → text**. A command carries one
70
+ * entry; a skill carries `SKILL.md` plus siblings. Same arity-agnostic
71
+ * shape as [`AgentTextUnit::files`].
72
+ */
73
+ files: {
74
+ [k: string]: string;
75
+ };
76
+ /**
77
+ * What sort of unit this default is. The corpus is `kind`-discriminated,
78
+ * so the default layer must be too — otherwise a command and a skill of
79
+ * the same name collapse into one baseline.
80
+ */
81
+ kind: string;
82
+ /**
83
+ * The unit slug, e.g. `vet-plan`. Must satisfy the same
84
+ * [`validate_agent_text_unit_name`] rules as an override: a default that
85
+ * could not be named as an override could never be paired with one for a
86
+ * diff, which is the only thing it is for.
87
+ */
88
+ name: string;
89
+ /**
90
+ * ISO 8601 (RFC 3339) publish timestamp, matching this module's wire
91
+ * convention for [`AgentTextUnit::updated_at`] and
92
+ * [`AgentTextUnitVersion::created_at`].
93
+ */
94
+ published_at: string;
95
+ /**
96
+ * The runner version that published this body, e.g. `"0.4.12"`.
97
+ *
98
+ * Carried so the UI can label the baseline **"published by runner
99
+ * vX.Y.Z"** rather than "the default" — an org whose devices run
100
+ * different builds has no single default, and the label must not claim
101
+ * otherwise. It is also the monotonic guard's input: the store rejects a
102
+ * publish older than the version it already holds.
103
+ *
104
+ * That guard is a **mitigation, not a fix** — a genuine downgrade still
105
+ * wins and equal versions tie-break last-writer — so neither this field
106
+ * nor the UI built on it may describe the baseline as authoritative.
107
+ */
108
+ published_by_version: string;
109
+ [k: string]: unknown;
110
+ }
@@ -41,8 +41,55 @@ export interface UIBridgeElement {
41
41
  bbox?: ElementBbox | null;
42
42
  /**
43
43
  * Custom (application-defined) actions.
44
- */
45
- customActions?: string[] | null;
44
+ *
45
+ * **Objects, not names.** These used to be a bare `Vec<String>` of action
46
+ * names, which left an element-level custom action with nowhere to carry a
47
+ * safety class — so the walker had no way to tell a `refresh` from a
48
+ * `sendKeys` that writes raw bytes into a live agent PTY. Widening this to
49
+ * [`ElementActionInfo`] is what makes `effect` REACHABLE from an element;
50
+ * see that type's docs.
51
+ *
52
+ * Absent (`None`) means the element declares none. That is deliberately
53
+ * distinct from an empty list, which would mean "declared, and empty".
54
+ * ---
55
+ *
56
+ * **TRANSITIONAL: this field also accepts the legacy bare-NAME form on the
57
+ * way in.** `["sendKeys"]` deserializes as
58
+ * `[ElementActionInfo { id: "sendKeys", .. }]`, with every other field —
59
+ * `effect` included — left `None`, i.e. UNCLASSIFIED. See
60
+ * [`deserialize_custom_actions`].
61
+ *
62
+ * **Why a shim exists at all**, when this workspace's rule is
63
+ * delete-over-deprecate. The shape change spans three repos that cannot
64
+ * land atomically — this crate owns the type, `ui-bridge` emits, and
65
+ * `qontinui-runner` parses live SDK snapshots strictly
66
+ * (`spec-check/src/fetch.rs`, `spec_api/spec_check.rs`) while pinning a
67
+ * PUBLISHED SDK. Both two-party orderings leave a window in which the
68
+ * fleet is broken: land this crate first and the runner rejects the names
69
+ * the published SDK still emits; land the SDK first and it emits objects
70
+ * at a runner whose type is still `Vec<String>`. Only a tolerant READER
71
+ * removes the window, and there is one reader against nine emitters.
72
+ *
73
+ * This is NOT here to spare a caller a breaking change — that is never a
74
+ * reason in this workspace.
75
+ *
76
+ * **DELETE ME, and the trigger is observable rather than intentional:**
77
+ * once no emitter produces names — `ui-bridge`'s eight element
78
+ * projections plus `qontinui-runner`'s
79
+ * `src/services/background-observer-service.ts` — and the runner's SDK pin
80
+ * has moved past that release, remove [`deserialize_custom_actions`] and
81
+ * this attribute, and flip
82
+ * `ui_bridge_element_tolerates_legacy_name_custom_actions` into a test
83
+ * that asserts a bare string is REJECTED. Plan
84
+ * `2026-09-04-effect-calculus-joins-the-component-action-registry`,
85
+ * Design decision 4, step 5.
86
+ *
87
+ * The published SCHEMA is deliberately not widened to advertise the name
88
+ * form: the schema states the target contract, while the reader is
89
+ * transitionally lenient. A producer validating against the schema is
90
+ * correctly told that names are not the shape to emit.
91
+ */
92
+ customActions?: ElementActionInfo[] | null;
46
93
  /**
47
94
  * Unique element ID within the registry.
48
95
  */
@@ -94,3 +141,72 @@ export interface UIBridgeElement {
94
141
  */
95
142
  visible?: boolean | null;
96
143
  }
144
+ /**
145
+ * Information about a single custom (application-defined) action exposed by a
146
+ * UI Bridge **element**.
147
+ *
148
+ * The element-level twin of [`ComponentActionInfo`], and deliberately the same
149
+ * field vocabulary so a consumer that walks both action planes reads one shape,
150
+ * not two. One field is NOT carried over: `path`. A component action has a
151
+ * resolved per-action invocation path because the SDK annotates one
152
+ * (`/control/component/<componentId>/action/<actionId>`); an element action has
153
+ * no analogue — every element action is invoked through the single
154
+ * `/control/element/<elementId>/action` route with the action name in the body.
155
+ * A field nothing would ever populate is dead schema surface, so it is absent
156
+ * rather than perpetually `null`.
157
+ *
158
+ * ## Why this is an object rather than a name
159
+ *
160
+ * It exists so `effect` has somewhere to live. A bare list of action NAMES is
161
+ * unannotatable: there is no slot on a name for a safety class, so an
162
+ * element-level custom action could not declare itself `destructive` however
163
+ * much its author wanted to. That is not hypothetical — the runner exposes
164
+ * element custom actions that write raw bytes into a live agent PTY, and some
165
+ * of them act on a pane with no visible view.
166
+ *
167
+ * The wire projection is widened FIRST and the annotation lands on top of it.
168
+ * The reverse order ships an UNREACHABLE annotation, which is worse than an
169
+ * absent one: the author believes the delete button is marked, and the walker
170
+ * walks it anyway.
171
+ */
172
+ export interface ElementActionInfo {
173
+ /**
174
+ * Longer description of what the action does.
175
+ */
176
+ description?: string | null;
177
+ /**
178
+ * Safety class of this action: `read`, `write` or `destructive`.
179
+ *
180
+ * **A safety annotation, not a hint.** An autonomous walk MUST NOT fire an
181
+ * action annotated `destructive`; that is the same exclusion the IR already
182
+ * applies to `destructive` transitions when generating auto-regressions.
183
+ * Author-declared, because only the app author knows that a particular
184
+ * custom action sends the keystrokes that end a session.
185
+ *
186
+ * Absent means **unclassified, not safe** — an action nobody has judged
187
+ * must be treated as unknown rather than as `read`. `skip_serializing_if`
188
+ * keeps an un-annotated action ABSENT on the wire rather than defaulting to
189
+ * a class nobody chose.
190
+ */
191
+ effect?: ("read" | "write" | "destructive") | null;
192
+ /**
193
+ * Unique action identifier within the element — the key the action is
194
+ * registered under, and the name `/control/element/<id>/action` is called
195
+ * with.
196
+ */
197
+ id: string;
198
+ /**
199
+ * Human-readable label.
200
+ */
201
+ label?: string | null;
202
+ /**
203
+ * Free-form declaration of the action's parameters, author-supplied on the
204
+ * SDK side and surfaced verbatim. Conventionally a small JSON Schema
205
+ * subset, but the SDK does not constrain the shape, so it is carried
206
+ * through untyped — the same treatment `ElementActionRequest::params` and
207
+ * `ComponentActionInfo::param_schema` get.
208
+ */
209
+ paramSchema?: {
210
+ [k: string]: unknown;
211
+ };
212
+ }
@@ -22,6 +22,7 @@ export type { AgentCommand } from './AgentCommand';
22
22
  export type { AgentCommandError } from './AgentCommandError';
23
23
  export type { AgentCommandVersion } from './AgentCommandVersion';
24
24
  export type { AgentTextUnit } from './AgentTextUnit';
25
+ export type { AgentTextUnitDefault } from './AgentTextUnitDefault';
25
26
  export type { AgentTextUnitError } from './AgentTextUnitError';
26
27
  export type { AgentTextUnitFile } from './AgentTextUnitFile';
27
28
  export type { AgentTextUnitVersion } from './AgentTextUnitVersion';