@anycon/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 (49) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +146 -0
  3. package/README.zh-CN.md +118 -0
  4. package/dist/constants.d.ts +151 -0
  5. package/dist/constants.d.ts.map +1 -0
  6. package/dist/constants.js +159 -0
  7. package/dist/constants.js.map +1 -0
  8. package/dist/crypto.d.ts +202 -0
  9. package/dist/crypto.d.ts.map +1 -0
  10. package/dist/crypto.js +218 -0
  11. package/dist/crypto.js.map +1 -0
  12. package/dist/envelope.d.ts +105 -0
  13. package/dist/envelope.d.ts.map +1 -0
  14. package/dist/envelope.js +390 -0
  15. package/dist/envelope.js.map +1 -0
  16. package/dist/errors.d.ts +5 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +5 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/generated.d.ts +2007 -0
  21. package/dist/generated.d.ts.map +1 -0
  22. package/dist/generated.js +4 -0
  23. package/dist/generated.js.map +1 -0
  24. package/dist/index.d.ts +17 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +16 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/method-types.d.ts +293 -0
  29. package/dist/method-types.d.ts.map +1 -0
  30. package/dist/method-types.js +2 -0
  31. package/dist/method-types.js.map +1 -0
  32. package/dist/rpc.d.ts +70 -0
  33. package/dist/rpc.d.ts.map +1 -0
  34. package/dist/rpc.js +310 -0
  35. package/dist/rpc.js.map +1 -0
  36. package/package.json +62 -0
  37. package/src/constants.ts +173 -0
  38. package/src/crypto.ts +427 -0
  39. package/src/envelope.ts +469 -0
  40. package/src/errors.ts +4 -0
  41. package/src/generated.ts +2094 -0
  42. package/src/index.ts +18 -0
  43. package/src/method-types.ts +183 -0
  44. package/src/rpc.ts +377 -0
  45. package/wasm/THIRD-PARTY-LICENSES.txt +1957 -0
  46. package/wasm/anycon_crypto.d.ts +248 -0
  47. package/wasm/anycon_crypto.js +1250 -0
  48. package/wasm/anycon_crypto_bg.wasm +0 -0
  49. package/wasm/anycon_crypto_bg.wasm.d.ts +48 -0
