mu-agent-bridge 1.0.55 → 1.0.56

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WorkbuddyCdpClient = exports.assistantSelector = exports.editorSelector = void 0;
3
+ exports.WorkbuddyCdpClient = exports.chineseLocaleScript = exports.assistantSelector = exports.editorSelector = void 0;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const attachments_1 = require("../../attachments");
6
6
  function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }
@@ -17,6 +17,16 @@ function interactionChoice(value, options) {
17
17
  }
18
18
  exports.editorSelector = '[data-slate-editor][contenteditable="true"]';
19
19
  exports.assistantSelector = '.cr-agent[data-message-id] [data-assistant-content]';
20
+ exports.chineseLocaleScript = `(() => {
21
+ const key = 'CODEBUDDY_IDE_STORAGE_LANG';
22
+ const legacyKey = 'workbuddy-language';
23
+ const locale = 'zh-CN';
24
+ const changed = localStorage.getItem(key) !== locale || localStorage.getItem(legacyKey) !== locale || /[?&]locale=en-US(?:&|$)/i.test(location.search);
25
+ localStorage.setItem(key, locale);
26
+ localStorage.setItem(legacyKey, locale);
27
+ if (changed) setTimeout(() => location.reload(), 0);
28
+ return changed;
29
+ })()`;
20
30
  class WorkbuddyCdpClient {
21
31
  attachmentInput = true;
22
32
  socket;
@@ -95,6 +105,8 @@ class WorkbuddyCdpClient {
95
105
  this.socket.onmessage = (event) => this.onMessage(String(event.data));
96
106
  try {
97
107
  await new Promise((resolve, reject) => { const socket = this.socket; socket.onopen = () => resolve(); socket.onerror = () => reject(new Error("WorkBuddy CDP WebSocket 连接失败")); });
108
+ if (await this.evaluate(exports.chineseLocaleScript))
109
+ await this.waitFor("!/[?&]locale=en-US(?:&|$)/i.test(location.search)", "WorkBuddy 中文界面切换超时");
98
110
  }
99
111
  catch (error) {
100
112
  this.close();
@@ -15,7 +15,7 @@ const session_history_1 = require("./session-history");
15
15
  const desktop_launch_1 = require("../desktop-launch");
16
16
  const desktop_launch_2 = require("./desktop-launch");
17
17
  exports.workbuddyManifest = {
18
- id: "workbuddy", version: "1.1.17", displayName: "WorkBuddy", type: "agent",
18
+ id: "workbuddy", version: "1.1.18", displayName: "WorkBuddy", type: "agent",
19
19
  entry: "dist/index.js", apiVersion: "1", process: "in-process",
20
20
  capabilities: ["chat", "health"], configSchema: "config.schema.json",
21
21
  };
@@ -265,22 +265,22 @@ class WorkbuddyPlugin {
265
265
  const timeout = request.timeoutMs ?? this.timeoutMs;
266
266
  const expert = extractExpertQuery(request.task);
267
267
  const usesCli = Boolean(this.cliPath && this.transport !== "cdp" && !expert);
268
+ // 内部恢复消息可能没有 sessionId,沿用当前桌面会话,避免恢复任务被会话保护拒绝。
269
+ const sessionId = request.sessionId ?? this.activeSessionId;
268
270
  const hasAttachments = Array.isArray(request.attachments) && request.attachments.length > 0;
269
271
  if (hasAttachments && !this.attachmentInput)
270
272
  throw new Error("WorkBuddy 当前传输不支持附件输入");
271
273
  if (!usesCli && !this.client?.connected())
272
274
  await this.reconnect?.();
273
275
  const pendingInteractionSessionId = this.client?.pendingInteractionSessionId?.();
274
- if (!usesCli && pendingInteractionSessionId && pendingInteractionSessionId !== request.sessionId)
276
+ if (!usesCli && pendingInteractionSessionId && pendingInteractionSessionId !== sessionId)
275
277
  throw new Error("WorkBuddy 正在等待另一个会话的选择");
276
278
  if (usesCli && request.sessionId)
277
279
  throw new Error("CodeBuddy CLI 会话隔离未验证,不能处理带 sessionId 的请求");
278
- if (!usesCli && !request.sessionId && this.activeSessionId)
279
- throw new Error("WorkBuddy 已绑定逻辑会话,请使用相同 sessionId 或先执行 /new");
280
- if (!usesCli && !request.sessionId && !this.desktopSessionValid)
280
+ if (!usesCli && !sessionId && !this.desktopSessionValid)
281
281
  throw new Error("WorkBuddy 桌面任务状态未知,请先创建新会话");
282
282
  if (!usesCli)
283
- await this.ensureSession(request.sessionId);
283
+ await this.ensureSession(sessionId);
284
284
  if (expert) {
285
285
  if (!this.client?.connected())
286
286
  throw new Error(`专家请求需要已连接的 WorkBuddy 桌面端:${expert}`);
@@ -51,6 +51,12 @@ const node_test_1 = __importDefault(require("node:test"));
51
51
  const node_vm_1 = require("node:vm");
52
52
  const workbuddy_1 = require("../src-ts/plugins/workbuddy");
53
53
  const cdp_client_1 = require("../src-ts/plugins/workbuddy/cdp-client");
54
+ (0, node_test_1.default)("WorkBuddy CDP 启动后固定中文语言偏好", () => {
55
+ strict_1.default.match(cdp_client_1.chineseLocaleScript, /CODEBUDDY_IDE_STORAGE_LANG/);
56
+ strict_1.default.match(cdp_client_1.chineseLocaleScript, /workbuddy-language/);
57
+ strict_1.default.match(cdp_client_1.chineseLocaleScript, /zh-CN/);
58
+ strict_1.default.match(cdp_client_1.chineseLocaleScript, /location\.reload/);
59
+ });
54
60
  (0, node_test_1.default)("workbuddy CDP 拒绝连接其他应用的调试页面", async () => {
55
61
  const client = new cdp_client_1.WorkbuddyCdpClient({ fetchImpl: async () => new Response(JSON.stringify([{ type: "page", title: "Other App", webSocketDebuggerUrl: "ws://127.0.0.1:9229/devtools/page/1" }])) });
56
62
  await strict_1.default.rejects(() => client.connect(), /未找到 WorkBuddy 页面 target/);
@@ -203,6 +209,19 @@ const cdp_client_1 = require("../src-ts/plugins/workbuddy/cdp-client");
203
209
  strict_1.default.equal((await plugin.health()).status, "ready");
204
210
  await plugin.deactivate("stop");
205
211
  });
212
+ (0, node_test_1.default)("workbuddy 内部恢复消息无 sessionId 时沿用当前桌面会话", async () => {
213
+ const calls = [];
214
+ const client = {
215
+ connect: async () => undefined, close() { }, connected: () => true,
216
+ direct: async (task) => { calls.push(task); return "恢复成功"; },
217
+ };
218
+ const plugin = new workbuddy_1.WorkbuddyPlugin({ client });
219
+ await plugin.activate({ config: { transport: "cdp" }, logger: { info() { }, warn() { }, error() { } } });
220
+ plugin.activeSessionId = "session-active";
221
+ await strict_1.default.doesNotReject(() => plugin.handle({ task: "继续当前任务" }));
222
+ strict_1.default.deepEqual(calls, ["继续当前任务"]);
223
+ await plugin.deactivate("stop");
224
+ });
206
225
  (0, node_test_1.default)("workbuddy 结构化客户端接收附件并保留附件响应和逻辑会话", async () => {
207
226
  const attachment = { kind: "file", data: new Uint8Array([1, 2]), filename: "输入.txt", contentType: "text/plain" };
208
227
  const output = { kind: "file", data: new Uint8Array([3]), filename: "输出.txt", contentType: "text/plain" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mu-agent-bridge",
3
- "version": "1.0.55",
3
+ "version": "1.0.56",
4
4
  "description": "将 AUN Agent 连接到本地桌面 AI 客户端的插件平台。",
5
5
  "main": "dist/src-ts/cli.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WorkbuddyCdpClient = exports.assistantSelector = exports.editorSelector = void 0;
3
+ exports.WorkbuddyCdpClient = exports.chineseLocaleScript = exports.assistantSelector = exports.editorSelector = void 0;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const attachments_1 = require("../../attachments");
6
6
  function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }
@@ -17,6 +17,16 @@ function interactionChoice(value, options) {
17
17
  }
18
18
  exports.editorSelector = '[data-slate-editor][contenteditable="true"]';
19
19
  exports.assistantSelector = '.cr-agent[data-message-id] [data-assistant-content]';
20
+ exports.chineseLocaleScript = `(() => {
21
+ const key = 'CODEBUDDY_IDE_STORAGE_LANG';
22
+ const legacyKey = 'workbuddy-language';
23
+ const locale = 'zh-CN';
24
+ const changed = localStorage.getItem(key) !== locale || localStorage.getItem(legacyKey) !== locale || /[?&]locale=en-US(?:&|$)/i.test(location.search);
25
+ localStorage.setItem(key, locale);
26
+ localStorage.setItem(legacyKey, locale);
27
+ if (changed) setTimeout(() => location.reload(), 0);
28
+ return changed;
29
+ })()`;
20
30
  class WorkbuddyCdpClient {
21
31
  attachmentInput = true;
22
32
  socket;
@@ -95,6 +105,8 @@ class WorkbuddyCdpClient {
95
105
  this.socket.onmessage = (event) => this.onMessage(String(event.data));
96
106
  try {
97
107
  await new Promise((resolve, reject) => { const socket = this.socket; socket.onopen = () => resolve(); socket.onerror = () => reject(new Error("WorkBuddy CDP WebSocket 连接失败")); });
108
+ if (await this.evaluate(exports.chineseLocaleScript))
109
+ await this.waitFor("!/[?&]locale=en-US(?:&|$)/i.test(location.search)", "WorkBuddy 中文界面切换超时");
98
110
  }
99
111
  catch (error) {
100
112
  this.close();
@@ -15,7 +15,7 @@ const session_history_1 = require("./session-history");
15
15
  const desktop_launch_1 = require("../desktop-launch");
16
16
  const desktop_launch_2 = require("./desktop-launch");
17
17
  exports.workbuddyManifest = {
18
- id: "workbuddy", version: "1.1.17", displayName: "WorkBuddy", type: "agent",
18
+ id: "workbuddy", version: "1.1.18", displayName: "WorkBuddy", type: "agent",
19
19
  entry: "dist/index.js", apiVersion: "1", process: "in-process",
20
20
  capabilities: ["chat", "health"], configSchema: "config.schema.json",
21
21
  };
@@ -265,22 +265,22 @@ class WorkbuddyPlugin {
265
265
  const timeout = request.timeoutMs ?? this.timeoutMs;
266
266
  const expert = extractExpertQuery(request.task);
267
267
  const usesCli = Boolean(this.cliPath && this.transport !== "cdp" && !expert);
268
+ // 内部恢复消息可能没有 sessionId,沿用当前桌面会话,避免恢复任务被会话保护拒绝。
269
+ const sessionId = request.sessionId ?? this.activeSessionId;
268
270
  const hasAttachments = Array.isArray(request.attachments) && request.attachments.length > 0;
269
271
  if (hasAttachments && !this.attachmentInput)
270
272
  throw new Error("WorkBuddy 当前传输不支持附件输入");
271
273
  if (!usesCli && !this.client?.connected())
272
274
  await this.reconnect?.();
273
275
  const pendingInteractionSessionId = this.client?.pendingInteractionSessionId?.();
274
- if (!usesCli && pendingInteractionSessionId && pendingInteractionSessionId !== request.sessionId)
276
+ if (!usesCli && pendingInteractionSessionId && pendingInteractionSessionId !== sessionId)
275
277
  throw new Error("WorkBuddy 正在等待另一个会话的选择");
276
278
  if (usesCli && request.sessionId)
277
279
  throw new Error("CodeBuddy CLI 会话隔离未验证,不能处理带 sessionId 的请求");
278
- if (!usesCli && !request.sessionId && this.activeSessionId)
279
- throw new Error("WorkBuddy 已绑定逻辑会话,请使用相同 sessionId 或先执行 /new");
280
- if (!usesCli && !request.sessionId && !this.desktopSessionValid)
280
+ if (!usesCli && !sessionId && !this.desktopSessionValid)
281
281
  throw new Error("WorkBuddy 桌面任务状态未知,请先创建新会话");
282
282
  if (!usesCli)
283
- await this.ensureSession(request.sessionId);
283
+ await this.ensureSession(sessionId);
284
284
  if (expert) {
285
285
  if (!this.client?.connected())
286
286
  throw new Error(`专家请求需要已连接的 WorkBuddy 桌面端:${expert}`);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-bridge-workbuddy",
3
- "version": "1.1.17",
3
+ "version": "1.1.18",
4
4
  "description": "mu-agent-bridge 的 WorkBuddy 桌面端插件。",
5
5
  "keywords": [
6
6
  "mu-agent-bridge-plugin",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "workbuddy",
3
- "version": "1.1.17",
3
+ "version": "1.1.18",
4
4
  "type": "agent",
5
5
  "displayName": "WorkBuddy",
6
6
  "entry": "dist/src-ts/plugins/workbuddy/index.js",