wave-agent-sdk 1.2.0 → 1.3.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 (175) hide show
  1. package/dist/agent.d.ts +58 -4
  2. package/dist/agent.js +91 -19
  3. package/dist/builtin/index.js +2 -0
  4. package/dist/builtin/skills/settings.js +1 -12
  5. package/dist/builtin/skills/wave-daemon.d.ts +1 -0
  6. package/dist/builtin/skills/wave-daemon.js +194 -0
  7. package/dist/constants/images.d.ts +26 -0
  8. package/dist/constants/images.js +26 -0
  9. package/dist/constants/index.d.ts +16 -0
  10. package/dist/constants/index.js +16 -0
  11. package/dist/constants/memory.d.ts +26 -0
  12. package/dist/constants/memory.js +34 -0
  13. package/dist/constants/messages.d.ts +11 -0
  14. package/dist/constants/messages.js +11 -0
  15. package/dist/constants/plugins.d.ts +8 -0
  16. package/dist/constants/plugins.js +8 -0
  17. package/dist/constants/tools.d.ts +1 -0
  18. package/dist/constants/tools.js +1 -0
  19. package/dist/core/plugin.d.ts +53 -13
  20. package/dist/core/plugin.js +134 -26
  21. package/dist/core/session.d.ts +1 -1
  22. package/dist/core/session.js +1 -1
  23. package/dist/exec/catalog.d.ts +140 -0
  24. package/dist/exec/catalog.js +470 -0
  25. package/dist/exec/catalogAnnouncement.d.ts +89 -0
  26. package/dist/exec/catalogAnnouncement.js +293 -0
  27. package/dist/exec/constants.d.ts +51 -0
  28. package/dist/exec/constants.js +51 -0
  29. package/dist/exec/execRuntime.d.ts +55 -0
  30. package/dist/exec/execRuntime.js +217 -0
  31. package/dist/exec/workerSource.d.ts +28 -0
  32. package/dist/exec/workerSource.js +299 -0
  33. package/dist/host/index.d.ts +23 -0
  34. package/dist/host/index.js +23 -0
  35. package/dist/index.d.ts +5 -0
  36. package/dist/index.js +6 -0
  37. package/dist/managers/MemoryRuleManager.d.ts +6 -0
  38. package/dist/managers/MemoryRuleManager.js +12 -0
  39. package/dist/managers/aiManager.d.ts +35 -1
  40. package/dist/managers/aiManager.js +190 -21
  41. package/dist/managers/backgroundTaskManager.js +14 -0
  42. package/dist/managers/hookManager.d.ts +13 -0
  43. package/dist/managers/hookManager.js +31 -4
  44. package/dist/managers/liveConfigManager.d.ts +33 -0
  45. package/dist/managers/liveConfigManager.js +103 -8
  46. package/dist/managers/lspManager.d.ts +9 -0
  47. package/dist/managers/lspManager.js +47 -18
  48. package/dist/managers/mcpManager.d.ts +45 -10
  49. package/dist/managers/mcpManager.js +103 -1
  50. package/dist/managers/messageManager.d.ts +48 -5
  51. package/dist/managers/messageManager.js +107 -21
  52. package/dist/managers/permissionManager.d.ts +40 -0
  53. package/dist/managers/permissionManager.js +63 -8
  54. package/dist/managers/pluginManager.d.ts +46 -2
  55. package/dist/managers/pluginManager.js +117 -11
  56. package/dist/managers/pluginScopeManager.d.ts +15 -2
  57. package/dist/managers/pluginScopeManager.js +20 -1
  58. package/dist/managers/skillManager.d.ts +19 -0
  59. package/dist/managers/skillManager.js +44 -0
  60. package/dist/managers/slashCommandManager.d.ts +10 -0
  61. package/dist/managers/slashCommandManager.js +35 -3
  62. package/dist/managers/subagentManager.d.ts +8 -0
  63. package/dist/managers/subagentManager.js +20 -0
  64. package/dist/managers/toolManager.d.ts +29 -3
  65. package/dist/managers/toolManager.js +87 -13
  66. package/dist/prompts/autoMemory.d.ts +9 -0
  67. package/dist/prompts/autoMemory.js +30 -31
  68. package/dist/prompts/autoMemoryExtraction.d.ts +4 -0
  69. package/dist/prompts/autoMemoryExtraction.js +8 -111
  70. package/dist/prompts/memoryTypes.d.ts +63 -0
  71. package/dist/prompts/memoryTypes.js +191 -0
  72. package/dist/services/GitService.d.ts +7 -0
  73. package/dist/services/GitService.js +23 -0
  74. package/dist/services/MarketplaceService.d.ts +101 -17
  75. package/dist/services/MarketplaceService.js +318 -119
  76. package/dist/services/artifactContent.d.ts +84 -0
  77. package/dist/services/artifactContent.js +204 -0
  78. package/dist/services/artifactSession.d.ts +6 -0
  79. package/dist/services/artifactSession.js +17 -0
  80. package/dist/services/autoMemoryService.js +5 -13
  81. package/dist/services/configurationService.d.ts +60 -9
  82. package/dist/services/configurationService.js +129 -54
  83. package/dist/services/contentSummarizer.d.ts +15 -0
  84. package/dist/services/contentSummarizer.js +45 -0
  85. package/dist/services/execAvailability.d.ts +9 -0
  86. package/dist/services/execAvailability.js +32 -0
  87. package/dist/services/fileWatcher.js +61 -6
  88. package/dist/services/initializationService.js +19 -15
  89. package/dist/services/interactionService.d.ts +9 -1
  90. package/dist/services/interactionService.js +28 -8
  91. package/dist/services/jsonlHandler.d.ts +84 -0
  92. package/dist/services/jsonlHandler.js +209 -14
  93. package/dist/services/memory.d.ts +3 -1
  94. package/dist/services/memory.js +13 -9
  95. package/dist/services/officialMarketplaceMirror.js +3 -2
  96. package/dist/services/pluginLoader.d.ts +12 -4
  97. package/dist/services/pluginLoader.js +38 -7
  98. package/dist/services/remoteSettingsService.js +16 -2
  99. package/dist/services/session.d.ts +74 -0
  100. package/dist/services/session.js +144 -3
  101. package/dist/services/sessionEntries.d.ts +2 -0
  102. package/dist/services/sessionEntries.js +20 -0
  103. package/dist/stdio/index.d.ts +3 -1
  104. package/dist/stdio/index.js +3 -1
  105. package/dist/stdio/notificationRouter.js +1 -0
  106. package/dist/stdio/stdioAgent.d.ts +14 -7
  107. package/dist/stdio/stdioAgent.js +19 -0
  108. package/dist/tools/artifactTool.js +406 -273
  109. package/dist/tools/bashTool.js +8 -6
  110. package/dist/tools/editTool.js +6 -3
  111. package/dist/tools/execTool.d.ts +2 -0
  112. package/dist/tools/execTool.js +165 -0
  113. package/dist/tools/grepTool.js +7 -1
  114. package/dist/tools/readTool.js +30 -2
  115. package/dist/tools/types.d.ts +34 -8
  116. package/dist/tools/webFetchTool.js +15 -166
  117. package/dist/tools/workflowTool.js +40 -8
  118. package/dist/tools/writeTool.js +6 -3
  119. package/dist/types/agent.d.ts +20 -5
  120. package/dist/types/configuration.d.ts +39 -1
  121. package/dist/types/marketplace.d.ts +40 -2
  122. package/dist/types/mcp.d.ts +39 -0
  123. package/dist/types/permissions.d.ts +22 -0
  124. package/dist/types/permissions.js +17 -0
  125. package/dist/types/plugins.d.ts +26 -2
  126. package/dist/types/skills.d.ts +15 -0
  127. package/dist/utils/constants.d.ts +10 -0
  128. package/dist/utils/constants.js +10 -0
  129. package/dist/utils/containerSetup.js +43 -0
  130. package/dist/utils/convertMessagesForAPI.d.ts +7 -1
  131. package/dist/utils/convertMessagesForAPI.js +64 -14
  132. package/dist/utils/fileChangeReminder.d.ts +20 -0
  133. package/dist/utils/fileChangeReminder.js +153 -0
  134. package/dist/utils/fileSearch.js +4 -3
  135. package/dist/utils/fileUtils.d.ts +33 -0
  136. package/dist/utils/fileUtils.js +81 -0
  137. package/dist/utils/frontmatterYaml.d.ts +33 -0
  138. package/dist/utils/frontmatterYaml.js +192 -0
  139. package/dist/utils/imageBudget.d.ts +85 -0
  140. package/dist/utils/imageBudget.js +109 -0
  141. package/dist/utils/imageDimensions.d.ts +83 -0
  142. package/dist/utils/imageDimensions.js +232 -0
  143. package/dist/utils/imageProcessor.d.ts +66 -0
  144. package/dist/utils/imageProcessor.js +84 -0
  145. package/dist/utils/imageRewrite.d.ts +29 -0
  146. package/dist/utils/imageRewrite.js +251 -0
  147. package/dist/utils/markdownParser.d.ts +5 -1
  148. package/dist/utils/markdownParser.js +9 -51
  149. package/dist/utils/mcpInstructions.d.ts +61 -0
  150. package/dist/utils/mcpInstructions.js +126 -0
  151. package/dist/utils/mcpUtils.d.ts +7 -0
  152. package/dist/utils/mcpUtils.js +11 -2
  153. package/dist/utils/memoryAge.d.ts +32 -0
  154. package/dist/utils/memoryAge.js +47 -0
  155. package/dist/utils/memoryEntrypoint.d.ts +20 -0
  156. package/dist/utils/memoryEntrypoint.js +49 -0
  157. package/dist/utils/memoryIndex.d.ts +30 -0
  158. package/dist/utils/memoryIndex.js +76 -0
  159. package/dist/utils/messageOperations.d.ts +6 -2
  160. package/dist/utils/messageOperations.js +40 -29
  161. package/dist/utils/nestedMemory.d.ts +22 -0
  162. package/dist/utils/nestedMemory.js +61 -0
  163. package/dist/utils/npmTarball.d.ts +19 -0
  164. package/dist/utils/npmTarball.js +92 -0
  165. package/dist/utils/pluginSource.d.ts +37 -0
  166. package/dist/utils/pluginSource.js +73 -0
  167. package/dist/utils/ripgrep.d.ts +18 -4
  168. package/dist/utils/ripgrep.js +56 -4
  169. package/dist/utils/runtimeDeps.d.ts +35 -0
  170. package/dist/utils/runtimeDeps.js +426 -0
  171. package/dist/utils/skillParser.js +22 -52
  172. package/dist/utils/subagentParser.js +39 -43
  173. package/dist/utils/userSettings.d.ts +90 -0
  174. package/dist/utils/userSettings.js +291 -0
  175. package/package.json +10 -7
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Source of the Exec sandbox worker.
3
+ *
4
+ * It is a plain string evaluated with `new Worker(source, { eval: true })` so
5
+ * that no extra dist file is needed and no host bundler (esbuild in
6
+ * `packages/vscode`, the JetBrains/desktop packaging steps) has to know about
7
+ * it.
8
+ *
9
+ * Two properties are load-bearing and were both measured on Node 22:
10
+ *
11
+ * 1. **Isolation is a thread + plain-data boundary, not `node:vm`.** Handing a
12
+ * host function or host object to a `vm` context lets the script reach the
13
+ * HOST realm through `tools.x.constructor(...)` — `codeGeneration` cannot
14
+ * stop that, because the host realm has code generation enabled. So the
15
+ * sandbox receives no host value at all: every bridge is built inside the
16
+ * context and every value crossing back is deep-cloned into the context
17
+ * realm.
18
+ * 2. **Termination is `worker.terminate()`.** `vm`'s `{ timeout }` only bounds
19
+ * synchronous execution: `(async () => { await 0; while (true) {} })()`
20
+ * returns in ~1ms and then spins inside the host event loop forever, which
21
+ * hangs the whole process. `{ timeout }` is still passed as a cheap first
22
+ * line for purely synchronous spins.
23
+ *
24
+ * `codeGeneration: { strings: false, wasm: false }` remains the mechanism that
25
+ * blocks `eval` / `new Function` / dynamic `import` at the engine level.
26
+ */
27
+ /** The worker body. Receives `run` / `result` messages on the parent port. */
28
+ export declare const EXEC_WORKER_SOURCE: string;
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Source of the Exec sandbox worker.
3
+ *
4
+ * It is a plain string evaluated with `new Worker(source, { eval: true })` so
5
+ * that no extra dist file is needed and no host bundler (esbuild in
6
+ * `packages/vscode`, the JetBrains/desktop packaging steps) has to know about
7
+ * it.
8
+ *
9
+ * Two properties are load-bearing and were both measured on Node 22:
10
+ *
11
+ * 1. **Isolation is a thread + plain-data boundary, not `node:vm`.** Handing a
12
+ * host function or host object to a `vm` context lets the script reach the
13
+ * HOST realm through `tools.x.constructor(...)` — `codeGeneration` cannot
14
+ * stop that, because the host realm has code generation enabled. So the
15
+ * sandbox receives no host value at all: every bridge is built inside the
16
+ * context and every value crossing back is deep-cloned into the context
17
+ * realm.
18
+ * 2. **Termination is `worker.terminate()`.** `vm`'s `{ timeout }` only bounds
19
+ * synchronous execution: `(async () => { await 0; while (true) {} })()`
20
+ * returns in ~1ms and then spins inside the host event loop forever, which
21
+ * hangs the whole process. `{ timeout }` is still passed as a cheap first
22
+ * line for purely synchronous spins.
23
+ *
24
+ * `codeGeneration: { strings: false, wasm: false }` remains the mechanism that
25
+ * blocks `eval` / `new Function` / dynamic `import` at the engine level.
26
+ */
27
+ /** Helpers compiled *inside* the context, so everything the script can reach belongs to the sandbox realm. */
28
+ const SANDBOX_HELPERS = `
29
+ (function () {
30
+ "use strict";
31
+ function cloneValue(v) {
32
+ if (v === null || typeof v !== "object") return v;
33
+ if (Array.isArray(v)) {
34
+ const out = [];
35
+ for (let i = 0; i < v.length; i++) out.push(cloneValue(v[i]));
36
+ return out;
37
+ }
38
+ const obj = { __proto__: null };
39
+ const keys = Object.keys(v);
40
+ for (let i = 0; i < keys.length; i++) {
41
+ const key = keys[i];
42
+ if (key === "__proto__") continue;
43
+ const child = v[key];
44
+ if (typeof child === "function") continue;
45
+ obj[key] = cloneValue(child);
46
+ }
47
+ return obj;
48
+ }
49
+ return {
50
+ build: function (callHost, emit, toolNames, searchName, reservedNamespace) {
51
+ // Everything handed to the script is built here, so every function object
52
+ // the script receives belongs to the context realm: reaching
53
+ // \`tools.x.constructor\` yields the context's Function, which refuses to
54
+ // compile without code generation. Handing out \`callHost\` itself — a
55
+ // worker-realm function whose Function can compile — would be the way out.
56
+ function makeTool(name) {
57
+ return function () {
58
+ const arg = arguments.length > 0 ? arguments[0] : {};
59
+ return Promise.resolve(callHost(name, arg)).then(cloneValue);
60
+ };
61
+ }
62
+ const tools = { __proto__: null };
63
+ for (let i = 0; i < toolNames.length; i++) {
64
+ tools[toolNames[i]] = makeTool(toolNames[i]);
65
+ }
66
+ const namespace = { __proto__: null };
67
+ namespace.search = makeTool(searchName);
68
+ tools[reservedNamespace] = Object.freeze(namespace);
69
+
70
+ // A name that is not in the pool must reach the host so it can answer with
71
+ // a pointer to search; otherwise the script would only see a bare
72
+ // "tools.foo is not a function". Restricted to the mcp__ prefix so
73
+ // ordinary property reads stay untouched — in particular "then", which
74
+ // would otherwise make this object look like a thenable.
75
+ const reachable = new Proxy(tools, {
76
+ get: function (target, key) {
77
+ if (
78
+ typeof key === "string" &&
79
+ !(key in target) &&
80
+ key.indexOf("mcp__") === 0
81
+ ) {
82
+ return makeTool(key);
83
+ }
84
+ return target[key];
85
+ },
86
+ });
87
+ Object.freeze(tools);
88
+
89
+ const levels = ["log", "info", "warn", "error", "debug"];
90
+ const consoleObj = {};
91
+ for (let i = 0; i < levels.length; i++) {
92
+ const level = levels[i];
93
+ consoleObj[level] = function () {
94
+ emit(level, Array.prototype.slice.call(arguments));
95
+ };
96
+ }
97
+
98
+ return {
99
+ tools: reachable,
100
+ console: Object.freeze(consoleObj),
101
+ };
102
+ },
103
+ };
104
+ })()
105
+ `;
106
+ /**
107
+ * Surface reduction. These globals have no legitimate use inside a bounded
108
+ * script: they either expose an alternate code-generation path (`ShadowRealm`,
109
+ * `WebAssembly`), schedule host callbacks outside the run's try/catch
110
+ * (`FinalizationRegistry`, `WeakRef`, `queueMicrotask`), or only matter with
111
+ * shared memory (`Atomics`, `SharedArrayBuffer`). Some are engine-optional
112
+ * today, so the loop is defensive.
113
+ */
114
+ const HARDEN_SOURCE = `
115
+ (function () {
116
+ "use strict";
117
+ const removed = [
118
+ "ShadowRealm",
119
+ "WebAssembly",
120
+ "FinalizationRegistry",
121
+ "WeakRef",
122
+ "Atomics",
123
+ "SharedArrayBuffer",
124
+ "queueMicrotask",
125
+ ];
126
+ for (let i = 0; i < removed.length; i++) {
127
+ try {
128
+ delete globalThis[removed[i]];
129
+ } catch (error) {
130
+ /* non-configurable in some engines */
131
+ }
132
+ }
133
+ })()
134
+ `;
135
+ /** The worker body. Receives `run` / `result` messages on the parent port. */
136
+ export const EXEC_WORKER_SOURCE = `
137
+ "use strict";
138
+ const vm = require("node:vm");
139
+ const { parentPort } = require("node:worker_threads");
140
+
141
+ const pending = new Map();
142
+ let callSeq = 0;
143
+ let logs = [];
144
+ let logChars = 0;
145
+ let maxLogChars = 8000;
146
+ let maxResultChars = 100000;
147
+
148
+ function describeError(err) {
149
+ if (err && typeof err === "object") {
150
+ const message = err.message;
151
+ if (typeof message === "string" && message.length > 0) return message;
152
+ try {
153
+ return String(err);
154
+ } catch (stringifyError) {
155
+ return "an unprintable error";
156
+ }
157
+ }
158
+ return String(err);
159
+ }
160
+
161
+ function safeStringify(value) {
162
+ if (value === undefined) return "undefined";
163
+ if (typeof value === "string") return value;
164
+ try {
165
+ const json = JSON.stringify(value, function (key, item) {
166
+ return typeof item === "function" ? undefined : item;
167
+ });
168
+ if (json !== undefined) return json;
169
+ } catch (error) {
170
+ /* circular structure or a hostile toJSON */
171
+ }
172
+ try {
173
+ return String(value);
174
+ } catch (error) {
175
+ return "<unprintable>";
176
+ }
177
+ }
178
+
179
+ function emit(level, args) {
180
+ if (logChars >= maxLogChars) return;
181
+ const parts = [];
182
+ for (let i = 0; i < args.length; i++) parts.push(safeStringify(args[i]));
183
+ const line = (level === "log" ? "" : level + ": ") + parts.join(" ");
184
+ logChars += line.length;
185
+ logs.push(line);
186
+ }
187
+
188
+ /**
189
+ * Bound what the script hands back. The flat MCP path caps its own results
190
+ * (toolResultStorage), so returning an unbounded value here would make the
191
+ * nested call *more* expensive than the call it replaced.
192
+ */
193
+ function boundResult(text) {
194
+ if (text.length <= maxResultChars) return text;
195
+ return (
196
+ text.slice(0, maxResultChars) +
197
+ "\\n... (returned value truncated: " + text.length + " characters total)"
198
+ );
199
+ }
200
+
201
+ function callHost(name, args) {
202
+ return new Promise(function (resolve, reject) {
203
+ let payload;
204
+ try {
205
+ payload = args === undefined || args === null ? {} : JSON.parse(JSON.stringify(args));
206
+ } catch (error) {
207
+ reject(new Error("Exec tool arguments must be JSON-serializable"));
208
+ return;
209
+ }
210
+ if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
211
+ reject(new Error("Exec tool arguments must be a plain object"));
212
+ return;
213
+ }
214
+ const id = ++callSeq;
215
+ pending.set(id, { resolve: resolve, reject: reject });
216
+ parentPort.postMessage({ kind: "call", id: id, name: name, args: payload });
217
+ });
218
+ }
219
+
220
+ function runScript(message) {
221
+ maxLogChars = message.maxLogChars;
222
+ if (typeof message.maxResultChars === "number") {
223
+ maxResultChars = message.maxResultChars;
224
+ }
225
+ const sandbox = { __proto__: null };
226
+ const context = vm.createContext(sandbox, {
227
+ codeGeneration: { strings: false, wasm: false },
228
+ });
229
+
230
+ vm.runInContext(${JSON.stringify(HARDEN_SOURCE)}, context);
231
+ const helpers = vm.runInContext(${JSON.stringify(SANDBOX_HELPERS)}, context);
232
+ const globals = helpers.build(
233
+ callHost,
234
+ emit,
235
+ message.toolNames,
236
+ message.searchName,
237
+ message.reservedNamespace,
238
+ );
239
+ sandbox.tools = globals.tools;
240
+ sandbox.console = globals.console;
241
+
242
+ let scriptResult;
243
+ try {
244
+ scriptResult = vm.runInContext("(async () => {\\n" + message.code + "\\n})()", context, {
245
+ timeout: message.timeoutMs,
246
+ });
247
+ } catch (error) {
248
+ parentPort.postMessage({
249
+ kind: "done",
250
+ ok: false,
251
+ error: describeError(error),
252
+ logs: logs,
253
+ });
254
+ return;
255
+ }
256
+
257
+ Promise.resolve(scriptResult).then(
258
+ function (value) {
259
+ parentPort.postMessage({
260
+ kind: "done",
261
+ ok: true,
262
+ value: boundResult(safeStringify(value)),
263
+ logs: logs,
264
+ });
265
+ },
266
+ function (error) {
267
+ parentPort.postMessage({
268
+ kind: "done",
269
+ ok: false,
270
+ error: describeError(error),
271
+ logs: logs,
272
+ });
273
+ },
274
+ );
275
+ }
276
+
277
+ parentPort.on("message", function (message) {
278
+ if (message.kind === "result") {
279
+ const entry = pending.get(message.id);
280
+ if (!entry) return;
281
+ pending.delete(message.id);
282
+ if (message.ok) entry.resolve(message.value);
283
+ else entry.reject(new Error(message.error));
284
+ return;
285
+ }
286
+ if (message.kind === "run") {
287
+ try {
288
+ runScript(message);
289
+ } catch (error) {
290
+ parentPort.postMessage({
291
+ kind: "done",
292
+ ok: false,
293
+ error: describeError(error),
294
+ logs: logs,
295
+ });
296
+ }
297
+ }
298
+ });
299
+ `;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 宿主面入口 —— 所有"由宿主进程驱动 agent"的消费者(desktop 主进程、VS Code
3
+ * 扩展宿主)**只从这里导入**,不要碰桶入口(`.`)。
4
+ *
5
+ * 宿主只通过 JSON-RPC 跟 `wave --stdio` 子进程讲话,它需要的东西恰好是这一组:
6
+ * - `./stdio`:RPC 客户端封装(StdioAgent / rpcClient / NotificationRouter)
7
+ * - `./constants`:与 CLI 共用的字面量(工具名、逐字文案)
8
+ * - `./types`:协议与消息类型
9
+ *
10
+ * 为什么要有这个入口:桶入口会把整套 agent 运行时(工具、供应商 SDK、OTel…)连成
11
+ * 一张图,而图里有些模块在**求值期**就会抛(可选原生包缺席时,如 `sharp`)。
12
+ * v1.2.5 的桌面端/插件"装出来打不开"就是有人为了复用两条文案从桶入口 import,
13
+ * 把那份图连坐进了主进程与扩展后端(PR #2267 引入,#2281/#2283 修复)。
14
+ *
15
+ * 过去宿主从 `/types`、`/constants`、`/stdio` 三个窄入口分别取用,纪律是"记住别用
16
+ * 桶"——但需求出现时作者常常不知道新值该去哪个窄入口,于是又走回桶。这里把宿主面
17
+ * 收成一个**正向**入口:宿主需要的值都应该出现在这里,取不到就来这里加,而加完会
18
+ * 撞上 `scripts/check-sdk-surface.mjs` 的闭包预算检查(该入口的闭包必须零第三方
19
+ * 依赖、体积在预算内)。旧的三个子路径继续保留给外部消费者,不 breaking。
20
+ */
21
+ export * from "../constants/index.js";
22
+ export * from "../stdio/index.js";
23
+ export * from "../types/index.js";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 宿主面入口 —— 所有"由宿主进程驱动 agent"的消费者(desktop 主进程、VS Code
3
+ * 扩展宿主)**只从这里导入**,不要碰桶入口(`.`)。
4
+ *
5
+ * 宿主只通过 JSON-RPC 跟 `wave --stdio` 子进程讲话,它需要的东西恰好是这一组:
6
+ * - `./stdio`:RPC 客户端封装(StdioAgent / rpcClient / NotificationRouter)
7
+ * - `./constants`:与 CLI 共用的字面量(工具名、逐字文案)
8
+ * - `./types`:协议与消息类型
9
+ *
10
+ * 为什么要有这个入口:桶入口会把整套 agent 运行时(工具、供应商 SDK、OTel…)连成
11
+ * 一张图,而图里有些模块在**求值期**就会抛(可选原生包缺席时,如 `sharp`)。
12
+ * v1.2.5 的桌面端/插件"装出来打不开"就是有人为了复用两条文案从桶入口 import,
13
+ * 把那份图连坐进了主进程与扩展后端(PR #2267 引入,#2281/#2283 修复)。
14
+ *
15
+ * 过去宿主从 `/types`、`/constants`、`/stdio` 三个窄入口分别取用,纪律是"记住别用
16
+ * 桶"——但需求出现时作者常常不知道新值该去哪个窄入口,于是又走回桶。这里把宿主面
17
+ * 收成一个**正向**入口:宿主需要的值都应该出现在这里,取不到就来这里加,而加完会
18
+ * 撞上 `scripts/check-sdk-surface.mjs` 的闭包预算检查(该入口的闭包必须零第三方
19
+ * 依赖、体积在预算内)。旧的三个子路径继续保留给外部消费者,不 breaking。
20
+ */
21
+ export * from "../constants/index.js";
22
+ export * from "../stdio/index.js";
23
+ export * from "../types/index.js";
package/dist/index.d.ts CHANGED
@@ -23,12 +23,17 @@ export * from "./utils/tokenCalculation.js";
23
23
  export * from "./utils/gitUtils.js";
24
24
  export * from "./utils/nameGenerator.js";
25
25
  export * from "./utils/pathEncoder.js";
26
+ export { ensureRuntimeDeps } from "./utils/runtimeDeps.js";
27
+ export type { RuntimeDepsResult } from "./utils/runtimeDeps.js";
26
28
  export * from "./utils/worktreeSession.js";
27
29
  export * from "./utils/worktreeUtils.js";
28
30
  export { loadMergedWaveConfig, loadUserConfigEnv, loadWaveConfigFromFile, } from "./services/configurationService.js";
29
31
  export { getUserConfigPaths, getProjectConfigPaths, } from "./utils/configPaths.js";
32
+ export { readUserPreferenceSettings, readUserPreferenceView, updateUserPreferenceSettings, userSettingsFilePath, contextLengthToMaxInputTokens, maxInputTokensToContextLength, MAX_INPUT_TOKENS_ENV_KEY, } from "./utils/userSettings.js";
33
+ export type { UserPreferenceSettings, UserPreferenceView, } from "./utils/userSettings.js";
30
34
  export * from "./types/index.js";
31
35
  export type { SubagentConfiguration } from "./utils/subagentParser.js";
32
36
  export type { SubagentInstance } from "./managers/subagentManager.js";
37
+ export { PLUGIN_CHANGE_PENDING_MESSAGE, PLUGIN_RELOADED_MESSAGE, } from "./constants/messages.js";
33
38
  export * from "./tools/buildTool.js";
34
39
  export type { ToolPlugin, ToolResult, ToolContext } from "./tools/types.js";
package/dist/index.js CHANGED
@@ -27,10 +27,16 @@ export * from "./utils/tokenCalculation.js";
27
27
  export * from "./utils/gitUtils.js";
28
28
  export * from "./utils/nameGenerator.js";
29
29
  export * from "./utils/pathEncoder.js";
30
+ export { ensureRuntimeDeps } from "./utils/runtimeDeps.js";
30
31
  export * from "./utils/worktreeSession.js";
31
32
  export * from "./utils/worktreeUtils.js";
32
33
  export { loadMergedWaveConfig, loadUserConfigEnv, loadWaveConfigFromFile, } from "./services/configurationService.js";
33
34
  export { getUserConfigPaths, getProjectConfigPaths, } from "./utils/configPaths.js";
35
+ export { readUserPreferenceSettings, readUserPreferenceView, updateUserPreferenceSettings, userSettingsFilePath, contextLengthToMaxInputTokens, maxInputTokensToContextLength, MAX_INPUT_TOKENS_ENV_KEY, } from "./utils/userSettings.js";
34
36
  export * from "./types/index.js";
37
+ // Plugin reload prompts, shared with the hosts that only display them. The
38
+ // reload result types (PluginLoadFailure / PluginReloadResult) come with the
39
+ // ./types/index.js re-export above.
40
+ export { PLUGIN_CHANGE_PENDING_MESSAGE, PLUGIN_RELOADED_MESSAGE, } from "./constants/messages.js";
35
41
  // Export tool building utilities
36
42
  export * from "./tools/buildTool.js";
@@ -15,6 +15,12 @@ export declare class MemoryRuleManager {
15
15
  private workdir;
16
16
  private service;
17
17
  constructor(container: Container, options: MemoryRuleManagerOptions);
18
+ /**
19
+ * Re-point rule discovery at another working directory (in-session session
20
+ * switch). Project rules are resolved relative to the workdir, so the
21
+ * registry is rebuilt from scratch rather than merged.
22
+ */
23
+ setWorkdir(workdir: string): Promise<void>;
18
24
  /**
19
25
  * Scans .wave/rules and ~/.wave/rules for memory rule files.
20
26
  */
@@ -13,6 +13,18 @@ export class MemoryRuleManager {
13
13
  this.workdir = options.workdir;
14
14
  this.service = new MemoryRuleService();
15
15
  }
16
+ /**
17
+ * Re-point rule discovery at another working directory (in-session session
18
+ * switch). Project rules are resolved relative to the workdir, so the
19
+ * registry is rebuilt from scratch rather than merged.
20
+ */
21
+ async setWorkdir(workdir) {
22
+ if (this.workdir === workdir) {
23
+ return;
24
+ }
25
+ this.workdir = workdir;
26
+ await this.discoverRules();
27
+ }
16
28
  /**
17
29
  * Scans .wave/rules and ~/.wave/rules for memory rule files.
18
30
  */
@@ -23,6 +23,12 @@ export interface AIManagerCallbacks {
23
23
  onCompactionReasoningUpdate?: (content: string) => void;
24
24
  onUsageAdded?: (usage: Usage) => void;
25
25
  onCwdChange?: (newCwd: string) => void;
26
+ /**
27
+ * Full plan-file content after a successful `Write`/`Edit` of the plan file
28
+ * (spec: 计划文件更新后刷新计划面板). Inherited from AgentCallbacks via the
29
+ * spread in container setup.
30
+ */
31
+ onPlanFileUpdated?: (content: string) => void;
26
32
  }
27
33
  export interface AIManagerOptions {
28
34
  callbacks?: AIManagerCallbacks;
@@ -72,6 +78,7 @@ export declare class AIManager {
72
78
  private get hookManager();
73
79
  private get reversionManager();
74
80
  private get permissionManager();
81
+ private get mcpManager();
75
82
  private get planManager();
76
83
  private get configurationService();
77
84
  /**
@@ -85,7 +92,7 @@ export declare class AIManager {
85
92
  getGatewayConfig(): GatewayConfig;
86
93
  getModelConfig(): ModelConfig;
87
94
  getMaxInputTokens(): number;
88
- getLanguage(): string | undefined;
95
+ getLanguage(): string;
89
96
  getAutoMemoryEnabled(): boolean;
90
97
  getWorktreeBaseRef(): "fresh" | "head";
91
98
  getWorkdir(): string;
@@ -160,6 +167,21 @@ export declare class AIManager {
160
167
  * match the main conversation's for the prompt cache to be reused.
161
168
  */
162
169
  private buildMainSystemPrompt;
170
+ /**
171
+ * Announce the connected MCP servers' own usage notes in the conversation,
172
+ * once per server. Not part of the system prompt: this content appears when a
173
+ * connection happens, and rewriting the system prompt mid-session would drop
174
+ * the whole cached prefix (see `utils/mcpInstructions.ts`).
175
+ */
176
+ private maybeAnnounceMcpInstructions;
177
+ /**
178
+ * Announce the MCP catalog in the conversation, whenever the pool renders
179
+ * differently from the last announcement. Keeping it out of `Exec`'s description
180
+ * is what makes that declaration a constant: a server connecting would otherwise
181
+ * rewrite `tools[]`, which sits in the cached prefix (see
182
+ * `exec/catalogAnnouncement.ts`).
183
+ */
184
+ private maybeAnnounceExecCatalog;
163
185
  private resolveFilteredTools;
164
186
  /**
165
187
  * Fork-path loop: run a bounded agent loop over a copy of the conversation
@@ -226,6 +248,7 @@ export declare class AIManager {
226
248
  private get subagentManager();
227
249
  private get cronManager();
228
250
  private get skillManager();
251
+ private get liveConfigManager();
229
252
  sendAIMessage(options?: {
230
253
  recursionDepth?: number;
231
254
  model?: string;
@@ -244,6 +267,17 @@ export declare class AIManager {
244
267
  * tool execution, PostToolUse hooks, and error handling.
245
268
  */
246
269
  private executeToolCall;
270
+ /**
271
+ * Plan panel refresh (spec: 计划文件更新后刷新计划面板).
272
+ *
273
+ * When a successful `Write`/`Edit` targets the current plan file, read it and
274
+ * emit the full content so hosts can update an already-open plan panel. The
275
+ * path comparison mirrors the plan-mode allow branch in PermissionManager so
276
+ * "the write that was allowed" and "the write that refreshes the panel" stay
277
+ * the same set. The path is only set while plan mode is active, so post-exit
278
+ * writes can't reach the panels.
279
+ */
280
+ private notifyPlanFileUpdate;
247
281
  /**
248
282
  * Execute PreToolUse hooks before tool execution
249
283
  * Returns true if hooks allow tool execution, false if blocked