@qontinui/shared-types 0.5.0 → 0.7.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.
@@ -872,7 +872,7 @@ interface RunnerFindingCodeContext {
872
872
  * disambiguate from `qontinui_types::findings::FindingUserInput`.
873
873
  */
874
874
  interface RunnerFindingUserInput {
875
- input_type: string;
875
+ inputType: string;
876
876
  options?: string[] | null;
877
877
  question: string;
878
878
  [k: string]: unknown;
@@ -872,7 +872,7 @@ interface RunnerFindingCodeContext {
872
872
  * disambiguate from `qontinui_types::findings::FindingUserInput`.
873
873
  */
874
874
  interface RunnerFindingUserInput {
875
- input_type: string;
875
+ inputType: string;
876
876
  options?: string[] | null;
877
877
  question: string;
878
878
  [k: string]: unknown;
@@ -477,7 +477,53 @@ interface IRDocument {
477
477
  synthesizedGroups?: IRGroup[];
478
478
  /** ID of the initial/starting state, if applicable. */
479
479
  initialState?: string;
480
+ /** Per-page API-contract assertions evaluated by the Spec CI harness. */
481
+ apiAssertions?: IRApiCheck[];
480
482
  }
483
+ /**
484
+ * A single API-contract check: issue a request, validate the response.
485
+ */
486
+ interface IRApiCheck {
487
+ id: string;
488
+ description?: string;
489
+ request: {
490
+ method: string;
491
+ path: string;
492
+ headers?: Record<string, string>;
493
+ body?: unknown;
494
+ };
495
+ effect?: "read" | "write" | "destructive";
496
+ assertions: IRApiAssertion[];
497
+ }
498
+ /**
499
+ * API assertion: either a value-level assertion (status_code, json_path, etc.)
500
+ * or a schema-conformance assertion (conforms_to -- Phase 2 placeholder).
501
+ */
502
+ type IRApiAssertion = {
503
+ type: "status_code";
504
+ expected: unknown;
505
+ operator?: string;
506
+ } | {
507
+ type: "json_path";
508
+ jsonPath: string;
509
+ expected: unknown;
510
+ operator?: string;
511
+ } | {
512
+ type: "header";
513
+ headerName: string;
514
+ expected: unknown;
515
+ operator?: string;
516
+ } | {
517
+ type: "body_contains";
518
+ expected: unknown;
519
+ } | {
520
+ type: "response_time";
521
+ expected: unknown;
522
+ operator?: string;
523
+ } | {
524
+ type: "conforms_to";
525
+ schema: string;
526
+ };
481
527
 
482
528
  /**
483
529
  * IR -> WorkflowConfig adapter.
@@ -978,4 +1024,4 @@ interface ProjectLegacyToIROptions {
978
1024
  */
979
1025
  declare function projectLegacyToIR(legacy: LegacySpec, opts?: ProjectLegacyToIROptions): IRDocument;
980
1026
 
981
- export { type AdaptedState, type AdaptedTransition, type AdaptedTransitionAction, type AdaptedWaitAfter, type AdaptedWorkflowConfig, type IRAcceptDriftPolicy, type IRAssertion, type IRAssertionTarget, type IRCrossRef, type IRDocument, type IREffect, type IRElementCriteria, type IRGroup, type IRMetadata, type IRPairingAxis, type IRPairingPolicy, type IRProvenance, type IRState, type IRStateCondition, type IRTransition, type IRTransitionAction, type IRVersion, type IRVisualRef, type IRWaitSpec, type LegacyAssertion, type LegacyAssertionTarget, type LegacyCriteria, type LegacyGroup, type LegacyMetadata, type LegacyProcessStep, type LegacySpec, type LegacyStateMachine, type LegacyStateMachineState, type LegacyTransition, type ProjectLegacyToIROptions, adaptIRDocumentToWorkflowConfig, adaptIRState, adaptIRTransition, adaptIRTransitionAction, projectIRToBundledPage, projectLegacyToIR, projectionVersion };
1027
+ export { type AdaptedState, type AdaptedTransition, type AdaptedTransitionAction, type AdaptedWaitAfter, type AdaptedWorkflowConfig, type IRAcceptDriftPolicy, type IRApiAssertion, type IRApiCheck, type IRAssertion, type IRAssertionTarget, type IRCrossRef, type IRDocument, type IREffect, type IRElementCriteria, type IRGroup, type IRMetadata, type IRPairingAxis, type IRPairingPolicy, type IRProvenance, type IRState, type IRStateCondition, type IRTransition, type IRTransitionAction, type IRVersion, type IRVisualRef, type IRWaitSpec, type LegacyAssertion, type LegacyAssertionTarget, type LegacyCriteria, type LegacyGroup, type LegacyMetadata, type LegacyProcessStep, type LegacySpec, type LegacyStateMachine, type LegacyStateMachineState, type LegacyTransition, type ProjectLegacyToIROptions, adaptIRDocumentToWorkflowConfig, adaptIRState, adaptIRTransition, adaptIRTransitionAction, projectIRToBundledPage, projectLegacyToIR, projectionVersion };
@@ -477,7 +477,53 @@ interface IRDocument {
477
477
  synthesizedGroups?: IRGroup[];
478
478
  /** ID of the initial/starting state, if applicable. */
479
479
  initialState?: string;
480
+ /** Per-page API-contract assertions evaluated by the Spec CI harness. */
481
+ apiAssertions?: IRApiCheck[];
480
482
  }
483
+ /**
484
+ * A single API-contract check: issue a request, validate the response.
485
+ */
486
+ interface IRApiCheck {
487
+ id: string;
488
+ description?: string;
489
+ request: {
490
+ method: string;
491
+ path: string;
492
+ headers?: Record<string, string>;
493
+ body?: unknown;
494
+ };
495
+ effect?: "read" | "write" | "destructive";
496
+ assertions: IRApiAssertion[];
497
+ }
498
+ /**
499
+ * API assertion: either a value-level assertion (status_code, json_path, etc.)
500
+ * or a schema-conformance assertion (conforms_to -- Phase 2 placeholder).
501
+ */
502
+ type IRApiAssertion = {
503
+ type: "status_code";
504
+ expected: unknown;
505
+ operator?: string;
506
+ } | {
507
+ type: "json_path";
508
+ jsonPath: string;
509
+ expected: unknown;
510
+ operator?: string;
511
+ } | {
512
+ type: "header";
513
+ headerName: string;
514
+ expected: unknown;
515
+ operator?: string;
516
+ } | {
517
+ type: "body_contains";
518
+ expected: unknown;
519
+ } | {
520
+ type: "response_time";
521
+ expected: unknown;
522
+ operator?: string;
523
+ } | {
524
+ type: "conforms_to";
525
+ schema: string;
526
+ };
481
527
 
482
528
  /**
483
529
  * IR -> WorkflowConfig adapter.
@@ -978,4 +1024,4 @@ interface ProjectLegacyToIROptions {
978
1024
  */
979
1025
  declare function projectLegacyToIR(legacy: LegacySpec, opts?: ProjectLegacyToIROptions): IRDocument;
980
1026
 
981
- export { type AdaptedState, type AdaptedTransition, type AdaptedTransitionAction, type AdaptedWaitAfter, type AdaptedWorkflowConfig, type IRAcceptDriftPolicy, type IRAssertion, type IRAssertionTarget, type IRCrossRef, type IRDocument, type IREffect, type IRElementCriteria, type IRGroup, type IRMetadata, type IRPairingAxis, type IRPairingPolicy, type IRProvenance, type IRState, type IRStateCondition, type IRTransition, type IRTransitionAction, type IRVersion, type IRVisualRef, type IRWaitSpec, type LegacyAssertion, type LegacyAssertionTarget, type LegacyCriteria, type LegacyGroup, type LegacyMetadata, type LegacyProcessStep, type LegacySpec, type LegacyStateMachine, type LegacyStateMachineState, type LegacyTransition, type ProjectLegacyToIROptions, adaptIRDocumentToWorkflowConfig, adaptIRState, adaptIRTransition, adaptIRTransitionAction, projectIRToBundledPage, projectLegacyToIR, projectionVersion };
1027
+ export { type AdaptedState, type AdaptedTransition, type AdaptedTransitionAction, type AdaptedWaitAfter, type AdaptedWorkflowConfig, type IRAcceptDriftPolicy, type IRApiAssertion, type IRApiCheck, type IRAssertion, type IRAssertionTarget, type IRCrossRef, type IRDocument, type IREffect, type IRElementCriteria, type IRGroup, type IRMetadata, type IRPairingAxis, type IRPairingPolicy, type IRProvenance, type IRState, type IRStateCondition, type IRTransition, type IRTransitionAction, type IRVersion, type IRVisualRef, type IRWaitSpec, type LegacyAssertion, type LegacyAssertionTarget, type LegacyCriteria, type LegacyGroup, type LegacyMetadata, type LegacyProcessStep, type LegacySpec, type LegacyStateMachine, type LegacyStateMachineState, type LegacyTransition, type ProjectLegacyToIROptions, adaptIRDocumentToWorkflowConfig, adaptIRState, adaptIRTransition, adaptIRTransitionAction, projectIRToBundledPage, projectLegacyToIR, projectionVersion };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qontinui/shared-types",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Shared TypeScript types for the Qontinui ecosystem",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -16,6 +16,25 @@ export interface ActionResponse {
16
16
  * Time taken to execute the action in milliseconds.
17
17
  */
18
18
  durationMs: number;
19
+ /**
20
+ * D3 effect-calculus verification: the predicted-vs-observed outcome for
21
+ * this action, present only when a handler effect signature resolved for
22
+ * the `(action, element)` (opt-in; absent otherwise).
23
+ *
24
+ * Carried as an opaque JSON object on the wire, deliberately matching the
25
+ * established lean-wire / rich-SDK split (the SDK's `EffectVerification`
26
+ * has a richer shape than any consumer needs to type). The runner
27
+ * deserializes the sub-shape it asserts on (`outcome` / `cause` /
28
+ * `containment` / `durationMs`) with its own local struct in the
29
+ * `effect_check` step handler, and relays the rest into `result_json`. See
30
+ * `ui-bridge/.../control/effect-types.ts` for the SDK-side producer. Kept
31
+ * opaque here so the nested effect types need no top-level codegen
32
+ * registration (which would couple this crate's bindings to a runner
33
+ * `schema_export.rs` change).
34
+ */
35
+ effectVerification?: {
36
+ [k: string]: unknown;
37
+ };
19
38
  /**
20
39
  * Updated element state after the action (if applicable).
21
40
  */
@@ -12,22 +12,22 @@
12
12
  */
13
13
  export type AppError =
14
14
  | {
15
- app_id: string;
15
+ appId: string;
16
16
  reason: "not-registered";
17
17
  [k: string]: unknown;
18
18
  }
19
19
  | {
20
- app_id: string;
20
+ appId: string;
21
21
  reason: "invalid-app-id";
22
22
  [k: string]: unknown;
23
23
  }
24
24
  | {
25
25
  reason: "invalid-repo-root";
26
- repo_root: string;
26
+ repoRoot: string;
27
27
  [k: string]: unknown;
28
28
  }
29
29
  | {
30
- app_id: string;
30
+ appId: string;
31
31
  reason: "already-registered";
32
32
  [k: string]: unknown;
33
33
  };
@@ -0,0 +1,23 @@
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 entry in the `GET /coord/git-ops/branches` response — the latest
10
+ * branch a given device is on for a given repo, derived from the most
11
+ * recent `checkout`/`branch_create` op per `(device_id, repo)`.
12
+ */
13
+ export interface DeviceBranchSummary {
14
+ branch?: string | null;
15
+ device_id: string;
16
+ /**
17
+ * ISO 8601 timestamp (RFC 3339) of the op this summary was derived from.
18
+ */
19
+ recorded_at: string;
20
+ repo: string;
21
+ sha?: string | null;
22
+ [k: string]: unknown;
23
+ }
@@ -0,0 +1,19 @@
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
+ import type { GitOpRecord } from './GitOpRecord';
9
+
10
+ /**
11
+ * `GET /coord/git-ops/list` + `GET /coord/git-ops/by-session/:id`
12
+ * response envelope. Wrapped in a struct (rather than a bare
13
+ * `Vec<GitOpRecord>`) so the generated TS / Python schemas get a named
14
+ * exported interface rather than an anonymous array alias.
15
+ */
16
+ export interface GitOpListResponse {
17
+ items: GitOpRecord[];
18
+ [k: string]: unknown;
19
+ }
@@ -0,0 +1,28 @@
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 row in `coord.git_ops`. Returned by `GET /coord/git-ops/:op_id`,
10
+ * `GET /coord/git-ops/list`, and `GET /coord/git-ops/by-session/:id`.
11
+ */
12
+ export interface GitOpRecord {
13
+ branch?: string | null;
14
+ device_id: string;
15
+ message?: string | null;
16
+ metadata: unknown;
17
+ op_id: string;
18
+ op_kind: string;
19
+ /**
20
+ * ISO 8601 timestamp (RFC 3339).
21
+ */
22
+ recorded_at: string;
23
+ repo: string;
24
+ session_id: string;
25
+ sha?: string | null;
26
+ tenant_id?: string | null;
27
+ [k: string]: unknown;
28
+ }
@@ -27,6 +27,12 @@ import type { ProposalStatus } from './ProposalStatus';
27
27
  * surface — the projection layer derives the runtime `LegacySpec` from this.
28
28
  */
29
29
  export interface IrPageSpec {
30
+ /**
31
+ * Per-page API-contract assertions evaluated by the Spec CI harness.
32
+ * Phase 1: value-level assertions (status_code, json_path, header,
33
+ * body_contains, response_time). Phase 2 will add schema conformance.
34
+ */
35
+ apiAssertions?: IrApiCheck[] | null;
30
36
  description?: string | null;
31
37
  id: string;
32
38
  initialState?: string | null;
@@ -11,5 +11,11 @@
11
11
  * Ordering mirrors the lifecycle progression:
12
12
  * `Stopped → Starting → (Building) → Running → Healthy → Stopping → Stopped`,
13
13
  * or to `Failed` on any abnormal exit.
14
+ * `ExternallyOwned` is a special out-of-band state meaning "a process is
15
+ * running on our port, but this runner did not spawn it" — used by the
16
+ * process-reconcile feature to surface port squatters without touching the
17
+ * normal lifecycle.
14
18
  */
15
- export type ProcessState = "stopped" | "starting" | "building" | "running" | "healthy" | "stopping" | "failed";
19
+ export type ProcessState =
20
+ | ("stopped" | "starting" | "building" | "running" | "healthy" | "stopping" | "failed")
21
+ | "externally_owned";
@@ -0,0 +1,46 @@
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
+ * `POST /coord/git-ops/record` body. `repo` + `op_kind` are the only
10
+ * required fields; the rest is optional metadata.
11
+ *
12
+ * `device_id` / `session_id` are NOT in this body — coord resolves the
13
+ * tenant from the `X-Qontinui-Tenant-Id` header and reads device/session
14
+ * from the request wrapper (mirroring the federation-report surface).
15
+ */
16
+ export interface RecordGitOpRequest {
17
+ /**
18
+ * Affected branch (null for stash/tag ops).
19
+ */
20
+ branch?: string | null;
21
+ /**
22
+ * Commit message or op description.
23
+ */
24
+ message?: string | null;
25
+ /**
26
+ * Extensible metadata (files_changed, remote, ahead_count, …).
27
+ */
28
+ metadata?: {
29
+ [k: string]: unknown;
30
+ };
31
+ /**
32
+ * One of: `commit | push | checkout | branch_create | merge |
33
+ * rebase | reset | stash | tag` (free-form on the wire).
34
+ */
35
+ op_kind: string;
36
+ /**
37
+ * Repo basename (origin remote URL basename, falling back to the
38
+ * working-dir basename for remote-less clones).
39
+ */
40
+ repo: string;
41
+ /**
42
+ * Resulting commit SHA (null for branch_create/stash).
43
+ */
44
+ sha?: string | null;
45
+ [k: string]: unknown;
46
+ }
@@ -12,7 +12,7 @@
12
12
  * disambiguate from `qontinui_types::findings::FindingUserInput`.
13
13
  */
14
14
  export interface RunnerFindingUserInput {
15
- input_type: string;
15
+ inputType: string;
16
16
  options?: string[] | null;
17
17
  question: string;
18
18
  [k: string]: unknown;
@@ -46,6 +46,19 @@ export interface SpecCheckResult {
46
46
  * Caller-minted snapshot ID. Format: `"scs_" + ULID()`. See §5.8.
47
47
  */
48
48
  snapshotId: string;
49
+ /**
50
+ * JCS-canonicalized SHA-256 of the raw snapshot payload, as
51
+ * `"sha256-<hex>"`. Available on adapter calls that went through
52
+ * `wrap_snapshot` (HTTP / MCP fresh-fetch path); `None` for in-process
53
+ * evaluator calls (validator, distinctness check, supplied-snapshot
54
+ * path that doesn't precompute it) which either don't have raw bytes
55
+ * to hash or chose to skip the JCS round-trip.
56
+ *
57
+ * Consumers that join spec-check results back to a stored snapshot
58
+ * blob should prefer this over `bridge_fingerprint.snapshot_timestamp`
59
+ * (timestamps collide; content hashes don't).
60
+ */
61
+ snapshotSha256?: string | null;
49
62
  /**
50
63
  * Hash of the spec IR document at evaluation time. `"sha256-<hex>"`.
51
64
  */
@@ -0,0 +1,47 @@
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
+ * Canonical error envelope for the qontinui-web Next.js UI-Bridge proxy.
10
+ *
11
+ * The catch-all route at
12
+ * `qontinui-web/frontend/src/app/api/ui-bridge/[...path]/route.ts`
13
+ * short-circuits requests the SDK would otherwise 404 on — and the
14
+ * browser-required routes that can't respond without a live SDK client —
15
+ * to a structured HTTP 503 with this body
16
+ * (`route.ts::noBrowserResponse`):
17
+ *
18
+ * ```json
19
+ * { "success": false, "code": "NO_BROWSER_CONNECTED",
20
+ * "message": "<path> requires a browser SDK client" }
21
+ * ```
22
+ *
23
+ * Modeled as a *generic* error envelope rather than a one-off
24
+ * `NoBrowserConnected` type: the `{success:false, code, message}` shape is
25
+ * the canonical structured-error contract for the whole proxy surface (not
26
+ * just the no-browser path), so a single reusable type is the more
27
+ * scalable and cleaner home. `code` stays a free-form `String` — the
28
+ * discriminator set (currently just `NO_BROWSER_CONNECTED`) is expected to
29
+ * grow, and pinning it to an enum here would force a schemas release on every
30
+ * new proxy error code. `success` is always `false` on this envelope (the
31
+ * success path uses [`UiBridgeHttpHealthEnvelope`] / the SDK's own envelopes).
32
+ */
33
+ export interface UiBridgeHttpErrorEnvelope {
34
+ /**
35
+ * Machine-readable error discriminator (e.g. `"NO_BROWSER_CONNECTED"`).
36
+ */
37
+ code: string;
38
+ /**
39
+ * Human-readable explanation (e.g. `"<path> requires a browser SDK client"`).
40
+ */
41
+ message: string;
42
+ /**
43
+ * Always `false` — this envelope is only emitted on the error path.
44
+ */
45
+ success: boolean;
46
+ [k: string]: unknown;
47
+ }
@@ -0,0 +1,36 @@
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
+ * UI-Bridge metadata block included in the health envelope for the app
10
+ * discovery scanner. Spread of `config.appInfo` plus a fixed `capabilities`
11
+ * list. Present only when the server is configured with `appInfo` (the
12
+ * qontinui-web proxy always is — `route.ts` sets `appId: "qontinui-web"`).
13
+ */
14
+ export interface UiBridgeHttpHealthAppInfo {
15
+ /**
16
+ * Stable app identifier (e.g. `"qontinui-web"`).
17
+ */
18
+ appId: string;
19
+ /**
20
+ * Human-readable app name.
21
+ */
22
+ appName: string;
23
+ /**
24
+ * App surface type (e.g. `"web"`).
25
+ */
26
+ appType: string;
27
+ /**
28
+ * Advertised UI-Bridge capabilities (e.g. `["control","renderLog","debug"]`).
29
+ */
30
+ capabilities: string[];
31
+ /**
32
+ * UI framework (e.g. `"nextjs"`).
33
+ */
34
+ framework: string;
35
+ [k: string]: unknown;
36
+ }
@@ -0,0 +1,30 @@
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
+ * Inner `data` payload of the UI-Bridge SDK HTTP health envelope.
10
+ *
11
+ * Emitted by the SDK's relay-transport handler for `GET /health`
12
+ * (`@qontinui/ui-bridge/server` `handleRelayRoute`, `nextjs.ts`): the
13
+ * `responsive` + `lastHeartbeat` fields plus a spread of the relay's
14
+ * `TransportDiagnostics`. Only `responsive` and `lastHeartbeat` are modeled
15
+ * explicitly here — the diagnostics spread (pendingCommandCount, connectedTabs,
16
+ * buildId, …) is intentionally left open (no `additionalProperties: false`,
17
+ * which schemars omits by default) so the diagnostics surface can evolve
18
+ * without a schemas release while the two stable health signals stay typed.
19
+ */
20
+ export interface UiBridgeHttpHealthData {
21
+ /**
22
+ * Max heartbeat timestamp (ms since epoch) across all tabs; `0` when none.
23
+ */
24
+ lastHeartbeat: number;
25
+ /**
26
+ * True when at least one connected tab has a fresh heartbeat.
27
+ */
28
+ responsive: boolean;
29
+ [k: string]: unknown;
30
+ }
@@ -0,0 +1,44 @@
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
+ import type { UiBridgeHttpHealthAppInfo } from './UiBridgeHttpHealthAppInfo';
9
+ import type { UiBridgeHttpHealthData } from './UiBridgeHttpHealthData';
10
+
11
+ /**
12
+ * Canonical success envelope for `GET /api/ui-bridge/health`.
13
+ *
14
+ * Distinct from [`UiBridgeResponseEnvelope`]: the HTTP health envelope has
15
+ * no `requestId` / `type`, and carries an app-discovery `uiBridge` block.
16
+ * Wire shape (`nextjs.ts::handleRelayRoute`):
17
+ *
18
+ * ```json
19
+ * { "success": true,
20
+ * "data": { "responsive": false, "lastHeartbeat": 0, ...diagnostics },
21
+ * "timestamp": 1713200000000,
22
+ * "uiBridge": { "appId": "qontinui-web", ..., "capabilities": [...] } }
23
+ * ```
24
+ *
25
+ * `uiBridge` is optional (omitted when the server has no `appInfo`); the
26
+ * other three fields are always present.
27
+ */
28
+ export interface UiBridgeHttpHealthEnvelope {
29
+ data: UiBridgeHttpHealthData;
30
+ /**
31
+ * Always `true` on the health path.
32
+ */
33
+ success: boolean;
34
+ /**
35
+ * Server-side timestamp (ms since epoch) of when the response was produced.
36
+ */
37
+ timestamp: number;
38
+ /**
39
+ * App-discovery metadata; present only when the server is configured
40
+ * with `appInfo`.
41
+ */
42
+ uiBridge?: UiBridgeHttpHealthAppInfo | null;
43
+ [k: string]: unknown;
44
+ }
@@ -93,6 +93,7 @@ export type { DagCancelStep } from './DagCancelStep';
93
93
  export type { DagLoopStep } from './DagLoopStep';
94
94
  export type { DecomposerConfig } from './DecomposerConfig';
95
95
  export type { DevSeedFindingPayload } from './DevSeedFindingPayload';
96
+ export type { DeviceBranchSummary } from './DeviceBranchSummary';
96
97
  export type { DiagnosePhaseConfig } from './DiagnosePhaseConfig';
97
98
  export type { DiagnosticResult } from './DiagnosticResult';
98
99
  export type { DiscoveredElement } from './DiscoveredElement';
@@ -170,6 +171,8 @@ export type { FlowEvent } from './FlowEvent';
170
171
  export type { FullRunnerStep } from './FullRunnerStep';
171
172
  export type { GUIElementChunk } from './GUIElementChunk';
172
173
  export type { GateEvaluationResult } from './GateEvaluationResult';
174
+ export type { GitOpListResponse } from './GitOpListResponse';
175
+ export type { GitOpRecord } from './GitOpRecord';
173
176
  export type { HealthCheckUrl } from './HealthCheckUrl';
174
177
  export type { HistoricalActionQuery } from './HistoricalActionQuery';
175
178
  export type { HistoricalActionResult } from './HistoricalActionResult';
@@ -290,6 +293,7 @@ export type { RagProgressEvent } from './RagProgressEvent';
290
293
  export type { ReadConfigResponse } from './ReadConfigResponse';
291
294
  export type { RecommendationReviewDecisionPayload } from './RecommendationReviewDecisionPayload';
292
295
  export type { RecommendedState } from './RecommendedState';
296
+ export type { RecordGitOpRequest } from './RecordGitOpRequest';
293
297
  export type { ReflectionFixOutput } from './ReflectionFixOutput';
294
298
  export type { Region } from './Region';
295
299
  export type { RegisterAppRequest } from './RegisterAppRequest';
@@ -441,6 +445,10 @@ export type { UiBridgeAction } from './UiBridgeAction';
441
445
  export type { UiBridgeAssertType } from './UiBridgeAssertType';
442
446
  export type { UiBridgeComparisonMode } from './UiBridgeComparisonMode';
443
447
  export type { UiBridgeDesignAuditStep } from './UiBridgeDesignAuditStep';
448
+ export type { UiBridgeHttpErrorEnvelope } from './UiBridgeHttpErrorEnvelope';
449
+ export type { UiBridgeHttpHealthAppInfo } from './UiBridgeHttpHealthAppInfo';
450
+ export type { UiBridgeHttpHealthData } from './UiBridgeHttpHealthData';
451
+ export type { UiBridgeHttpHealthEnvelope } from './UiBridgeHttpHealthEnvelope';
444
452
  export type { UiBridgeRequestEnvelope } from './UiBridgeRequestEnvelope';
445
453
  export type { UiBridgeResponseEnvelope } from './UiBridgeResponseEnvelope';
446
454
  export type { UiBridgeSeverity } from './UiBridgeSeverity';
@@ -111,4 +111,39 @@ export interface IRDocument {
111
111
 
112
112
  /** ID of the initial/starting state, if applicable. */
113
113
  initialState?: string;
114
+
115
+ /** Per-page API-contract assertions evaluated by the Spec CI harness. */
116
+ apiAssertions?: IRApiCheck[];
114
117
  }
118
+
119
+ // ---------------------------------------------------------------------------
120
+ // API-contract checks (Spec CI harness)
121
+ // ---------------------------------------------------------------------------
122
+
123
+ /**
124
+ * A single API-contract check: issue a request, validate the response.
125
+ */
126
+ export interface IRApiCheck {
127
+ id: string;
128
+ description?: string;
129
+ request: {
130
+ method: string;
131
+ path: string;
132
+ headers?: Record<string, string>;
133
+ body?: unknown;
134
+ };
135
+ effect?: "read" | "write" | "destructive";
136
+ assertions: IRApiAssertion[];
137
+ }
138
+
139
+ /**
140
+ * API assertion: either a value-level assertion (status_code, json_path, etc.)
141
+ * or a schema-conformance assertion (conforms_to -- Phase 2 placeholder).
142
+ */
143
+ export type IRApiAssertion =
144
+ | { type: "status_code"; expected: unknown; operator?: string }
145
+ | { type: "json_path"; jsonPath: string; expected: unknown; operator?: string }
146
+ | { type: "header"; headerName: string; expected: unknown; operator?: string }
147
+ | { type: "body_contains"; expected: unknown }
148
+ | { type: "response_time"; expected: unknown; operator?: string }
149
+ | { type: "conforms_to"; schema: string };