@kangentic/protocol 0.1.0 → 0.2.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/LICENSE +659 -4
- package/dist/capabilities/board-tools.d.ts +22 -0
- package/dist/capabilities/verbs.d.ts +1 -1
- package/dist/crypto/slot.d.ts +1 -0
- package/dist/events/event.d.ts +76 -16
- package/dist/events/payloads.d.ts +220 -0
- package/dist/index.cjs +548 -23
- package/dist/index.d.ts +6 -1
- package/dist/index.mjs +525 -23
- package/dist/wire/json-value.d.ts +9 -0
- package/dist/wire/payloads.d.ts +139 -0
- package/package.json +1 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Concrete per-verb request/response payload shapes. `CapabilityRequestMessage.payload`
|
|
3
|
+
* and `CapabilityResponseMessage.payload` stay `JsonValue` on the envelope
|
|
4
|
+
* (messages.ts) - these interfaces narrow that generic value at the handler
|
|
5
|
+
* boundary, and the `parse*RequestPayload` guards below are the runtime
|
|
6
|
+
* checks a handler runs against an untrusted phone-originated request before
|
|
7
|
+
* trusting any field.
|
|
8
|
+
*
|
|
9
|
+
* Fields that mirror an app-internal shape the protocol package cannot
|
|
10
|
+
* import (git diff results, board rows, an MCP tool's result) stay
|
|
11
|
+
* `JsonValue`, same rationale as messages.ts/events/event.ts: this package
|
|
12
|
+
* is a dependency-light leaf shared by desktop and phone, so it does not
|
|
13
|
+
* know the desktop app's internal types. Only the fixed envelope fields
|
|
14
|
+
* (ids, actions, booleans) are concretely typed and runtime-validated here.
|
|
15
|
+
*/
|
|
16
|
+
import type { CapabilityVerb } from '../capabilities/verbs';
|
|
17
|
+
import type { JsonValue } from './messages';
|
|
18
|
+
import { type ActivityReasonWire, type ActivityStateWire, type BacklogItemWire, type BoardColumnWire, type BoardTaskWire, type DiffFileContentWire, type DiffFileListWire, type SessionUsageWire } from '../events/payloads';
|
|
19
|
+
export interface ReadStreamRequestPayload {
|
|
20
|
+
sessionId: string;
|
|
21
|
+
action: 'subscribe' | 'unsubscribe';
|
|
22
|
+
}
|
|
23
|
+
/** Initial snapshot returned on subscribe; live updates arrive as TerminalEvent/ActivityEvent/TranscriptEvent. */
|
|
24
|
+
export interface ReadStreamResponsePayload {
|
|
25
|
+
scrollback: string;
|
|
26
|
+
activity: {
|
|
27
|
+
state: ActivityStateWire | null;
|
|
28
|
+
reason: ActivityReasonWire | null;
|
|
29
|
+
};
|
|
30
|
+
usage: SessionUsageWire | null;
|
|
31
|
+
/** The live outstanding permission-prompt id (see answer-permission-prompt), or null when none is pending. */
|
|
32
|
+
awaitedPromptId: string | null;
|
|
33
|
+
}
|
|
34
|
+
/** Phone-side narrowing of a read-stream subscribe response. Throws on a malformed required field. */
|
|
35
|
+
export declare function parseReadStreamResponsePayload(payload: JsonValue): ReadStreamResponsePayload;
|
|
36
|
+
export interface ReadBoardRequestPayload {
|
|
37
|
+
projectId?: string;
|
|
38
|
+
/** Defaults to 'subscribe' when omitted. 'unsubscribe' only has an effect when projectId is set - the no-projectId project list is a one-shot read with no live feed to tear down. */
|
|
39
|
+
action?: 'subscribe' | 'unsubscribe';
|
|
40
|
+
}
|
|
41
|
+
export interface ReadBoardProjectSummary {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
}
|
|
45
|
+
/** Returned when the request omits projectId - the phone's project-bootstrap listing. */
|
|
46
|
+
export interface ReadBoardProjectListResponsePayload {
|
|
47
|
+
projects: ReadBoardProjectSummary[];
|
|
48
|
+
}
|
|
49
|
+
/** Returned when the request carries a projectId - a snapshot of that project's board. */
|
|
50
|
+
export interface ReadBoardSnapshotResponsePayload {
|
|
51
|
+
projectId: string;
|
|
52
|
+
columns: BoardColumnWire[];
|
|
53
|
+
tasks: BoardTaskWire[];
|
|
54
|
+
backlog: BacklogItemWire[];
|
|
55
|
+
}
|
|
56
|
+
export type ReadBoardResponsePayload = ReadBoardProjectListResponsePayload | ReadBoardSnapshotResponsePayload;
|
|
57
|
+
/** Phone-side narrowing of a read-board response (project list or board snapshot). Throws on a malformed required field. */
|
|
58
|
+
export declare function parseReadBoardResponsePayload(payload: JsonValue): ReadBoardResponsePayload;
|
|
59
|
+
/** Mirrors DiffService's GitDiffScope in the desktop app; kept as a literal union here rather than an import, since the protocol package does not depend on the app. */
|
|
60
|
+
export type ReadDiffScope = 'working' | 'staged' | 'branch';
|
|
61
|
+
export interface ReadDiffRequestPayload {
|
|
62
|
+
taskId: string;
|
|
63
|
+
projectId: string;
|
|
64
|
+
filePath?: string;
|
|
65
|
+
scope?: ReadDiffScope;
|
|
66
|
+
/** Defaults to 'subscribe' when omitted. Only the file-list watch (no filePath) has a live feed to tear down; a single-file content fetch is always one-shot. */
|
|
67
|
+
action?: 'subscribe' | 'unsubscribe';
|
|
68
|
+
}
|
|
69
|
+
/** The desktop's GitDiffFilesResult mirror (no filePath) or GitFileContentResult mirror (filePath set). */
|
|
70
|
+
export type ReadDiffResponsePayload = DiffFileListWire | DiffFileContentWire;
|
|
71
|
+
/** Phone-side narrowing of a read-diff response, discriminated by the presence of "files". Throws on a malformed required field. */
|
|
72
|
+
export declare function parseReadDiffResponsePayload(payload: JsonValue): ReadDiffResponsePayload;
|
|
73
|
+
export interface SendUserMessageRequestPayload {
|
|
74
|
+
sessionId: string;
|
|
75
|
+
text: string;
|
|
76
|
+
}
|
|
77
|
+
export interface SendUserMessageResponsePayload {
|
|
78
|
+
delivered: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface MoveTaskRequestPayload {
|
|
81
|
+
taskId: string;
|
|
82
|
+
targetSwimlaneId: string;
|
|
83
|
+
targetPosition: number;
|
|
84
|
+
projectId: string;
|
|
85
|
+
}
|
|
86
|
+
export interface MoveTaskResponsePayload {
|
|
87
|
+
ok: boolean;
|
|
88
|
+
}
|
|
89
|
+
export interface AnswerPermissionPromptRequestPayload {
|
|
90
|
+
sessionId: string;
|
|
91
|
+
/** The prompt id the phone believes is outstanding - the handler rejects a stale/replayed answer whose id no longer matches the live awaited prompt. */
|
|
92
|
+
promptId: string;
|
|
93
|
+
keystrokes: string;
|
|
94
|
+
}
|
|
95
|
+
export interface AnswerPermissionPromptResponsePayload {
|
|
96
|
+
answered: boolean;
|
|
97
|
+
}
|
|
98
|
+
export interface InteractiveTerminalRequestPayload {
|
|
99
|
+
sessionId: string;
|
|
100
|
+
data: string;
|
|
101
|
+
}
|
|
102
|
+
export interface InteractiveTerminalResponsePayload {
|
|
103
|
+
written: boolean;
|
|
104
|
+
}
|
|
105
|
+
export interface BoardToolRequestPayload {
|
|
106
|
+
tool: string;
|
|
107
|
+
params: JsonValue;
|
|
108
|
+
}
|
|
109
|
+
export interface BoardToolResponsePayload {
|
|
110
|
+
result: JsonValue;
|
|
111
|
+
}
|
|
112
|
+
export interface CapabilityRequestPayloadMap {
|
|
113
|
+
'read-stream': ReadStreamRequestPayload;
|
|
114
|
+
'read-board': ReadBoardRequestPayload;
|
|
115
|
+
'read-diff': ReadDiffRequestPayload;
|
|
116
|
+
'send-user-message': SendUserMessageRequestPayload;
|
|
117
|
+
'move-task': MoveTaskRequestPayload;
|
|
118
|
+
'answer-permission-prompt': AnswerPermissionPromptRequestPayload;
|
|
119
|
+
'interactive-terminal': InteractiveTerminalRequestPayload;
|
|
120
|
+
'board-tool-read': BoardToolRequestPayload;
|
|
121
|
+
'board-tool-write': BoardToolRequestPayload;
|
|
122
|
+
}
|
|
123
|
+
export interface CapabilityResponsePayloadMap {
|
|
124
|
+
'read-stream': ReadStreamResponsePayload;
|
|
125
|
+
'read-board': ReadBoardResponsePayload;
|
|
126
|
+
'read-diff': ReadDiffResponsePayload;
|
|
127
|
+
'send-user-message': SendUserMessageResponsePayload;
|
|
128
|
+
'move-task': MoveTaskResponsePayload;
|
|
129
|
+
'answer-permission-prompt': AnswerPermissionPromptResponsePayload;
|
|
130
|
+
'interactive-terminal': InteractiveTerminalResponsePayload;
|
|
131
|
+
'board-tool-read': BoardToolResponsePayload;
|
|
132
|
+
'board-tool-write': BoardToolResponsePayload;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Validates and narrows a decoded capability-request's generic JsonValue
|
|
136
|
+
* payload into its verb-specific shape. This is the runtime trust boundary:
|
|
137
|
+
* every field the phone supplies is checked before a handler reads it.
|
|
138
|
+
*/
|
|
139
|
+
export declare function parseCapabilityRequestPayload<Verb extends CapabilityVerb>(verb: Verb, payload: JsonValue): CapabilityRequestPayloadMap[Verb];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kangentic/protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.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",
|