@agent-watch/protocol 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.
Files changed (50) hide show
  1. package/README.md +322 -0
  2. package/dist/index.d.ts +15 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +35 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/schemas/action.schema.json +71 -0
  7. package/dist/schemas/approval-request.schema.json +36 -0
  8. package/dist/schemas/approval-response.schema.json +36 -0
  9. package/dist/schemas/entitlement-request.schema.json +25 -0
  10. package/dist/schemas/entitlement-response.schema.json +38 -0
  11. package/dist/schemas/hook-input.schema.json +34 -0
  12. package/dist/schemas/hook-output.schema.json +20 -0
  13. package/dist/schemas/push.schema.json +30 -0
  14. package/dist/schemas/registration.schema.json +30 -0
  15. package/dist/schemas/session.schema.json +47 -0
  16. package/dist/schemas/subscription-event.schema.json +41 -0
  17. package/dist/schemas/subscription-status.schema.json +46 -0
  18. package/dist/types/action.d.ts +34 -0
  19. package/dist/types/action.d.ts.map +1 -0
  20. package/dist/types/action.js +6 -0
  21. package/dist/types/action.js.map +1 -0
  22. package/dist/types/approval.d.ts +30 -0
  23. package/dist/types/approval.d.ts.map +1 -0
  24. package/dist/types/approval.js +6 -0
  25. package/dist/types/approval.js.map +1 -0
  26. package/dist/types/hook.d.ts +24 -0
  27. package/dist/types/hook.d.ts.map +1 -0
  28. package/dist/types/hook.js +6 -0
  29. package/dist/types/hook.js.map +1 -0
  30. package/dist/types/push.d.ts +15 -0
  31. package/dist/types/push.d.ts.map +1 -0
  32. package/dist/types/push.js +6 -0
  33. package/dist/types/push.js.map +1 -0
  34. package/dist/types/registration.d.ts +15 -0
  35. package/dist/types/registration.d.ts.map +1 -0
  36. package/dist/types/registration.js +6 -0
  37. package/dist/types/registration.js.map +1 -0
  38. package/dist/types/session.d.ts +21 -0
  39. package/dist/types/session.d.ts.map +1 -0
  40. package/dist/types/session.js +6 -0
  41. package/dist/types/session.js.map +1 -0
  42. package/dist/types/subscription.d.ts +58 -0
  43. package/dist/types/subscription.d.ts.map +1 -0
  44. package/dist/types/subscription.js +6 -0
  45. package/dist/types/subscription.js.map +1 -0
  46. package/dist/validators.d.ts +36 -0
  47. package/dist/validators.d.ts.map +1 -0
  48. package/dist/validators.js +92 -0
  49. package/dist/validators.js.map +1 -0
  50. package/package.json +37 -0
