@kangentic/protocol 0.13.1 → 0.15.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/dist/capabilities/verbs.d.ts +10 -1
- package/dist/events/event.d.ts +38 -0
- package/dist/index.cjs +1198 -1181
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +1194 -1181
- package/dist/wire/framing.d.ts +30 -1
- package/dist/wire/messages.d.ts +15 -0
- package/dist/wire/payloads.d.ts +34 -0
- package/package.json +1 -1
package/dist/wire/framing.d.ts
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
1
|
-
import type { BridgeMessage } from './messages';
|
|
1
|
+
import type { BridgeMessage, CapabilityErrorCode } from './messages';
|
|
2
2
|
export declare const MAX_FRAME_LENGTH: number;
|
|
3
3
|
/** Upper bound on the JSON a compressed frame may declare/inflate to. */
|
|
4
4
|
export declare const MAX_DECODED_LENGTH: number;
|
|
5
5
|
/** JSON below this size ships raw - deflate overhead is not worth it. */
|
|
6
6
|
export declare const COMPRESSION_THRESHOLD: number;
|
|
7
|
+
/** The `code` a desktop puts on its refusal of a verb its build does not know. */
|
|
8
|
+
export declare const UNSUPPORTED_VERB_ERROR_CODE: CapabilityErrorCode;
|
|
9
|
+
/**
|
|
10
|
+
* Thrown by `decodeMessage` for a capability-request whose envelope is
|
|
11
|
+
* well-formed (a string `requestId`, a string `verb`, a JSON `payload`) but
|
|
12
|
+
* whose verb this build's `CAPABILITY_VERBS` does not carry. It is the one
|
|
13
|
+
* decode failure that names its request, so the receiver can ANSWER it
|
|
14
|
+
* (`{ ok: false, code: 'unsupported-verb' }`) instead of dropping the frame.
|
|
15
|
+
*
|
|
16
|
+
* Without this a desktop that predates a verb sent nothing back at all, and
|
|
17
|
+
* the phone that sent it timed out, unable to tell an old desktop from an
|
|
18
|
+
* unreachable one. Every verb added to the protocol has that failure mode on
|
|
19
|
+
* a mixed-version pair. A frame that is NOT a well-formed request (a missing
|
|
20
|
+
* `requestId`, a non-string `verb`, a non-JSON `payload`) still throws a
|
|
21
|
+
* plain `Error` and stays a silent rejection: there is nothing to answer, and
|
|
22
|
+
* answering unstructured input would hand a probe to whoever sent it.
|
|
23
|
+
*/
|
|
24
|
+
export declare class UnsupportedVerbError extends Error {
|
|
25
|
+
readonly requestId: string;
|
|
26
|
+
readonly verb: string;
|
|
27
|
+
constructor(requestId: string, verb: string);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Keyed on `name`, not `instanceof`: the desktop consumes this package from
|
|
31
|
+
* source through a workspace alias while the mobile app resolves the published
|
|
32
|
+
* `dist`, and a bundler can hold two copies of the class, which `instanceof`
|
|
33
|
+
* would tell apart.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isUnsupportedVerbError(error: unknown): error is UnsupportedVerbError;
|
|
7
36
|
export declare function encodeMessage(message: BridgeMessage): Uint8Array;
|
|
8
37
|
export declare function decodeMessage(bytes: Uint8Array): BridgeMessage;
|
package/dist/wire/messages.d.ts
CHANGED
|
@@ -30,6 +30,15 @@ export interface CapabilityRequestMessage {
|
|
|
30
30
|
verb: CapabilityVerb;
|
|
31
31
|
payload: JsonValue;
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* A stable key a client can branch on, beside the human-readable `error`.
|
|
35
|
+
* Today the one member is the refusal a desktop sends for a verb its build
|
|
36
|
+
* does not know (see `UnsupportedVerbError` in framing.ts), so a newer phone
|
|
37
|
+
* can tell "desktop is old" from "desktop is unreachable" and show the right
|
|
38
|
+
* copy. A union rather than a bare string so a second code is a deliberate
|
|
39
|
+
* addition here, not a typo at a call site.
|
|
40
|
+
*/
|
|
41
|
+
export type CapabilityErrorCode = 'unsupported-verb';
|
|
33
42
|
export interface CapabilityResponseMessage {
|
|
34
43
|
type: 'capability-response';
|
|
35
44
|
requestId: string;
|
|
@@ -37,6 +46,12 @@ export interface CapabilityResponseMessage {
|
|
|
37
46
|
payload?: JsonValue;
|
|
38
47
|
/** Present only when ok is false. */
|
|
39
48
|
error?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Present only when ok is false AND the refusal has a stable key. Additive
|
|
51
|
+
* on the wire: a peer whose decoder predates the field rebuilds the message
|
|
52
|
+
* from the keys it knows and keeps `error`, so the text still shows.
|
|
53
|
+
*/
|
|
54
|
+
code?: CapabilityErrorCode;
|
|
40
55
|
}
|
|
41
56
|
export interface EventMessage {
|
|
42
57
|
type: 'event';
|
package/dist/wire/payloads.d.ts
CHANGED
|
@@ -278,6 +278,38 @@ export interface MoveTaskRequestPayload {
|
|
|
278
278
|
export interface MoveTaskResponsePayload {
|
|
279
279
|
ok: boolean;
|
|
280
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Keyed by task, not by session: the state this verb exists for is a task
|
|
283
|
+
* whose session has ENDED, so there is no live session id to name. The
|
|
284
|
+
* desktop spawns or resumes in the task's current column with that column's
|
|
285
|
+
* settings; a live session is an idempotent no-op.
|
|
286
|
+
*/
|
|
287
|
+
export interface StartSessionRequestPayload {
|
|
288
|
+
taskId: string;
|
|
289
|
+
projectId: string;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* What the desktop did with an accepted start. `starting`: the worktree and
|
|
293
|
+
* PTY work run behind this response and the successor's arrival reaches the
|
|
294
|
+
* phone as a board / stream event, the same way a column move's does. `live`:
|
|
295
|
+
* the task already had a running session, nothing was spawned, and NO event
|
|
296
|
+
* is coming, so a phone that tapped Start from a stale screen must refresh
|
|
297
|
+
* its board and stream itself rather than wait.
|
|
298
|
+
*/
|
|
299
|
+
export type StartSessionOutcome = 'starting' | 'live';
|
|
300
|
+
/**
|
|
301
|
+
* `ok` means the start was ACCEPTED (the task exists, is in a column that may
|
|
302
|
+
* run an agent, and either has no live session or already has one), not that
|
|
303
|
+
* a successor is up: the desktop answers before the worktree and PTY work so
|
|
304
|
+
* the response fits the phone's per-verb budget. `outcome` says which of the
|
|
305
|
+
* two accepted shapes this was.
|
|
306
|
+
*/
|
|
307
|
+
export interface StartSessionResponsePayload {
|
|
308
|
+
ok: boolean;
|
|
309
|
+
outcome: StartSessionOutcome;
|
|
310
|
+
}
|
|
311
|
+
/** Phone-side guard: narrows a decoded start-session response before the phone acts on it. */
|
|
312
|
+
export declare function parseStartSessionResponsePayload(payload: JsonValue): StartSessionResponsePayload;
|
|
281
313
|
export interface AnswerPermissionPromptRequestPayload {
|
|
282
314
|
sessionId: string;
|
|
283
315
|
/** The prompt id the phone believes is outstanding - the handler rejects a stale/replayed answer whose id no longer matches the live awaited prompt. */
|
|
@@ -363,6 +395,7 @@ export interface CapabilityRequestPayloadMap {
|
|
|
363
395
|
'board-tool-read': BoardToolRequestPayload;
|
|
364
396
|
'board-tool-write': BoardToolRequestPayload;
|
|
365
397
|
'register-push': RegisterPushRequestPayload;
|
|
398
|
+
'start-session': StartSessionRequestPayload;
|
|
366
399
|
}
|
|
367
400
|
export interface CapabilityResponsePayloadMap {
|
|
368
401
|
'read-stream': ReadStreamResponsePayload | TranscriptWindowResponsePayload;
|
|
@@ -375,6 +408,7 @@ export interface CapabilityResponsePayloadMap {
|
|
|
375
408
|
'board-tool-read': BoardToolResponsePayload;
|
|
376
409
|
'board-tool-write': BoardToolResponsePayload;
|
|
377
410
|
'register-push': RegisterPushResponsePayload;
|
|
411
|
+
'start-session': StartSessionResponsePayload;
|
|
378
412
|
}
|
|
379
413
|
/**
|
|
380
414
|
* Validates and narrows a decoded capability-request's generic JsonValue
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kangentic/protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Kangentic mobile bridge wire protocol: framing, Noise-based pairing and session handshakes, signed device roster, and capability verbs shared between desktop and mobile.",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.mjs",
|