@miadi/tide-contract 0.1.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/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # @miadi/tide-contract
2
+
3
+ Schema-first contract for the Tide operator cockpit boundary.
4
+
5
+ This package is the shared covenant between:
6
+
7
+ - the IronSilk `tide` runtime,
8
+ - the `@miadi/tide` TypeScript client,
9
+ - the `/api/tide/*` Next.js routes,
10
+ - and the cockpit UI at `/tide`.
11
+
12
+ ## Current shape
13
+
14
+ - `schema/tide-api.schema.json` is the planned source of truth.
15
+ - `src/index.ts` carries hand-written TypeScript types for this scaffold.
16
+ - Future work should generate the TypeScript types from the schema and validate IronSilk runtime payloads with Python `jsonschema`.
17
+
18
+ ## Drift posture
19
+
20
+ The intended CI shape is:
21
+
22
+ 1. Generate TypeScript types from `schema/tide-api.schema.json`.
23
+ 2. Compare generated output against committed types.
24
+ 3. Validate runtime fixture JSON from IronSilk.
25
+ 4. Fail when the contract, client, routes, and runtime drift.
26
+
27
+ Ref: jgwill/Miadi#378
@@ -0,0 +1,81 @@
1
+ export declare const TIDE_API_SCHEMA_ID = "https://miadi.dev/schemas/tide-api.schema.json";
2
+ export interface TerminalContext {
3
+ tmux_pane: string;
4
+ pid: number;
5
+ cwd: string;
6
+ domain_id: string | null;
7
+ domain_confidence: number;
8
+ is_active: boolean;
9
+ recent_commands: string[];
10
+ captured_at: string;
11
+ }
12
+ export interface WindowEvent {
13
+ window_id?: string;
14
+ app?: string;
15
+ title?: string;
16
+ domain_id?: string | null;
17
+ domain_confidence?: number;
18
+ [key: string]: unknown;
19
+ }
20
+ export interface ContextSnapshot {
21
+ snapshot_id: string;
22
+ timestamp: string;
23
+ domain_summary: Record<string, number>;
24
+ terminals: TerminalContext[];
25
+ desktop_windows?: WindowEvent[];
26
+ editor_buffers?: string[];
27
+ }
28
+ export interface TideHealthResult {
29
+ ok: boolean;
30
+ transport: {
31
+ selected: "socket" | "cli";
32
+ effective: "socket" | "cli";
33
+ fallback: "cli";
34
+ socketPath: string;
35
+ socketAvailable: boolean;
36
+ };
37
+ daemon: {
38
+ pinged: boolean;
39
+ ok: boolean;
40
+ error: string | null;
41
+ };
42
+ timestamp: string;
43
+ }
44
+ export interface TideTerminalTarget {
45
+ terminal_id: string;
46
+ session_id: string;
47
+ session_name: string;
48
+ window_id: string;
49
+ window_name: string;
50
+ pane_id: string;
51
+ cwd: string;
52
+ pane_active: boolean;
53
+ session_attached: number;
54
+ pid: number;
55
+ command: string;
56
+ domain_id: string | null;
57
+ domain_confidence: number;
58
+ attach_command: string;
59
+ switch_command: string;
60
+ select_pane_command: string;
61
+ }
62
+ export type TideTerminalsResult = TideTerminalTarget[];
63
+ export interface TideDetectMatch {
64
+ domain_id: string;
65
+ confidence: number;
66
+ signal_type: string;
67
+ source_detail: string;
68
+ }
69
+ export type TideDetectResult = TideDetectMatch | null;
70
+ export interface TidePeekResult {
71
+ pane?: string;
72
+ lines?: string[];
73
+ [key: string]: unknown;
74
+ }
75
+ export interface TideSteerResult {
76
+ [key: string]: unknown;
77
+ }
78
+ export interface TideSendResult {
79
+ [key: string]: unknown;
80
+ }
81
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ // Hand-written scaffold for the Tide API contract.
2
+ // TODO(jgwill/Miadi#378): generate these types from schema/tide-api.schema.json.
3
+ export const TIDE_API_SCHEMA_ID = "https://miadi.dev/schemas/tide-api.schema.json";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,iFAAiF;AAEjF,MAAM,CAAC,MAAM,kBAAkB,GAAG,gDAAgD,CAAA"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@miadi/tide-contract",
3
+ "version": "0.1.0",
4
+ "description": "Schema-first Tide API contract shared by Miadi and the IronSilk tide runtime.",
5
+ "license": "MIT",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./schema/tide-api.schema.json": "./schema/tide-api.schema.json",
18
+ "./package.json": "./package.json"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "schema",
23
+ "README.md"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "type-check": "tsc --noEmit"
28
+ },
29
+ "devDependencies": {
30
+ "typescript": "^5.4.0"
31
+ }
32
+ }
@@ -0,0 +1,180 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://miadi.dev/schemas/tide-api.schema.json",
4
+ "title": "Tide API Contract",
5
+ "description": "Schema-first contract for the Miadi Tide operator cockpit boundary.",
6
+ "type": "object",
7
+ "$defs": {
8
+ "terminalContext": {
9
+ "type": "object",
10
+ "additionalProperties": false,
11
+ "required": [
12
+ "tmux_pane",
13
+ "pid",
14
+ "cwd",
15
+ "domain_id",
16
+ "domain_confidence",
17
+ "is_active",
18
+ "recent_commands",
19
+ "captured_at"
20
+ ],
21
+ "properties": {
22
+ "tmux_pane": { "type": "string", "pattern": "^%?[0-9]+$" },
23
+ "pid": { "type": "integer" },
24
+ "cwd": { "type": "string" },
25
+ "domain_id": { "type": ["string", "null"] },
26
+ "domain_confidence": { "type": "integer", "minimum": 0, "maximum": 100 },
27
+ "is_active": { "type": "boolean" },
28
+ "recent_commands": { "type": "array", "items": { "type": "string" } },
29
+ "captured_at": { "type": "string" }
30
+ }
31
+ },
32
+ "windowEvent": {
33
+ "type": "object",
34
+ "additionalProperties": true,
35
+ "properties": {
36
+ "window_id": { "type": "string" },
37
+ "app": { "type": "string" },
38
+ "title": { "type": "string" },
39
+ "domain_id": { "type": ["string", "null"] },
40
+ "domain_confidence": { "type": "integer", "minimum": 0, "maximum": 100 }
41
+ }
42
+ },
43
+ "contextSnapshot": {
44
+ "type": "object",
45
+ "additionalProperties": false,
46
+ "required": ["snapshot_id", "timestamp", "domain_summary", "terminals"],
47
+ "properties": {
48
+ "snapshot_id": { "type": "string" },
49
+ "timestamp": { "type": "string" },
50
+ "domain_summary": {
51
+ "type": "object",
52
+ "additionalProperties": { "type": "integer", "minimum": 0 }
53
+ },
54
+ "terminals": {
55
+ "type": "array",
56
+ "items": { "$ref": "#/$defs/terminalContext" }
57
+ },
58
+ "desktop_windows": {
59
+ "type": "array",
60
+ "items": { "$ref": "#/$defs/windowEvent" }
61
+ },
62
+ "editor_buffers": {
63
+ "type": "array",
64
+ "items": { "type": "string" }
65
+ }
66
+ }
67
+ },
68
+ "healthResult": {
69
+ "type": "object",
70
+ "additionalProperties": false,
71
+ "required": ["ok", "transport", "daemon", "timestamp"],
72
+ "properties": {
73
+ "ok": { "type": "boolean" },
74
+ "transport": {
75
+ "type": "object",
76
+ "additionalProperties": false,
77
+ "required": [
78
+ "selected",
79
+ "effective",
80
+ "fallback",
81
+ "socketPath",
82
+ "socketAvailable"
83
+ ],
84
+ "properties": {
85
+ "selected": { "enum": ["socket", "cli"] },
86
+ "effective": { "enum": ["socket", "cli"] },
87
+ "fallback": { "const": "cli" },
88
+ "socketPath": { "type": "string" },
89
+ "socketAvailable": { "type": "boolean" }
90
+ }
91
+ },
92
+ "daemon": {
93
+ "type": "object",
94
+ "additionalProperties": false,
95
+ "required": ["pinged", "ok", "error"],
96
+ "properties": {
97
+ "pinged": { "type": "boolean" },
98
+ "ok": { "type": "boolean" },
99
+ "error": { "type": ["string", "null"] }
100
+ }
101
+ },
102
+ "timestamp": { "type": "string" }
103
+ }
104
+ },
105
+ "terminalTarget": {
106
+ "type": "object",
107
+ "additionalProperties": false,
108
+ "required": [
109
+ "terminal_id",
110
+ "session_id",
111
+ "session_name",
112
+ "window_id",
113
+ "window_name",
114
+ "pane_id",
115
+ "cwd",
116
+ "pane_active",
117
+ "session_attached",
118
+ "pid",
119
+ "command",
120
+ "domain_id",
121
+ "domain_confidence",
122
+ "attach_command",
123
+ "switch_command",
124
+ "select_pane_command"
125
+ ],
126
+ "properties": {
127
+ "terminal_id": { "type": "string" },
128
+ "session_id": { "type": "string" },
129
+ "session_name": { "type": "string" },
130
+ "window_id": { "type": "string" },
131
+ "window_name": { "type": "string" },
132
+ "pane_id": { "type": "string", "pattern": "^%?[0-9]+$" },
133
+ "cwd": { "type": "string" },
134
+ "pane_active": { "type": "boolean" },
135
+ "session_attached": { "type": "integer", "minimum": 0 },
136
+ "pid": { "type": "integer" },
137
+ "command": { "type": "string" },
138
+ "domain_id": { "type": ["string", "null"] },
139
+ "domain_confidence": { "type": "integer", "minimum": 0, "maximum": 100 },
140
+ "attach_command": { "type": "string" },
141
+ "switch_command": { "type": "string" },
142
+ "select_pane_command": { "type": "string" }
143
+ }
144
+ },
145
+ "terminalsResult": {
146
+ "type": "array",
147
+ "items": { "$ref": "#/$defs/terminalTarget" }
148
+ },
149
+ "detectMatch": {
150
+ "type": "object",
151
+ "additionalProperties": false,
152
+ "required": ["domain_id", "confidence", "signal_type", "source_detail"],
153
+ "properties": {
154
+ "domain_id": { "type": "string" },
155
+ "confidence": { "type": "integer", "minimum": 0, "maximum": 100 },
156
+ "signal_type": { "type": "string" },
157
+ "source_detail": { "type": "string" }
158
+ }
159
+ },
160
+ "detectResult": {
161
+ "oneOf": [
162
+ { "$ref": "#/$defs/detectMatch" },
163
+ { "type": "null" }
164
+ ]
165
+ },
166
+ "looseOperatorResult": {
167
+ "type": "object",
168
+ "additionalProperties": true
169
+ }
170
+ },
171
+ "properties": {
172
+ "context": { "$ref": "#/$defs/contextSnapshot" },
173
+ "health": { "$ref": "#/$defs/healthResult" },
174
+ "terminals": { "$ref": "#/$defs/terminalsResult" },
175
+ "detect": { "$ref": "#/$defs/detectResult" },
176
+ "peek": { "$ref": "#/$defs/looseOperatorResult" },
177
+ "steer": { "$ref": "#/$defs/looseOperatorResult" },
178
+ "send": { "$ref": "#/$defs/looseOperatorResult" }
179
+ }
180
+ }