package/README.md ADDED
@@ -0,0 +1,322 @@
1
+ # @agentwatch/protocol
2
+
3
+ The single authoritative definition of every message type in the AgentWatch protocol. TypeScript components import types and validators at compile time and runtime. Mobile apps use this repository as their reference for implementing equivalent Swift and Kotlin types.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @agentwatch/protocol
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Importing Types
14
+
15
+ ```typescript
16
+ import {
17
+ Session,
18
+ AgentAction,
19
+ ApprovalRequest,
20
+ ApprovalResponse,
21
+ SubscriptionStatus,
22
+ validate
23
+ } from '@agentwatch/protocol';
24
+
25
+ // Use types for type safety
26
+ const session: Session = {
27
+ id: 'sess_123',
28
+ ide: 'vscode',
29
+ cwd: '/home/user/project',
30
+ startedAt: '2026-03-21T10:00:00Z',
31
+ status: 'active',
32
+ };
33
+ ```
34
+
35
+ ### Validating Data
36
+
37
+ ```typescript
38
+ import { validate } from '@agentwatch/protocol';
39
+
40
+ // Validate incoming data
41
+ const result = validate.session(unknownData);
42
+
43
+ if (result.success) {
44
+ // Data is valid and typed
45
+ console.log(`Session ${result.data.id} started at ${result.data.startedAt}`);
46
+ } else {
47
+ // Validation failed with detailed errors
48
+ result.errors.forEach(err => {
49
+ console.error(`${err.field}: ${err.message}`);
50
+ });
51
+ }
52
+ ```
53
+
54
+ ## Core Type Definitions
55
+
56
+ ### Session
57
+
58
+ A single agent conversation — tracks ID, IDE, working directory, timestamps, and status.
59
+
60
+ **Fields:**
61
+ - `id` (string, required): Unique session identifier
62
+ - `ide` (string, required): IDE name (e.g., "vscode", "cursor", "windsurf")
63
+ - `cwd` (string, required): Current working directory at session start
64
+ - `startedAt` (string, required): ISO 8601 timestamp when session started
65
+ - `endedAt` (string, optional): ISO 8601 timestamp when session ended
66
+ - `status` (string, required): Current status — `"active" | "completed" | "failed" | "cancelled"`
67
+ - `pairingId` (string, optional): Pairing ID if session is paired to a device
68
+
69
+ **Used by:** All components
70
+
71
+ ### AgentAction
72
+
73
+ A single agent tool call — tracks action details, tier, and outcome.
74
+
75
+ **Fields:**
76
+ - `id` (string, required): Unique action identifier
77
+ - `sessionId` (string, required): Session this action belongs to
78
+ - `toolName` (string, required): Tool name (e.g., "read_file", "run_in_terminal")
79
+ - `input` (object, required): Tool input parameters as JSON object
80
+ - `summary` (string, required): Human-readable summary of the action
81
+ - `tier` (string, required): Action tier — `"read" | "write" | "run"`
82
+ - `timestamp` (string, required): ISO 8601 timestamp when action was requested
83
+ - `outcome` (string, optional): Action outcome — `"allowed" | "denied" | "auto_approved"`
84
+ - `autoApprovalRecord` (object, optional): Auto-approval details if outcome is `auto_approved`
85
+ - `reason` (string, required): Reason for auto-approval — `"limit_reached"`
86
+ - `limitType` (string, required): Type of limit reached — `"daily" | "monthly"`
87
+ - `resetDate` (string, required): ISO 8601 timestamp when limit resets
88
+
89
+ **Used by:** Daemon, hook, relay
90
+
91
+ ### ApprovalRequest
92
+
93
+ Pending decision requiring user approval.
94
+
95
+ **Fields:**
96
+ - `approvalId` (string, required): Unique approval request identifier
97
+ - `sessionId` (string, required): Session this approval belongs to
98
+ - `action` (AgentAction, required): The action requiring approval
99
+ - `precedingActions` (AgentAction[], required): Previous actions in this session for context
100
+ - `timeout` (string, required): ISO 8601 timestamp when request expires
101
+
102
+ **Used by:** Daemon, relay, phone apps
103
+
104
+ ### ApprovalResponse
105
+
106
+ User decision on an approval request.
107
+
108
+ **Fields:**
109
+ - `approvalId` (string, required): Approval request ID this response is for
110
+ - `sessionId` (string, required): Session ID
111
+ - `decision` (string, required): User's decision — `"allow" | "deny"`
112
+ - `signature` (string, required): HMAC signature for authenticity verification
113
+ - `timestamp` (string, required): ISO 8601 timestamp when decision was made
114
+
115
+ **Used by:** Phone apps, daemon
116
+
117
+ ### PushPayload
118
+
119
+ Relay envelope for encrypted messages sent via FCM/APNs.
120
+
121
+ **Fields:**
122
+ - `type` (string, required): Payload type — `"approval_request" | "session_start" | "session_end" | "subscription_event"`
123
+ - `sessionId` (string, optional): Session ID (if applicable)
124
+ - `pairingId` (string, required): Pairing ID for routing
125
+ - `encryptedBlob` (string, required): Encrypted message blob (base64 encoded)
126
+
127
+ **Used by:** Daemon, relay
128
+
129
+ ### DeviceRegistration
130
+
131
+ Phone app registration data for push notifications.
132
+
133
+ **Fields:**
134
+ - `deviceToken` (string, required): FCM or APNs device token
135
+ - `platform` (string, required): Platform type — `"ios" | "android"`
136
+ - `sessionId` (string, optional): Current session ID (if registering during session)
137
+ - `pairingId` (string, required): Pairing ID for device linkage
138
+
139
+ **Used by:** Phone apps, relay
140
+
141
+ ### HookInput
142
+
143
+ IDE stdin payload sent to the hook script.
144
+
145
+ **Fields:**
146
+ - `eventName` (string, required): Event being reported — `"tool_call" | "session_start" | "session_end"`
147
+ - `sessionId` (string, required): Session ID
148
+ - `cwd` (string, required): Current working directory
149
+ - `toolName` (string, optional): Tool name (for tool_call events)
150
+ - `toolInput` (object, optional): Tool input parameters (for tool_call events)
151
+
152
+ **Used by:** Hook script
153
+
154
+ ### HookOutput
155
+
156
+ Hook response sent back to the IDE.
157
+
158
+ **Fields:**
159
+ - `decision` (string, required): Decision for the hook event — `"allow" | "deny"`
160
+ - `reason` (string, optional): Optional reason for denial
161
+
162
+ **Used by:** Hook script
163
+
164
+ ## Subscription Type Definitions (v2)
165
+
166
+ ### SubscriptionStatus
167
+
168
+ User's current subscription and entitlement status.
169
+
170
+ **Fields:**
171
+ - `plan` (string, required): Current subscription plan — `"free" | "pro" | "enterprise"`
172
+ - `approvalCount` (number, required): Current approval count in period
173
+ - `approvalLimit` (number | null, required): Approval limit for current plan (null = unlimited)
174
+ - `resetDate` (string, required): ISO 8601 timestamp when approval count resets
175
+ - `deviceCount` (number, required): Number of paired devices
176
+ - `featureFlags` (string[], required): Enabled feature flags — `"unlimited_approvals" | "priority_support" | "custom_branding"`
177
+
178
+ **Used by:** Relay GET /status, daemon, phone apps
179
+
180
+ ### EntitlementRequest
181
+
182
+ Request to check if a user is entitled to perform an action.
183
+
184
+ **Fields:**
185
+ - `pairingId` (string, required): Pairing ID making the request
186
+ - `accountId` (string, required): Account ID for the user
187
+ - `actionType` (string, required): Action type being checked
188
+
189
+ **Used by:** Relay to accounts service
190
+
191
+ ### EntitlementResponse
192
+
193
+ Result of an entitlement check.
194
+
195
+ **Fields:**
196
+ - `decision` (string, required): Whether action is allowed — `"allowed" | "denied" | "soft_limit_warning"`
197
+ - `errorCode` (string, optional): Error code if denied — `"limit_exceeded" | "plan_downgraded" | "account_suspended" | "invalid_pairing"`
198
+ - `count` (number, required): Current count in period
199
+ - `limit` (number | null, required): Limit for current plan (null = unlimited)
200
+ - `resetDate` (string, required): ISO 8601 timestamp when count resets
201
+
202
+ **Used by:** Accounts service to relay
203
+
204
+ ### SubscriptionEvent
205
+
206
+ FCM message for subscription limit events.
207
+
208
+ **Fields:**
209
+ - `eventType` (string, required): Event type — `"limit_reached" | "limit_warning" | "plan_upgraded" | "plan_downgraded"`
210
+ - `limitType` (string, optional): Limit type for limit events — `"daily" | "monthly"`
211
+ - `count` (number, optional): Current count for limit events
212
+ - `limit` (number, optional): Limit value for limit events
213
+ - `resetDate` (string, optional): ISO 8601 timestamp when count resets
214
+ - `newPlan` (string, optional): New plan for upgrade/downgrade events — `"free" | "pro" | "enterprise"`
215
+
216
+ **Used by:** Relay to phone apps
217
+
218
+ ### AutoApprovalRecord
219
+
220
+ Embedded in AgentAction when outcome is `auto_approved`. Determines whether the session timeline shows the amber auto-approval indicator.
221
+
222
+ **Fields:**
223
+ - `reason` (string, required): Reason for auto-approval — `"limit_reached"`
224
+ - `limitType` (string, required): Type of limit that was reached — `"daily" | "monthly"`
225
+ - `resetDate` (string, required): ISO 8601 timestamp when the limit resets
226
+
227
+ **Used by:** Daemon, phone apps
228
+
229
+ ## Mobile Implementation Reference
230
+
231
+ This section documents all protocol types in plain language for iOS (Swift) and Android (Kotlin) developers.
232
+
233
+ ### Implementing Types in Swift
234
+
235
+ Use `Codable` structs with snake_case to camelCase mapping:
236
+
237
+ ```swift
238
+ struct Session: Codable {
239
+ let id: String
240
+ let ide: String
241
+ let cwd: String
242
+ let startedAt: String
243
+ let endedAt: String?
244
+ let status: SessionStatus
245
+ let pairingId: String?
246
+
247
+ enum CodingKeys: String, CodingKey {
248
+ case id, ide, cwd, status
249
+ case startedAt = "startedAt"
250
+ case endedAt = "endedAt"
251
+ case pairingId = "pairingId"
252
+ }
253
+ }
254
+
255
+ enum SessionStatus: String, Codable {
256
+ case active, completed, failed, cancelled
257
+ }
258
+ ```
259
+
260
+ ### Implementing Types in Kotlin
261
+
262
+ Use `data class` with `@SerializedName` annotations:
263
+
264
+ ```kotlin
265
+ data class Session(
266
+ @SerializedName("id") val id: String,
267
+ @SerializedName("ide") val ide: String,
268
+ @SerializedName("cwd") val cwd: String,
269
+ @SerializedName("startedAt") val startedAt: String,
270
+ @SerializedName("endedAt") val endedAt: String?,
271
+ @SerializedName("status") val status: SessionStatus,
272
+ @SerializedName("pairingId") val pairingId: String?
273
+ )
274
+
275
+ enum class SessionStatus {
276
+ @SerializedName("active") ACTIVE,
277
+ @SerializedName("completed") COMPLETED,
278
+ @SerializedName("failed") FAILED,
279
+ @SerializedName("cancelled") CANCELLED
280
+ }
281
+ ```
282
+
283
+ ### Important Implementation Notes
284
+
285
+ 1. **All timestamps are ISO 8601 strings** — Parse them using appropriate date formatters:
286
+ - Swift: `ISO8601DateFormatter()`
287
+ - Kotlin: `SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)`
288
+
289
+ 2. **Enum values are exact strings** — Never use free-form strings. All plan names, error codes, event types, and resolution types are enums.
290
+
291
+ 3. **AutoApprovalRecord is critical** — When an `AgentAction` has `outcome = "auto_approved"` and includes an `autoApprovalRecord`, the mobile UI must show the amber auto-approval indicator on the timeline.
292
+
293
+ 4. **Nested objects** — `ApprovalRequest` contains an `action` field (type `AgentAction`) and `precedingActions` array (`AgentAction[]`). Implement these as nested types.
294
+
295
+ 5. **Optional vs Required** — Fields marked optional in the TypeScript types should be nullable in Swift/Kotlin. All other fields are required.
296
+
297
+ ## Validation
298
+
299
+ All types have strict JSON schema validators with:
300
+ - `additionalProperties: false` — Rejects unexpected fields
301
+ - Explicit `maxLength` on all string fields
302
+ - Required fields explicitly listed
303
+ - Enum constraints on all categorical values
304
+
305
+ ## Versioning
306
+
307
+ This package follows semantic versioning:
308
+
309
+ | Version Bump | Meaning | Coordination Required |
310
+ |--------------|---------|----------------------|
311
+ | **Major** | Breaking change — field removed, type changed, required field added | Coordinated release: protocol + desktop + relay + mobile apps |
312
+ | **Minor** | New optional fields added — backwards compatible | Desktop and relay update independently. Mobile adds new types. |
313
+ | **Patch** | Documentation or validator fixes only — no API change | Any component updates independently |
314
+
315
+ ## Contributing
316
+
317
+ See [CHANGELOG.md](./CHANGELOG.md) for version history. Every release includes date, change description, affected components, and migration guides for major versions.
318
+
319
+ ## License
320
+
321
+ MIT
322
+
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @agentwatch/protocol
3
+ *
4
+ * Single authoritative definition of every message type in the AgentWatch protocol.
5
+ * TypeScript components import types and validators at compile time and runtime.
6
+ */
7
+ export * from './types/session';
8
+ export * from './types/action';
9
+ export * from './types/approval';
10
+ export * from './types/push';
11
+ export * from './types/registration';
12
+ export * from './types/hook';
13
+ export * from './types/subscription';
14
+ export { validate, ValidationResult } from './validators';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AAGrC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ /**
3
+ * @agentwatch/protocol
4
+ *
5
+ * Single authoritative definition of every message type in the AgentWatch protocol.
6
+ * TypeScript components import types and validators at compile time and runtime.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.validate = void 0;
24
+ // Export all types
25
+ __exportStar(require("./types/session"), exports);
26
+ __exportStar(require("./types/action"), exports);
27
+ __exportStar(require("./types/approval"), exports);
28
+ __exportStar(require("./types/push"), exports);
29
+ __exportStar(require("./types/registration"), exports);
30
+ __exportStar(require("./types/hook"), exports);
31
+ __exportStar(require("./types/subscription"), exports);
32
+ // Export validators
33
+ var validators_1 = require("./validators");
34
+ Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validators_1.validate; } });
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;AAEH,mBAAmB;AACnB,kDAAgC;AAChC,iDAA+B;AAC/B,mDAAiC;AACjC,+CAA6B;AAC7B,uDAAqC;AACrC,+CAA6B;AAC7B,uDAAqC;AAErC,oBAAoB;AACpB,2CAA0D;AAAjD,sGAAA,QAAQ,OAAA"}
@@ -0,0 +1,71 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "AgentAction",
5
+ "description": "A single agent tool call",
6
+ "additionalProperties": false,
7
+ "required": ["id", "sessionId", "toolName", "input", "summary", "tier", "timestamp"],
8
+ "properties": {
9
+ "id": {
10
+ "type": "string",
11
+ "description": "Unique action identifier",
12
+ "maxLength": 255
13
+ },
14
+ "sessionId": {
15
+ "type": "string",
16
+ "description": "Session this action belongs to",
17
+ "maxLength": 255
18
+ },
19
+ "toolName": {
20
+ "type": "string",
21
+ "description": "Tool name",
22
+ "maxLength": 255
23
+ },
24
+ "input": {
25
+ "type": "object",
26
+ "description": "Tool input parameters"
27
+ },
28
+ "summary": {
29
+ "type": "string",
30
+ "description": "Human-readable summary",
31
+ "maxLength": 2048
32
+ },
33
+ "tier": {
34
+ "type": "string",
35
+ "description": "Action tier",
36
+ "enum": ["read", "write", "run"]
37
+ },
38
+ "timestamp": {
39
+ "type": "string",
40
+ "description": "ISO 8601 timestamp when action was requested",
41
+ "format": "date-time",
42
+ "maxLength": 64
43
+ },
44
+ "outcome": {
45
+ "type": "string",
46
+ "description": "Action outcome",
47
+ "enum": ["allowed", "denied", "auto_approved"]
48
+ },
49
+ "autoApprovalRecord": {
50
+ "type": "object",
51
+ "description": "Auto-approval details",
52
+ "additionalProperties": false,
53
+ "required": ["reason", "limitType", "resetDate"],
54
+ "properties": {
55
+ "reason": {
56
+ "type": "string",
57
+ "enum": ["limit_reached"]
58
+ },
59
+ "limitType": {
60
+ "type": "string",
61
+ "enum": ["daily", "monthly"]
62
+ },
63
+ "resetDate": {
64
+ "type": "string",
65
+ "format": "date-time",
66
+ "maxLength": 64
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "ApprovalRequest",
5
+ "description": "Pending decision requiring user approval",
6
+ "additionalProperties": false,
7
+ "required": ["approvalId", "sessionId", "action", "precedingActions", "timeout"],
8
+ "properties": {
9
+ "approvalId": {
10
+ "type": "string",
11
+ "description": "Unique approval request identifier",
12
+ "maxLength": 255
13
+ },
14
+ "sessionId": {
15
+ "type": "string",
16
+ "description": "Session this approval belongs to",
17
+ "maxLength": 255
18
+ },
19
+ "action": {
20
+ "$ref": "./action.schema.json"
21
+ },
22
+ "precedingActions": {
23
+ "type": "array",
24
+ "description": "Previous actions in this session",
25
+ "items": {
26
+ "$ref": "./action.schema.json"
27
+ }
28
+ },
29
+ "timeout": {
30
+ "type": "string",
31
+ "description": "ISO 8601 timestamp when request expires",
32
+ "format": "date-time",
33
+ "maxLength": 64
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "ApprovalResponse",
5
+ "description": "User decision on approval request",
6
+ "additionalProperties": false,
7
+ "required": ["approvalId", "sessionId", "decision", "signature", "timestamp"],
8
+ "properties": {
9
+ "approvalId": {
10
+ "type": "string",
11
+ "description": "Approval request ID",
12
+ "maxLength": 255
13
+ },
14
+ "sessionId": {
15
+ "type": "string",
16
+ "description": "Session ID",
17
+ "maxLength": 255
18
+ },
19
+ "decision": {
20
+ "type": "string",
21
+ "description": "User's decision",
22
+ "enum": ["allow", "deny"]
23
+ },
24
+ "signature": {
25
+ "type": "string",
26
+ "description": "HMAC signature for authenticity",
27
+ "maxLength": 512
28
+ },
29
+ "timestamp": {
30
+ "type": "string",
31
+ "description": "ISO 8601 timestamp when decision was made",
32
+ "format": "date-time",
33
+ "maxLength": 64
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "EntitlementRequest",
5
+ "description": "Request to check user entitlement",
6
+ "additionalProperties": false,
7
+ "required": ["pairingId", "accountId", "actionType"],
8
+ "properties": {
9
+ "pairingId": {
10
+ "type": "string",
11
+ "description": "Pairing ID making the request",
12
+ "maxLength": 255
13
+ },
14
+ "accountId": {
15
+ "type": "string",
16
+ "description": "Account ID for the user",
17
+ "maxLength": 255
18
+ },
19
+ "actionType": {
20
+ "type": "string",
21
+ "description": "Action type being checked",
22
+ "maxLength": 255
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "EntitlementResponse",
5
+ "description": "Entitlement check result",
6
+ "additionalProperties": false,
7
+ "required": ["decision", "count", "limit", "resetDate"],
8
+ "properties": {
9
+ "decision": {
10
+ "type": "string",
11
+ "description": "Whether action is allowed",
12
+ "enum": ["allowed", "denied", "soft_limit_warning"]
13
+ },
14
+ "errorCode": {
15
+ "type": "string",
16
+ "description": "Error code if denied",
17
+ "enum": ["limit_exceeded", "plan_downgraded", "account_suspended", "invalid_pairing"]
18
+ },
19
+ "count": {
20
+ "type": "integer",
21
+ "description": "Current count in period",
22
+ "minimum": 0
23
+ },
24
+ "limit": {
25
+ "description": "Limit for current plan (null = unlimited)",
26
+ "oneOf": [
27
+ { "type": "integer", "minimum": 0 },
28
+ { "type": "null" }
29
+ ]
30
+ },
31
+ "resetDate": {
32
+ "type": "string",
33
+ "description": "ISO 8601 timestamp when count resets",
34
+ "format": "date-time",
35
+ "maxLength": 64
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "HookInput",
5
+ "description": "IDE stdin payload for hook script",
6
+ "additionalProperties": false,
7
+ "required": ["eventName", "sessionId", "cwd"],
8
+ "properties": {
9
+ "eventName": {
10
+ "type": "string",
11
+ "description": "Event being reported",
12
+ "enum": ["tool_call", "session_start", "session_end"]
13
+ },
14
+ "sessionId": {
15
+ "type": "string",
16
+ "description": "Session ID",
17
+ "maxLength": 255
18
+ },
19
+ "cwd": {
20
+ "type": "string",
21
+ "description": "Current working directory",
22
+ "maxLength": 4096
23
+ },
24
+ "toolName": {
25
+ "type": "string",
26
+ "description": "Tool name for tool_call events",
27
+ "maxLength": 255
28
+ },
29
+ "toolInput": {
30
+ "type": "object",
31
+ "description": "Tool input parameters for tool_call events"
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "HookOutput",
5
+ "description": "Hook response to IDE",
6
+ "additionalProperties": false,
7
+ "required": ["decision"],
8
+ "properties": {
9
+ "decision": {
10
+ "type": "string",
11
+ "description": "Decision for the hook event",
12
+ "enum": ["allow", "deny"]
13
+ },
14
+ "reason": {
15
+ "type": "string",
16
+ "description": "Optional reason for denial",
17
+ "maxLength": 2048
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "PushPayload",
5
+ "description": "Relay envelope for encrypted messages",
6
+ "additionalProperties": false,
7
+ "required": ["type", "pairingId", "encryptedBlob"],
8
+ "properties": {
9
+ "type": {
10
+ "type": "string",
11
+ "description": "Type of payload",
12
+ "enum": ["approval_request", "session_start", "session_end", "subscription_event"]
13
+ },
14
+ "sessionId": {
15
+ "type": "string",
16
+ "description": "Session ID if applicable",
17
+ "maxLength": 255
18
+ },
19
+ "pairingId": {
20
+ "type": "string",
21
+ "description": "Pairing ID for routing",
22
+ "maxLength": 255
23
+ },
24
+ "encryptedBlob": {
25
+ "type": "string",
26
+ "description": "Encrypted message blob (base64 encoded)",
27
+ "maxLength": 1048576
28
+ }
29
+ }
30
+ }