paseo-plugin-zcode-provider 0.0.0-stage → 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.
Files changed (141) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +29 -0
  3. package/README.md +112 -2
  4. package/client/account.tsx +827 -0
  5. package/client/diagnostics.tsx +379 -0
  6. package/client/runtime.tsx +296 -0
  7. package/client/settings.tsx +84 -0
  8. package/client/value.tsx +20 -0
  9. package/icon.svg +1 -0
  10. package/index.client.tsx +22 -0
  11. package/index.server.ts +39 -0
  12. package/package.json +77 -4
  13. package/paseo-plugin.json +6 -0
  14. package/server/account.ts +781 -0
  15. package/server/attachments.ts +150 -0
  16. package/server/build-info.ts +2 -0
  17. package/server/conversation.ts +319 -0
  18. package/server/diagnostics.ts +252 -0
  19. package/server/discovery/discover.ts +225 -0
  20. package/server/discovery/manifest.ts +36 -0
  21. package/server/discovery/types.ts +30 -0
  22. package/server/errors.ts +36 -0
  23. package/server/host/bridge.ts +490 -0
  24. package/server/host/schemas.ts +119 -0
  25. package/server/logger.ts +19 -0
  26. package/server/mapping.ts +270 -0
  27. package/server/models.ts +68 -0
  28. package/server/persistence.ts +146 -0
  29. package/server/presentation.ts +470 -0
  30. package/server/provider-status.ts +81 -0
  31. package/server/provider.ts +838 -0
  32. package/server/runtime/managed.ts +501 -0
  33. package/server/runtime/pins.ts +72 -0
  34. package/server/runtime-setup.ts +77 -0
  35. package/server/session-types.ts +49 -0
  36. package/server/session.ts +866 -0
  37. package/server/status.ts +89 -0
  38. package/server/timeline.ts +18 -0
  39. package/server/usage.ts +362 -0
  40. package/server/vendor/zcode/LICENSE +202 -0
  41. package/server/vendor/zcode/NOTICE.md +70 -0
  42. package/server/vendor/zcode/THIRD-PARTY-NOTICES.md +37 -0
  43. package/server/vendor/zcode/packages/model-option-map/src/compiler.ts +92 -0
  44. package/server/vendor/zcode/packages/model-option-map/src/evaluator.ts +214 -0
  45. package/server/vendor/zcode/packages/model-option-map/src/index.ts +5 -0
  46. package/server/vendor/zcode/packages/model-option-map/src/merge-patch.ts +97 -0
  47. package/server/vendor/zcode/packages/model-option-map/src/option-maps.ts +42 -0
  48. package/server/vendor/zcode/packages/model-option-map/src/parser.ts +240 -0
  49. package/server/vendor/zcode/packages/model-option-map/src/tokenizer.ts +141 -0
  50. package/server/vendor/zcode/packages/model-option-map/src/types.ts +36 -0
  51. package/server/vendor/zcode/packages/rpc/src/buffer.ts +88 -0
  52. package/server/vendor/zcode/packages/rpc/src/channelClient.ts +275 -0
  53. package/server/vendor/zcode/packages/rpc/src/channelServer.ts +283 -0
  54. package/server/vendor/zcode/packages/rpc/src/channels.shared.ts +66 -0
  55. package/server/vendor/zcode/packages/rpc/src/channels.ts +4 -0
  56. package/server/vendor/zcode/packages/rpc/src/delayedChannel.ts +17 -0
  57. package/server/vendor/zcode/packages/rpc/src/foundation.ts +260 -0
  58. package/server/vendor/zcode/packages/rpc/src/protocol.ts +397 -0
  59. package/server/vendor/zcode/packages/rpc/src/proxy-channel.ts +213 -0
  60. package/server/vendor/zcode/packages/rpc/src/serialization.ts +291 -0
  61. package/server/vendor/zcode/packages/shared/src/account-provider-state.ts +13 -0
  62. package/server/vendor/zcode/packages/shared/src/background-bash-output.ts +24 -0
  63. package/server/vendor/zcode/packages/shared/src/background-task-controls.ts +404 -0
  64. package/server/vendor/zcode/packages/shared/src/bash-output-display.ts +11 -0
  65. package/server/vendor/zcode/packages/shared/src/bots.ts +558 -0
  66. package/server/vendor/zcode/packages/shared/src/browser-use/backend.ts +80 -0
  67. package/server/vendor/zcode/packages/shared/src/browser-use/command-metadata.ts +170 -0
  68. package/server/vendor/zcode/packages/shared/src/browser-use/commands.ts +588 -0
  69. package/server/vendor/zcode/packages/shared/src/browser-use/result.ts +130 -0
  70. package/server/vendor/zcode/packages/shared/src/browser-use/snapshot.ts +77 -0
  71. package/server/vendor/zcode/packages/shared/src/command-types.ts +96 -0
  72. package/server/vendor/zcode/packages/shared/src/config-schema.ts +8 -0
  73. package/server/vendor/zcode/packages/shared/src/cuaAccessibilitySettings.ts +41 -0
  74. package/server/vendor/zcode/packages/shared/src/database-startup.ts +178 -0
  75. package/server/vendor/zcode/packages/shared/src/env.ts +63 -0
  76. package/server/vendor/zcode/packages/shared/src/execution-output-preview.ts +14 -0
  77. package/server/vendor/zcode/packages/shared/src/localTtft.ts +192 -0
  78. package/server/vendor/zcode/packages/shared/src/model-config.ts +123 -0
  79. package/server/vendor/zcode/packages/shared/src/model-execution.ts +23 -0
  80. package/server/vendor/zcode/packages/shared/src/model-provider-family.ts +171 -0
  81. package/server/vendor/zcode/packages/shared/src/model-provider-types.ts +81 -0
  82. package/server/vendor/zcode/packages/shared/src/model-selection.ts +60 -0
  83. package/server/vendor/zcode/packages/shared/src/oauth.ts +203 -0
  84. package/server/vendor/zcode/packages/shared/src/official-mcp-auth.ts +272 -0
  85. package/server/vendor/zcode/packages/shared/src/official-mcp-tool-error.ts +68 -0
  86. package/server/vendor/zcode/packages/shared/src/process-diagnostic.ts +42 -0
  87. package/server/vendor/zcode/packages/shared/src/protocol.ts +369 -0
  88. package/server/vendor/zcode/packages/shared/src/provider-family-connection-selection.ts +32 -0
  89. package/server/vendor/zcode/packages/shared/src/remoteAssetInstallMode.ts +11 -0
  90. package/server/vendor/zcode/packages/shared/src/remoteResourcePackages.ts +91 -0
  91. package/server/vendor/zcode/packages/shared/src/runtimeEnv.ts +315 -0
  92. package/server/vendor/zcode/packages/shared/src/settings-source.ts +10 -0
  93. package/server/vendor/zcode/packages/shared/src/usage-quota.ts +74 -0
  94. package/server/vendor/zcode/packages/shared/src/usage-stats.ts +462 -0
  95. package/server/vendor/zcode/packages/shared/src/validationAppSettings.ts +562 -0
  96. package/server/vendor/zcode/packages/shared/src/workspacePurpose.ts +2 -0
  97. package/server/vendor/zcode/packages/shared/src/wslUserValidation.ts +33 -0
  98. package/server/vendor/zcode/packages/shared/src/zcode-agent-policy.ts +25 -0
  99. package/server/vendor/zcode/packages/shared/src/zcode-media-policy.ts +10 -0
  100. package/server/vendor/zcode/packages/shared/src/zcode-protocol/index.ts +3720 -0
  101. package/server/vendor/zcode/packages/shared/src/zcode-protocol-legacy-types.ts +529 -0
  102. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/apply.ts +218 -0
  103. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/attachment-ref.ts +14 -0
  104. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/command.ts +482 -0
  105. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/core.ts +100 -0
  106. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/create-workflow-display.ts +156 -0
  107. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/cuaPermission.ts +41 -0
  108. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/delta.ts +147 -0
  109. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/input-intent.ts +69 -0
  110. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/rows.ts +432 -0
  111. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/session-config.ts +43 -0
  112. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index-workflow-activity.ts +195 -0
  113. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index.ts +85 -0
  114. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/shared-context-import.ts +38 -0
  115. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/shared-context-ref.ts +10 -0
  116. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/snapshot.ts +509 -0
  117. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/submission.ts +5 -0
  118. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/toolDisplay.ts +264 -0
  119. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/transport.ts +1152 -0
  120. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-assembler.ts +574 -0
  121. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-binary.ts +65 -0
  122. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-codec.ts +240 -0
  123. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-fault.ts +39 -0
  124. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire.ts +159 -0
  125. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-artifacts.ts +291 -0
  126. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-observation-display.ts +281 -0
  127. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-row-meta.ts +163 -0
  128. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-run-settings-command.ts +62 -0
  129. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs-delta.ts +517 -0
  130. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs.ts +512 -0
  131. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workspace-config.ts +81 -0
  132. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workspace-hook-review.ts +210 -0
  133. package/server/vendor/zcode/packages/shared/src/zcode-task-mode-schema.ts +6 -0
  134. package/server/vendor/zcode/packages/shared/src/zcode-task-types-core.ts +1187 -0
  135. package/server/vendor/zcode/packages/shared/src/zcodeEndpoint.ts +296 -0
  136. package/server/vendor/zcode/provenance.json +405 -0
  137. package/shared/account.ts +201 -0
  138. package/shared/diagnostics.ts +52 -0
  139. package/shared/runtime-setup.ts +73 -0
  140. package/vendor/acp-registry/LICENSE +176 -0
  141. package/vendor/paseo/LICENSE +211 -0
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Layer 5: ProxyChannel —— 服务自动代理(杀手锏)
3
+ *
4
+ * 这是让 VS Code 开发者效率极高的关键抽象。
5
+ *
6
+ * 没有 ProxyChannel 时,你需要为每个服务手写 IServerChannel:
7
+ * class FileServiceChannel implements IServerChannel {
8
+ * call(ctx, command, arg) {
9
+ * switch (command) {
10
+ * case 'readFile': return this.service.readFile(arg[0]);
11
+ * case 'writeFile': return this.service.writeFile(arg[0], arg[1]);
12
+ * // ... 每个方法都要手动映射
13
+ * }
14
+ * }
15
+ * }
16
+ *
17
+ * 有了 ProxyChannel,一行代码搞定:
18
+ * const channel = ProxyChannel.fromService(fileService);
19
+ * // 自动把所有方法映射为 call,所有 on* 事件映射为 listen
20
+ *
21
+ * 客户端同样一行:
22
+ * const fileService = ProxyChannel.toService<IFileService>(channel);
23
+ * await fileService.readFile(uri); // 就像调用本地方法!
24
+ *
25
+ * 原理:
26
+ * - fromService: 遍历 service 的属性,方法 → call,on* 事件 → listen
27
+ * - toService: 利用 ES6 Proxy 拦截属性访问,自动分派到 call/listen
28
+ */
29
+
30
+ import { Event, Emitter, IDisposable, DisposableStore } from "./foundation.js";
31
+ import { IChannel, IServerChannel } from "./channels.js";
32
+
33
+ // ============================================================================
34
+ // ProxyChannel
35
+ // ============================================================================
36
+
37
+ export namespace ProxyChannel {
38
+ /**
39
+ * 服务端:把一个 service 对象自动包装为 IServerChannel
40
+ *
41
+ * 约定:
42
+ * - 以 on + 大写字母开头的属性视为事件 (如 onDidChange)
43
+ * - 以 onDynamic + 大写字母开头的视为动态事件(方法,调用后返回事件)
44
+ * - 其他方法视为 RPC 方法
45
+ */
46
+ export function fromService<TContext>(
47
+ service: unknown,
48
+ disposables?: DisposableStore,
49
+ ): IServerChannel<TContext> {
50
+ const handler = service as { [key: string]: unknown };
51
+
52
+ // 预缓存所有事件并 buffer
53
+ const eventMap = new Map<string, Event<unknown>>();
54
+ for (const key in handler) {
55
+ if (isEvent(key) && !isDynamicEvent(key) && typeof handler[key] === "function") {
56
+ // 把事件 buffer 化:即使没人订阅,事件也不会丢失
57
+ eventMap.set(key, bufferEvent(handler[key] as Event<unknown>));
58
+ }
59
+ }
60
+
61
+ return {
62
+ listen<T>(_ctx: TContext, event: string, arg?: any): Event<T> {
63
+ // 先查缓存
64
+ const cached = eventMap.get(event);
65
+ if (cached) {
66
+ return cached as Event<T>;
67
+ }
68
+
69
+ const target = handler[event];
70
+ if (typeof target === "function") {
71
+ // 动态事件:onDynamicXxx(arg) 返回一个 Event
72
+ if (isDynamicEvent(event)) {
73
+ return target.call(handler, arg);
74
+ }
75
+ // 延迟发现的事件(Proxy 服务可能不会在 for-in 中出现)
76
+ if (isEvent(event)) {
77
+ eventMap.set(event, bufferEvent(handler[event] as Event<unknown>));
78
+ return eventMap.get(event) as Event<T>;
79
+ }
80
+ }
81
+
82
+ throw new Error(`Event not found: ${event}`);
83
+ },
84
+
85
+ call<T>(_ctx: TContext, command: string, args?: any[]): Promise<T> {
86
+ const target = handler[command];
87
+ if (typeof target === "function") {
88
+ let result = target.apply(handler, args || []);
89
+ if (!(result instanceof Promise)) {
90
+ result = Promise.resolve(result);
91
+ }
92
+ return result;
93
+ }
94
+ throw new Error(`Method not found: ${command}`);
95
+ },
96
+ };
97
+ }
98
+
99
+ /**
100
+ * 客户端:把一个 IChannel 包装成类型安全的 service 对象
101
+ *
102
+ * 利用 ES6 Proxy 拦截所有属性访问:
103
+ * - 访问 on* → channel.listen(propKey)
104
+ * - 访问其他 → 返回一个函数,调用时变成 channel.call(propKey, args)
105
+ */
106
+ export function toService<T extends object>(
107
+ channel: IChannel,
108
+ options?: { context?: unknown },
109
+ ): T {
110
+ return new Proxy({} as T, {
111
+ get(target: T, propKey: PropertyKey, receiver: object) {
112
+ // React 开发态、日志工具和浏览器运行时会探测对象的 Symbol / then 等内置属性。
113
+ // 之前这里把所有未知属性都强行当成 RPC 成员处理,读取 Symbol.toStringTag 会直接抛错,
114
+ // 读取 then 还会把普通 service 误判成 thenable,导致远程 workspace 在选目录后重渲染时炸掉。
115
+ // 这类运行时探测属性应该回退到普通对象语义,而不是走 RPC。
116
+ if (typeof propKey === "symbol") {
117
+ return Reflect.get(target as object, propKey, receiver);
118
+ }
119
+
120
+ if (typeof propKey === "string") {
121
+ if (propKey === "then") {
122
+ return undefined;
123
+ }
124
+
125
+ // 动态事件
126
+ if (isDynamicEvent(propKey)) {
127
+ return (arg: unknown) => channel.listen(propKey, arg);
128
+ }
129
+
130
+ // 普通事件
131
+ if (isEvent(propKey)) {
132
+ return channel.listen(propKey);
133
+ }
134
+
135
+ // 方法调用
136
+ return async (...args: unknown[]) => {
137
+ // 可选:注入 context 作为第一个参数
138
+ const methodArgs = options?.context !== undefined ? [options.context, ...args] : args;
139
+ return channel.call(propKey, methodArgs);
140
+ };
141
+ }
142
+
143
+ return Reflect.get(target as object, propKey, receiver);
144
+ },
145
+ });
146
+ }
147
+ }
148
+
149
+ // ============================================================================
150
+ // 辅助函数
151
+ // ============================================================================
152
+
153
+ /** 匹配 onXxx 事件命名约定 */
154
+ function isEvent(name: string): boolean {
155
+ return (
156
+ name.length >= 3 &&
157
+ name[0] === "o" &&
158
+ name[1] === "n" &&
159
+ name.charCodeAt(2) >= 65 && // A
160
+ name.charCodeAt(2) <= 90
161
+ ); // Z
162
+ }
163
+
164
+ /** 匹配 onDynamicXxx 动态事件命名约定 */
165
+ function isDynamicEvent(name: string): boolean {
166
+ return (
167
+ name.length >= 10 &&
168
+ name.startsWith("onDynamic") &&
169
+ name.charCodeAt(9) >= 65 &&
170
+ name.charCodeAt(9) <= 90
171
+ );
172
+ }
173
+
174
+ /**
175
+ * 缓冲事件:确保在订阅之前触发的事件不会丢失。
176
+ * 未订阅时事件存入队列,一有订阅者就 flush。
177
+ */
178
+ function bufferEvent<T>(event: Event<T>): Event<T> {
179
+ let buffer: T[] = [];
180
+ let flushing = false;
181
+ let listener: IDisposable | undefined;
182
+
183
+ const emitter = new Emitter<T>({
184
+ onWillAddFirstListener: () => {
185
+ listener = event((e) => {
186
+ if (flushing) {
187
+ emitter.fire(e);
188
+ } else {
189
+ buffer.push(e);
190
+ }
191
+ });
192
+ },
193
+ onDidRemoveLastListener: () => {
194
+ listener?.dispose();
195
+ listener = undefined;
196
+ buffer = [];
197
+ },
198
+ });
199
+
200
+ // 一旦有订阅者,先 flush 缓冲区
201
+ const originalEvent = emitter.event;
202
+ return (listener_fn) => {
203
+ const disposable = originalEvent(listener_fn);
204
+ if (!flushing) {
205
+ flushing = true;
206
+ for (const item of buffer) {
207
+ emitter.fire(item);
208
+ }
209
+ buffer = [];
210
+ }
211
+ return disposable;
212
+ };
213
+ }
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Layer 1: 二进制序列化
3
+ *
4
+ * RPC 消息需要编码为二进制才能通过 IMessagePassingProtocol 传输。
5
+ * 这里实现了 VS Code 的自定义序列化协议:
6
+ *
7
+ * 格式: [1 byte 类型标签] [VQL 编码的长度] [数据]
8
+ *
9
+ * VQL (Variable-Length Quantity) 用 7 bit 存数据,最高位标记是否还有后续字节。
10
+ * 小数字只需 1 byte,大数字按需扩展,比固定 4 byte 更紧凑。
11
+ */
12
+
13
+ import { VSBuffer } from "./buffer.js";
14
+
15
+ // ============================================================================
16
+ // Reader / Writer 接口
17
+ // ============================================================================
18
+
19
+ export interface IReader {
20
+ read(bytes: number): VSBuffer;
21
+ }
22
+
23
+ export interface IWriter {
24
+ write(buffer: VSBuffer): void;
25
+ }
26
+
27
+ /**
28
+ * BufferReader: 从一个 VSBuffer 中按顺序读取数据。
29
+ * 内部维护一个 pos 游标。
30
+ */
31
+ export class BufferReader implements IReader {
32
+ private pos = 0;
33
+
34
+ constructor(private buffer: VSBuffer) {}
35
+
36
+ read(bytes: number): VSBuffer {
37
+ const result = this.buffer.slice(this.pos, this.pos + bytes);
38
+ this.pos += result.byteLength;
39
+ return result;
40
+ }
41
+ }
42
+
43
+ /**
44
+ * BufferWriter: 收集多个写入的 buffer,最后通过 .buffer 属性一次性拼接。
45
+ * 避免了写入时频繁的内存拷贝。
46
+ */
47
+ export class BufferWriter implements IWriter {
48
+ private buffers: VSBuffer[] = [];
49
+
50
+ get buffer(): VSBuffer {
51
+ return VSBuffer.concat(this.buffers);
52
+ }
53
+
54
+ write(buffer: VSBuffer): void {
55
+ this.buffers.push(buffer);
56
+ }
57
+ }
58
+
59
+ // ============================================================================
60
+ // VQL 编码
61
+ // ============================================================================
62
+
63
+ /**
64
+ * 读取 VQL 编码的整数
65
+ * @see https://en.wikipedia.org/wiki/Variable-length_quantity
66
+ */
67
+ function readIntVQL(reader: IReader): number {
68
+ let value = 0;
69
+ for (let n = 0; ; n += 7) {
70
+ const next = reader.read(1);
71
+ value |= (next.buffer[0] & 0b01111111) << n;
72
+ if (!(next.buffer[0] & 0b10000000)) {
73
+ return value;
74
+ }
75
+ }
76
+ }
77
+
78
+ const vqlZero = createOneByteBuffer(0);
79
+
80
+ /**
81
+ * 写入 VQL 编码的整数
82
+ * 例: 0 → [0x00], 127 → [0x7F], 128 → [0x80, 0x01]
83
+ */
84
+ function writeInt32VQL(writer: IWriter, value: number): void {
85
+ if (value === 0) {
86
+ writer.write(vqlZero);
87
+ return;
88
+ }
89
+ let len = 0;
90
+ for (let v = value; v !== 0; v = v >>> 7) {
91
+ len++;
92
+ }
93
+
94
+ const scratch = VSBuffer.alloc(len);
95
+ for (let i = 0; value !== 0; i++) {
96
+ scratch.buffer[i] = value & 0b01111111;
97
+ value = value >>> 7;
98
+ if (value > 0) {
99
+ scratch.buffer[i] |= 0b10000000;
100
+ }
101
+ }
102
+ writer.write(scratch);
103
+ }
104
+
105
+ // ============================================================================
106
+ // 数据类型标签
107
+ // ============================================================================
108
+
109
+ enum DataType {
110
+ Undefined = 0,
111
+ String = 1,
112
+ Buffer = 2,
113
+ VSBuffer = 3,
114
+ Array = 4,
115
+ Object = 5, // JSON fallback
116
+ Int = 6, // VQL 编码的整数
117
+ }
118
+
119
+ function createOneByteBuffer(value: number): VSBuffer {
120
+ const result = VSBuffer.alloc(1);
121
+ result.writeUInt8(value, 0);
122
+ return result;
123
+ }
124
+
125
+ /** 预创建的类型标签 buffer,避免每次序列化都分配内存 */
126
+ const BufferPresets = {
127
+ Undefined: createOneByteBuffer(DataType.Undefined),
128
+ String: createOneByteBuffer(DataType.String),
129
+ Buffer: createOneByteBuffer(DataType.Buffer),
130
+ VSBuffer: createOneByteBuffer(DataType.VSBuffer),
131
+ Array: createOneByteBuffer(DataType.Array),
132
+ Object: createOneByteBuffer(DataType.Object),
133
+ Int: createOneByteBuffer(DataType.Int),
134
+ };
135
+
136
+ const RPC_NESTED_UINT8_ARRAY_MARKER = "__zcode_rpc_nested_uint8array_v1";
137
+ const RPC_NESTED_UINT8_ARRAY_BASE64_KEY = "base64";
138
+
139
+ // ============================================================================
140
+ // serialize / deserialize
141
+ // ============================================================================
142
+
143
+ /**
144
+ * 序列化任意数据到 writer。
145
+ *
146
+ * 格式:[1 byte 类型] [VQL 长度(如果需要)] [数据]
147
+ *
148
+ * 每条 RPC 消息 = serialize(header) + serialize(body)
149
+ * header 通常是 [RequestType, id, channelName, methodName]
150
+ * body 是方法参数或返回值
151
+ */
152
+ export function serialize(writer: IWriter, data: any): void {
153
+ if (typeof data === "undefined") {
154
+ writer.write(BufferPresets.Undefined);
155
+ } else if (typeof data === "string") {
156
+ const buffer = VSBuffer.fromString(data);
157
+ writer.write(BufferPresets.String);
158
+ writeInt32VQL(writer, buffer.byteLength);
159
+ writer.write(buffer);
160
+ } else if (data instanceof VSBuffer) {
161
+ writer.write(BufferPresets.VSBuffer);
162
+ writeInt32VQL(writer, data.byteLength);
163
+ writer.write(data);
164
+ } else if (data instanceof Uint8Array) {
165
+ const buffer = VSBuffer.wrap(data);
166
+ writer.write(BufferPresets.Buffer);
167
+ writeInt32VQL(writer, buffer.byteLength);
168
+ writer.write(buffer);
169
+ } else if (Array.isArray(data)) {
170
+ writer.write(BufferPresets.Array);
171
+ writeInt32VQL(writer, data.length);
172
+ for (const el of data) {
173
+ serialize(writer, el);
174
+ }
175
+ } else if (typeof data === "number" && (data | 0) === data) {
176
+ // 整数用 VQL 编码,比 JSON 更紧凑
177
+ writer.write(BufferPresets.Int);
178
+ writeInt32VQL(writer, data);
179
+ } else {
180
+ // 对象字段里的 Uint8Array 之前会被 JSON.stringify 展开成 {"0":...},
181
+ // 远端 RPC 收到后不再是二进制,skill sync 这类归档传输会在解压阶段失败。
182
+ // 这里保持 Object JSON fallback 的协议形态,只对嵌套 Uint8Array 加标记并在反序列化时恢复。
183
+ const buffer = VSBuffer.fromString(JSON.stringify(data, encodeRpcJsonValue));
184
+ writer.write(BufferPresets.Object);
185
+ writeInt32VQL(writer, buffer.byteLength);
186
+ writer.write(buffer);
187
+ }
188
+ }
189
+
190
+ /**
191
+ * 从 reader 反序列化数据
192
+ */
193
+ export function deserialize(reader: IReader): any {
194
+ const type = reader.read(1).readUInt8(0);
195
+
196
+ switch (type) {
197
+ case DataType.Undefined:
198
+ return undefined;
199
+ case DataType.String:
200
+ return reader.read(readIntVQL(reader)).toString();
201
+ case DataType.Buffer:
202
+ return reader.read(readIntVQL(reader)).buffer;
203
+ case DataType.VSBuffer:
204
+ return reader.read(readIntVQL(reader));
205
+ case DataType.Array: {
206
+ const length = readIntVQL(reader);
207
+ const result: any[] = [];
208
+ for (let i = 0; i < length; i++) {
209
+ result.push(deserialize(reader));
210
+ }
211
+ return result;
212
+ }
213
+ case DataType.Object:
214
+ return JSON.parse(reader.read(readIntVQL(reader)).toString(), decodeRpcJsonValue);
215
+ case DataType.Int:
216
+ return readIntVQL(reader);
217
+ }
218
+ }
219
+
220
+ function encodeRpcJsonValue(_key: string, value: unknown): unknown {
221
+ if (value instanceof Uint8Array) {
222
+ return {
223
+ [RPC_NESTED_UINT8_ARRAY_MARKER]: true,
224
+ [RPC_NESTED_UINT8_ARRAY_BASE64_KEY]: bytesToBase64(value),
225
+ };
226
+ }
227
+ return value;
228
+ }
229
+
230
+ function decodeRpcJsonValue(_key: string, value: unknown): unknown {
231
+ if (!isRpcEncodedUint8Array(value)) {
232
+ return value;
233
+ }
234
+ return base64ToBytes(value[RPC_NESTED_UINT8_ARRAY_BASE64_KEY]);
235
+ }
236
+
237
+ function isRpcEncodedUint8Array(value: unknown): value is {
238
+ [RPC_NESTED_UINT8_ARRAY_MARKER]: true;
239
+ [RPC_NESTED_UINT8_ARRAY_BASE64_KEY]: string;
240
+ } {
241
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
242
+ return false;
243
+ }
244
+ const record = value as Record<string, unknown>;
245
+ return (
246
+ record[RPC_NESTED_UINT8_ARRAY_MARKER] === true &&
247
+ typeof record[RPC_NESTED_UINT8_ARRAY_BASE64_KEY] === "string" &&
248
+ Object.keys(record).length === 2
249
+ );
250
+ }
251
+
252
+ function bytesToBase64(bytes: Uint8Array): string {
253
+ const bufferCtor = (
254
+ globalThis as {
255
+ Buffer?: {
256
+ from(input: Uint8Array): { toString(encoding: "base64"): string };
257
+ };
258
+ }
259
+ ).Buffer;
260
+ if (bufferCtor) {
261
+ return bufferCtor.from(bytes).toString("base64");
262
+ }
263
+
264
+ let binary = "";
265
+ const chunkSize = 0x8000;
266
+ for (let offset = 0; offset < bytes.length; offset += chunkSize) {
267
+ const chunk = bytes.subarray(offset, offset + chunkSize);
268
+ binary += String.fromCharCode(...chunk);
269
+ }
270
+ return globalThis.btoa(binary);
271
+ }
272
+
273
+ function base64ToBytes(base64: string): Uint8Array {
274
+ const bufferCtor = (
275
+ globalThis as {
276
+ Buffer?: {
277
+ from(input: string, encoding: "base64"): Uint8Array;
278
+ };
279
+ }
280
+ ).Buffer;
281
+ if (bufferCtor) {
282
+ return new Uint8Array(bufferCtor.from(base64, "base64"));
283
+ }
284
+
285
+ const binary = globalThis.atob(base64);
286
+ const bytes = new Uint8Array(binary.length);
287
+ for (let index = 0; index < binary.length; index += 1) {
288
+ bytes[index] = binary.charCodeAt(index);
289
+ }
290
+ return bytes;
291
+ }
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+
3
+ // 原因随 Account State 发送,必须与严格协议共用枚举,避免整份快照被拒绝。
4
+ // credential-failed 表示凭据获取/校验失败,不能据此断言 OAuth 已失效。
5
+ export const accountProviderUnavailableReasonSchema = z.enum([
6
+ "not-authenticated",
7
+ "not-connected",
8
+ "credential-failed",
9
+ "not-entitled",
10
+ ]);
11
+ export type AccountProviderUnavailableReason = z.infer<
12
+ typeof accountProviderUnavailableReasonSchema
13
+ >;
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+
3
+ export const BACKGROUND_BASH_OUTPUT_MAX_BYTES = 8192;
4
+
5
+ /** 后台详情的单次文件快照;不进入 conversation snapshot 或持久化事件。 */
6
+ export const backgroundBashOutputSchema = z.strictObject({
7
+ kind: z.literal("output"),
8
+ workId: z.string().min(1),
9
+ status: z.enum(["running", "completed", "failed", "timed_out", "cancelled", "spawn_error"]),
10
+ output: z.string().max(BACKGROUND_BASH_OUTPUT_MAX_BYTES),
11
+ truncated: z.boolean(),
12
+ outputPath: z.string().min(1),
13
+ });
14
+
15
+ export const backgroundBashOutputResultSchema = z.union([
16
+ backgroundBashOutputSchema,
17
+ z.strictObject({
18
+ kind: z.enum(["unavailable", "unsupported", "read_failed"]),
19
+ workId: z.string().min(1),
20
+ code: z.string().optional(),
21
+ }),
22
+ ]);
23
+ export type BackgroundBashOutput = z.infer<typeof backgroundBashOutputSchema>;
24
+ export type BackgroundBashOutputResult = z.infer<typeof backgroundBashOutputResultSchema>;