package/dist/rpc.js ADDED
@@ -0,0 +1,310 @@
1
+ /**
2
+ * 内层 JSON-RPC 2.0:类型、编解码、类型守卫,以及与传输无关的 `RpcPeer`。
3
+ *
4
+ * 一个 `data` 信封 = 一条 JSON-RPC 消息(请求 / 响应 / 通知之一),不合并。
5
+ * 错误以 `error.data.code`(稳定 snake_case)为准,`AnyconRpcError.code` 直接给出它。
6
+ */
7
+ import { ERROR_CODE_NUMBERS } from './constants.js';
8
+ import { ProtocolError } from './errors.js';
9
+ const JSONRPC = '2.0';
10
+ // ---------- 守卫 ----------
11
+ /** 有 `method` 且有 `id`。 */
12
+ export function isRequest(m) {
13
+ return 'method' in m && 'id' in m && m.id !== undefined && m.id !== null;
14
+ }
15
+ /** 有 `method` 无 `id`。 */
16
+ export function isNotification(m) {
17
+ return 'method' in m && !('id' in m && m.id !== undefined && m.id !== null);
18
+ }
19
+ /** 没有 `method`。 */
20
+ export function isResponse(m) {
21
+ return !('method' in m);
22
+ }
23
+ // ---------- 构造(键序与 Rust 结构体声明一致) ----------
24
+ export function makeRequest(id, method, params = {}) {
25
+ return { jsonrpc: JSONRPC, id, method, params: params };
26
+ }
27
+ export function makeNotification(method, params = {}) {
28
+ return { jsonrpc: JSONRPC, method, params: params };
29
+ }
30
+ export function makeResult(id, result) {
31
+ return { jsonrpc: JSONRPC, id, result };
32
+ }
33
+ export function makeError(id, error) {
34
+ return { jsonrpc: JSONRPC, id, error };
35
+ }
36
+ // ---------- 编解码 ----------
37
+ const textEncoder = new TextEncoder();
38
+ const textDecoder = new TextDecoder('utf-8', { fatal: true });
39
+ const isSet = (v) => v !== null && v !== undefined;
40
+ /** `RpcError` 的字段顺序 code, message, data;`data` 里的可选字段为 null / undefined 时省略。 */
41
+ function canonicalError(err) {
42
+ const out = { code: err.code, message: err.message };
43
+ const data = err.data;
44
+ if (data !== undefined && data !== null) {
45
+ const d = { code: data.code };
46
+ if (isSet(data.field))
47
+ d.field = data.field;
48
+ if (isSet(data.reason))
49
+ d.reason = data.reason;
50
+ if (isSet(data.retry_after_ms))
51
+ d.retry_after_ms = data.retry_after_ms;
52
+ out.data = d;
53
+ }
54
+ return out;
55
+ }
56
+ /** 按 Rust 侧的字段顺序重排,保证和 `serde_json::to_vec` 字节一致。 */
57
+ function canonicalRpc(msg) {
58
+ if (isRequest(msg))
59
+ return makeRequest(msg.id, msg.method, msg.params ?? {});
60
+ if (isNotification(msg))
61
+ return makeNotification(msg.method, msg.params ?? {});
62
+ const out = { jsonrpc: JSONRPC, id: msg.id };
63
+ if (msg.result !== undefined)
64
+ out.result = msg.result;
65
+ if (msg.error !== undefined && msg.error !== null)
66
+ out.error = canonicalError(msg.error);
67
+ return out;
68
+ }
69
+ export function encodeRpc(msg) {
70
+ return textEncoder.encode(JSON.stringify(canonicalRpc(msg)));
71
+ }
72
+ export function decodeRpc(bytes) {
73
+ let value;
74
+ try {
75
+ value = JSON.parse(textDecoder.decode(bytes));
76
+ }
77
+ catch (cause) {
78
+ throw new ProtocolError('rpc message is not valid JSON', { cause });
79
+ }
80
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
81
+ throw new ProtocolError('rpc message must be a JSON object');
82
+ }
83
+ const m = value;
84
+ if (m.jsonrpc !== JSONRPC)
85
+ throw new ProtocolError('rpc message is not jsonrpc 2.0');
86
+ const hasId = typeof m.id === 'number' || typeof m.id === 'string';
87
+ if ('method' in m) {
88
+ if (typeof m.method !== 'string')
89
+ throw new ProtocolError('rpc method must be a string');
90
+ if ('id' in m && !hasId)
91
+ throw new ProtocolError('rpc id must be a number or string');
92
+ return value;
93
+ }
94
+ if (!hasId)
95
+ throw new ProtocolError('rpc response needs a numeric or string id');
96
+ return value;
97
+ }
98
+ // ---------- 错误 ----------
99
+ const CODE_BY_NUMBER = new Map(Object.entries(ERROR_CODE_NUMBERS).map(([code, n]) => [n, code]));
100
+ /** 远端返回(或本地构造)的 JSON-RPC 错误。`code` 是稳定的 snake_case,客户端据此 i18n。 */
101
+ export class AnyconRpcError extends Error {
102
+ name = 'AnyconRpcError';
103
+ /** JSON-RPC 数字 code。 */
104
+ rpcCode;
105
+ data;
106
+ constructor(rpcCode, message, data) {
107
+ super(message);
108
+ this.rpcCode = rpcCode;
109
+ this.data = data ?? null;
110
+ }
111
+ /** 稳定错误码:优先 `data.code`,没有就按数字 code 反查,再不行是 `internal`。 */
112
+ get code() {
113
+ return this.data?.code ?? CODE_BY_NUMBER.get(this.rpcCode) ?? 'internal';
114
+ }
115
+ /** `invalid_settings` 时指出出错字段。 */
116
+ get field() {
117
+ return this.data?.field ?? undefined;
118
+ }
119
+ get reason() {
120
+ return this.data?.reason ?? undefined;
121
+ }
122
+ get retryAfterMs() {
123
+ return this.data?.retry_after_ms ?? undefined;
124
+ }
125
+ static fromWire(err) {
126
+ return new AnyconRpcError(err.code, err.message, err.data);
127
+ }
128
+ /** 构造稳定码对应的错误(daemon 侧请求处理器、测试用)。 */
129
+ static of(code, message, extra) {
130
+ return new AnyconRpcError(ERROR_CODE_NUMBERS[code], message, { code, ...extra });
131
+ }
132
+ toWire() {
133
+ const wire = { code: this.rpcCode, message: this.message };
134
+ if (this.data)
135
+ wire.data = this.data;
136
+ return wire;
137
+ }
138
+ }
139
+ /** 请求超时。 */
140
+ export class RpcTimeoutError extends Error {
141
+ method;
142
+ timeoutMs;
143
+ name = 'RpcTimeoutError';
144
+ constructor(method, timeoutMs) {
145
+ super(`rpc ${method} timed out after ${timeoutMs}ms`);
146
+ this.method = method;
147
+ this.timeoutMs = timeoutMs;
148
+ }
149
+ }
150
+ /**
151
+ * 与传输无关的 JSON-RPC 端点。`send` 注入,入站字节喂给 `handle()`。
152
+ * 请求 id 是递增整数;响应按 id 关联;通知按方法名分发(`'*'` 收所有)。
153
+ */
154
+ export class RpcPeer {
155
+ #send;
156
+ #defaultTimeoutMs;
157
+ #pending = new Map();
158
+ #notificationHandlers = new Map();
159
+ #requestHandlers = new Map();
160
+ #nextId = 1;
161
+ constructor(options) {
162
+ this.#send = options.send;
163
+ this.#defaultTimeoutMs = options.timeoutMs ?? 30_000;
164
+ }
165
+ /** 未答复的请求数。 */
166
+ get pending() {
167
+ return this.#pending.size;
168
+ }
169
+ request(method, params, options = {}) {
170
+ const id = this.#nextId++;
171
+ const timeoutMs = options.timeoutMs ?? this.#defaultTimeoutMs;
172
+ return new Promise((resolve, reject) => {
173
+ const { signal } = options;
174
+ if (signal?.aborted) {
175
+ reject(signal.reason ?? new Error('aborted'));
176
+ return;
177
+ }
178
+ const entry = {
179
+ method,
180
+ resolve: resolve,
181
+ reject,
182
+ timer: undefined,
183
+ cleanup: () => {
184
+ if (entry.timer !== undefined)
185
+ clearTimeout(entry.timer);
186
+ signal?.removeEventListener('abort', onAbort);
187
+ this.#pending.delete(id);
188
+ },
189
+ };
190
+ const onAbort = () => {
191
+ entry.cleanup();
192
+ reject(signal?.reason ?? new Error('aborted'));
193
+ };
194
+ if (timeoutMs > 0 && Number.isFinite(timeoutMs)) {
195
+ entry.timer = setTimeout(() => {
196
+ entry.cleanup();
197
+ reject(new RpcTimeoutError(method, timeoutMs));
198
+ }, timeoutMs);
199
+ }
200
+ signal?.addEventListener('abort', onAbort, { once: true });
201
+ this.#pending.set(id, entry);
202
+ try {
203
+ this.#send(encodeRpc(makeRequest(id, method, params ?? {})));
204
+ }
205
+ catch (err) {
206
+ entry.cleanup();
207
+ reject(err);
208
+ }
209
+ });
210
+ }
211
+ notify(method, params) {
212
+ this.#send(encodeRpc(makeNotification(method, params ?? {})));
213
+ }
214
+ /** 订阅通知。`method = '*'` 收全部。返回取消订阅函数。 */
215
+ onNotification(method, handler) {
216
+ let set = this.#notificationHandlers.get(method);
217
+ if (!set) {
218
+ set = new Set();
219
+ this.#notificationHandlers.set(method, set);
220
+ }
221
+ const h = handler;
222
+ set.add(h);
223
+ return () => {
224
+ set.delete(h);
225
+ };
226
+ }
227
+ /** 注册对端发来的请求的处理器(目前方向是 D→C,留给以后)。每个方法至多一个。 */
228
+ onRequest(method, handler) {
229
+ this.#requestHandlers.set(method, handler);
230
+ return () => {
231
+ if (this.#requestHandlers.get(method) === handler) {
232
+ this.#requestHandlers.delete(method);
233
+ }
234
+ };
235
+ }
236
+ /** 处理一条入站消息。解析失败抛 `ProtocolError`;处理器内部的错误不会向外抛。 */
237
+ handle(bytes) {
238
+ const msg = decodeRpc(bytes);
239
+ if (isResponse(msg)) {
240
+ this.#onResponse(msg);
241
+ }
242
+ else if (isRequest(msg)) {
243
+ void this.#onRequest(msg);
244
+ }
245
+ else {
246
+ this.#onNotification(msg);
247
+ }
248
+ }
249
+ /** 拒绝所有未答复请求(连接断开时调用)。 */
250
+ failAll(error) {
251
+ const entries = Array.from(this.#pending.values());
252
+ for (const entry of entries) {
253
+ entry.cleanup();
254
+ entry.reject(error);
255
+ }
256
+ }
257
+ #onResponse(msg) {
258
+ const entry = this.#pending.get(msg.id);
259
+ if (!entry)
260
+ return;
261
+ entry.cleanup();
262
+ if (msg.error)
263
+ entry.reject(AnyconRpcError.fromWire(msg.error));
264
+ else
265
+ entry.resolve(msg.result);
266
+ }
267
+ #onNotification(msg) {
268
+ for (const key of [msg.method, '*']) {
269
+ // 先拷贝:订阅者可能在回调里取消订阅。
270
+ const handlers = Array.from(this.#notificationHandlers.get(key) ?? []);
271
+ for (const handler of handlers) {
272
+ try {
273
+ handler(msg.params, msg.method);
274
+ }
275
+ catch {
276
+ // 订阅者的异常不能影响其他订阅者和连接。
277
+ }
278
+ }
279
+ }
280
+ }
281
+ async #onRequest(msg) {
282
+ const handler = this.#requestHandlers.get(msg.method);
283
+ let reply;
284
+ if (!handler) {
285
+ reply = makeError(msg.id, {
286
+ code: -32601,
287
+ message: `method not found: ${msg.method}`,
288
+ data: { code: 'unsupported' },
289
+ });
290
+ }
291
+ else {
292
+ try {
293
+ reply = makeResult(msg.id, (await handler(msg.params)) ?? null);
294
+ }
295
+ catch (err) {
296
+ const rpcErr = err instanceof AnyconRpcError
297
+ ? err
298
+ : AnyconRpcError.of('internal', err instanceof Error ? err.message : String(err));
299
+ reply = makeError(msg.id, rpcErr.toWire());
300
+ }
301
+ }
302
+ try {
303
+ this.#send(encodeRpc(reply));
304
+ }
305
+ catch {
306
+ // 连接已断,对端也拿不到答复了。
307
+ }
308
+ }
309
+ }
310
+ //# sourceMappingURL=rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@anycon/protocol",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript side of the Anycon protocol: generated types, envelope msgpack codec, JSON-RPC, and the Noise wasm wrapper.",
5
+ "homepage": "https://github.com/anycon-ai/anycon/tree/main/packages/protocol#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/anycon-ai/anycon/issues"
8
+ },
9
+ "license": "Apache-2.0",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/anycon-ai/anycon.git",
13
+ "directory": "packages/protocol"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "!dist/.tsbuildinfo",
18
+ "src",
19
+ "wasm/anycon_crypto.js",
20
+ "wasm/anycon_crypto.d.ts",
21
+ "wasm/anycon_crypto_bg.wasm",
22
+ "wasm/anycon_crypto_bg.wasm.d.ts",
23
+ "wasm/THIRD-PARTY-LICENSES.txt",
24
+ "README.md",
25
+ "README.zh-CN.md"
26
+ ],
27
+ "type": "module",
28
+ "sideEffects": false,
29
+ "main": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "source": "./src/index.ts",
34
+ "bun": "./src/index.ts",
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js"
37
+ },
38
+ "./wasm/*": "./wasm/*",
39
+ "./package.json": "./package.json"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc -p tsconfig.build.json",
46
+ "typecheck": "tsc --noEmit -p tsconfig.json",
47
+ "test": "bun test",
48
+ "test:node": "node --import tsx --conditions source --test \"tests/**/*.test.ts\"",
49
+ "lint": "oxlint -c ../../.oxlintrc.json src tests tools",
50
+ "fmt": "oxfmt --config ../../.oxfmtrc.json src tests tools",
51
+ "prepack": "bash tools/prepack.sh"
52
+ },
53
+ "dependencies": {
54
+ "@msgpack/msgpack": "^3.1.3"
55
+ },
56
+ "devDependencies": {
57
+ "@types/bun": "^1.4.2",
58
+ "@types/node": "^24.0.0",
59
+ "tsx": "^4.23.15",
60
+ "typescript": "~5.9.3"
61
+ }
62
+ }
@@ -0,0 +1,173 @@
1
+ /**
2
+ * 常量。全部镜像 `crates/protocol`,`constants.test.ts` 会解析 Rust 源码做漂移检查:
3
+ * 改了 Rust 侧的方法名 / 版本号 / close code / 错误码数值,这里不同步测试就会红。
4
+ */
5
+
6
+ /** 内层 JSON-RPC 协议版本。相邻 minor 兼容,0.x 阶段可 break。 */
7
+ export const PROTOCOL_VERSION = 1
8
+ /** 外层信封版本。极少改动。 */
9
+ export const ENVELOPE_VERSION = 1
10
+
11
+ /** 短码字母表:大写字母数字去掉 0 O 1 I L。 */
12
+ export const PAIR_CODE_ALPHABET = '23456789ABCDEFGHJKMNPQRSTUVWXYZ'
13
+ /** 短码长度:8 位(约 40 bit),`anycon pair --short` 生成的;只适合自建 hub,经不信任的 hub 配对不要用。 */
14
+ export const PAIR_CODE_LEN = 8
15
+ /** 长短码长度:16 位(约 79 bit),`anycon pair` 的**默认**长度,链接 / 二维码 / `--json` 都是它。与 `crates/crypto` 的 `PAIR_CODE_LEN_LONG` 一致。 */
16
+ export const PAIR_CODE_LEN_LONG = 16
17
+
18
+ /** WebSocket close code(hub → 设备)。 */
19
+ export const CLOSE_CODE = {
20
+ /** 同一设备的新连接顶掉了这条。不要自动重连,否则两条连接会互相踢。 */
21
+ SUPERSEDED: 4001,
22
+ /** hub 优雅关停。1–3 秒抖动后重连,而不是指数退避。 */
23
+ RESTARTING: 4002,
24
+ /** 接收太慢,发送缓冲持续满。 */
25
+ SLOW_CONSUMER: 4003,
26
+ /** 设备已被吊销。 */
27
+ REVOKED: 4004,
28
+ /** 第一帧 auth 超时。 */
29
+ AUTH_TIMEOUT: 4005,
30
+ } as const
31
+
32
+ /** 内层方法名。`域.动作`。键名与 `crates/protocol/src/methods.rs` 的常量名一致。 */
33
+ export const METHODS = {
34
+ // pairing(握手刚完成、PairDone 之后,daemon → joiner 的第一条加密通知;joiner 收到并校验后才落盘)
35
+ /** D→C notification,params = PairAck */
36
+ PAIR_ACK: 'pair.ack',
37
+
38
+ // node
39
+ NODE_INFO: 'node.info',
40
+ NODE_DEVICES: 'node.devices',
41
+ NODE_REVOKE_DEVICE: 'node.revoke_device',
42
+ NODE_PAIR_BEGIN: 'node.pair_begin',
43
+ NODE_STATS: 'node.stats',
44
+ NODE_DOCTOR: 'node.doctor',
45
+ NODE_AUDIT: 'node.audit',
46
+ NODE_SET_AGENT_DEFAULTS: 'node.set_agent_defaults',
47
+
48
+ // 账号内接入(ADR-36)
49
+ /** 进行中的接入会话。 */
50
+ NODE_ENROLL_LIST: 'node.enroll_list',
51
+ /** 批准一个接入请求:`code` 返回 6 位码,`scan` 带二维码里的密钥。 */
52
+ NODE_ENROLL_APPROVE: 'node.enroll_approve',
53
+ NODE_ENROLL_DENY: 'node.enroll_deny',
54
+ /** 主动生成 6 位接入码(「添加设备」、`anycon pair --enroll`)。 */
55
+ NODE_ENROLL_CODE: 'node.enroll_code',
56
+ NODE_ENROLL_STATUS: 'node.enroll_status',
57
+ NODE_SET_ENROLL_PASSWORD: 'node.set_enroll_password',
58
+ NODE_SET_ENROLL_ENABLED: 'node.set_enroll_enabled',
59
+ /** D→C notification,params = EnrollInfo */
60
+ NODE_ENROLL_REQUESTED: 'node.enroll_requested',
61
+ /** D→C notification,params = NodeEnrollResolved */
62
+ NODE_ENROLL_RESOLVED: 'node.enroll_resolved',
63
+ /** D→C notification,params = NodeSecurityEvent */
64
+ NODE_SECURITY_EVENT: 'node.security_event',
65
+
66
+ // agent
67
+ AGENT_LIST: 'agent.list',
68
+ AGENT_DIAGNOSE: 'agent.diagnose',
69
+ /** D→C notification,params = AgentListResult */
70
+ AGENT_CHANGED: 'agent.changed',
71
+
72
+ // workspace
73
+ WORKSPACE_LIST: 'workspace.list',
74
+ WORKSPACE_CREATE: 'workspace.create',
75
+ WORKSPACE_CLONE: 'workspace.clone',
76
+ WORKSPACE_RENAME: 'workspace.rename',
77
+ WORKSPACE_TRASH: 'workspace.trash',
78
+ WORKSPACE_TRASH_LIST: 'workspace.trash_list',
79
+ WORKSPACE_RESTORE: 'workspace.restore',
80
+ WORKSPACE_PURGE: 'workspace.purge',
81
+ /** 把本机已有目录关联为项目(params = WorkspaceLinkParams → Project)。 */
82
+ WORKSPACE_LINK: 'workspace.link',
83
+ /** 解除关联(不删除目录;params = WorkspaceNameParams)。 */
84
+ WORKSPACE_UNLINK: 'workspace.unlink',
85
+ /** 列本机目录供选择(params = WorkspaceBrowseParams → WorkspaceBrowseResult)。 */
86
+ WORKSPACE_BROWSE: 'workspace.browse',
87
+ /** 列项目的分支(params = WorkspaceBranchesParams → WorkspaceBranchesResult,ADR-34)。 */
88
+ WORKSPACE_BRANCHES: 'workspace.branches',
89
+ /** 列 anycon 建的 worktree(params = WorkspaceWorktreesParams → WorkspaceWorktreesResult)。 */
90
+ WORKSPACE_WORKTREES: 'workspace.worktrees',
91
+ /** 删掉一个已保留 / 没有会话的 worktree(params = WorkspaceRemoveWorktreeParams)。 */
92
+ WORKSPACE_REMOVE_WORKTREE: 'workspace.remove_worktree',
93
+ /** D→C notification */
94
+ WORKSPACE_CHANGED: 'workspace.changed',
95
+ /** D→C notification */
96
+ JOB_PROGRESS: 'job.progress',
97
+ /** D→C notification */
98
+ JOB_DONE: 'job.done',
99
+ JOB_CANCEL: 'job.cancel',
100
+
101
+ // fs
102
+ FS_LIST: 'fs.list',
103
+ FS_READ: 'fs.read',
104
+
105
+ // session
106
+ SESSION_LIST: 'session.list',
107
+ SESSION_GET: 'session.get',
108
+ SESSION_CREATE: 'session.create',
109
+ SESSION_SEND: 'session.send',
110
+ SESSION_CANCEL: 'session.cancel',
111
+ SESSION_SET_SETTINGS: 'session.set_settings',
112
+ SESSION_WATCH: 'session.watch',
113
+ SESSION_UNWATCH: 'session.unwatch',
114
+ SESSION_HISTORY: 'session.history',
115
+ /** D→C notification,params = SessionEvent */
116
+ SESSION_EVENT: 'session.event',
117
+ /** D→C notification,params = SessionChanged */
118
+ SESSION_CHANGED: 'session.changed',
119
+ SESSION_RENAME: 'session.rename',
120
+ SESSION_ARCHIVE: 'session.archive',
121
+ SESSION_UNARCHIVE: 'session.unarchive',
122
+ SESSION_DELETE: 'session.delete',
123
+ SESSION_RESTART: 'session.restart',
124
+ SESSION_SEARCH: 'session.search',
125
+ SESSION_PROMOTE: 'session.promote',
126
+ /** params = SessionGitStatusParams → SessionGitStatus(ADR-34) */
127
+ SESSION_GIT_STATUS: 'session.git_status',
128
+ /** params = SessionDiffParams → SessionDiffResult */
129
+ SESSION_DIFF: 'session.diff',
130
+ /** params = SessionSyncBaseParams → SessionSyncBaseResult */
131
+ SESSION_SYNC_BASE: 'session.sync_base',
132
+
133
+ // blob(附件,ADR-35)
134
+ /** params = BlobPutBeginParams → BlobPutBeginResult */
135
+ BLOB_PUT_BEGIN: 'blob.put_begin',
136
+ /** params = BlobPutChunkParams */
137
+ BLOB_PUT_CHUNK: 'blob.put_chunk',
138
+ /** params = BlobIdParams → AttachmentRef */
139
+ BLOB_PUT_END: 'blob.put_end',
140
+ /** params = BlobGetParams → BlobGetResult */
141
+ BLOB_GET: 'blob.get',
142
+ /** params = BlobIdParams */
143
+ BLOB_DISCARD: 'blob.discard',
144
+
145
+ // permission
146
+ /** D→C notification,params = PermissionRequest */
147
+ PERMISSION_REQUEST: 'permission.request',
148
+ PERMISSION_RESPOND: 'permission.respond',
149
+ /** D→C notification,params = PermissionResolved */
150
+ PERMISSION_RESOLVED: 'permission.resolved',
151
+ PERMISSION_LIST: 'permission.list',
152
+ } as const
153
+
154
+ export type MethodName = (typeof METHODS)[keyof typeof METHODS]
155
+
156
+ /**
157
+ * `ErrorCode` → JSON-RPC 数字 code(`crates/protocol/src/error.rs` 的 `rpc_code`)。
158
+ * 客户端只应依赖 `error.data.code`;数字 code 仅在对端没带 `data` 时做兜底。
159
+ */
160
+ export const ERROR_CODE_NUMBERS = {
161
+ invalid: -32602,
162
+ invalid_settings: -32001,
163
+ agent_unavailable: -32002,
164
+ node_busy: -32003,
165
+ busy: -32004,
166
+ already_resolved: -32005,
167
+ exists: -32006,
168
+ not_found: -32007,
169
+ forbidden: -32008,
170
+ unsupported: -32009,
171
+ protocol_mismatch: -32010,
172
+ internal: -32603,
173
+ } as const