cli-wechat-bridge 1.2.1 → 1.2.3

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 (54) hide show
  1. package/README.md +146 -73
  2. package/README_EN.md +544 -0
  3. package/bin/telegram-check-update.mjs +10 -0
  4. package/bin/telegram-claude.mjs +10 -0
  5. package/bin/telegram-codex.mjs +10 -0
  6. package/bin/telegram-daemon.mjs +10 -0
  7. package/bin/telegram-opencode.mjs +10 -0
  8. package/bin/telegram-pi.mjs +10 -0
  9. package/bin/telegram-setup.mjs +10 -0
  10. package/dist/bridge/adapter-control.js +19 -12
  11. package/dist/bridge/bridge-adapters.claude.js +219 -115
  12. package/dist/bridge/bridge-adapters.codex.js +532 -99
  13. package/dist/bridge/bridge-adapters.core.js +84 -7
  14. package/dist/bridge/bridge-adapters.opencode.js +202 -55
  15. package/dist/bridge/bridge-adapters.pi.js +23 -18
  16. package/dist/bridge/bridge-adapters.shared.js +9 -9
  17. package/dist/bridge/bridge-session-resume.js +13 -6
  18. package/dist/bridge/bridge-state.js +3 -1
  19. package/dist/bridge/bridge-utils.js +94 -144
  20. package/dist/bridge/claude-hooks.js +60 -3
  21. package/dist/bridge/claude-native-controls.js +19 -12
  22. package/dist/bridge/language-control.js +33 -0
  23. package/dist/bridge/native-terminal-control.js +26 -10
  24. package/dist/bridge/opencode-v2-compat.js +11 -3
  25. package/dist/bridge/wechat-bridge.js +154 -72
  26. package/dist/channels/channel-driver-factory.js +56 -0
  27. package/dist/channels/local/local-channel-port.js +40 -0
  28. package/dist/channels/local/local-driver.js +217 -0
  29. package/dist/channels/telegram/setup-cli.js +12 -0
  30. package/dist/channels/telegram/setup.js +163 -0
  31. package/dist/channels/telegram/telegram-channel-port.js +47 -0
  32. package/dist/channels/telegram/telegram-config.js +66 -0
  33. package/dist/channels/telegram/telegram-driver.js +106 -0
  34. package/dist/channels/telegram/telegram-message.js +41 -0
  35. package/dist/channels/telegram/telegram-transport.js +378 -0
  36. package/dist/channels/wechat/wechat-driver.js +11 -2
  37. package/dist/channels/wecom/wecom-driver.js +8 -1
  38. package/dist/companion/local-companion-start.js +180 -61
  39. package/dist/companion/local-companion.js +27 -7
  40. package/dist/companion/pi-tui-bridge-extension.js +10 -4
  41. package/dist/core/bridge-control.js +3 -0
  42. package/dist/core/bridge-defer.js +3 -2
  43. package/dist/core/bridge-event-forwarder.js +3 -0
  44. package/dist/core/channel-types.js +13 -1
  45. package/dist/daemon/wechat-daemon.js +239 -126
  46. package/dist/i18n/index.js +25 -11
  47. package/dist/i18n/messages-en.js +245 -1
  48. package/dist/i18n/messages-zh.js +245 -1
  49. package/dist/runtime/legacy-adapter-runtime.js +7 -4
  50. package/dist/wechat/channel-config.js +3 -2
  51. package/package.json +17 -5
  52. package/skills/codex-bridge/SKILL.md +35 -0
  53. package/skills/codex-bridge/agents/openai.yaml +4 -0
  54. package/skills/codex-bridge/scripts/install.mjs +28 -0
@@ -7,7 +7,7 @@
7
7
  import net from "node:net";
8
8
  import path from "node:path";
9
9
  import { spawn as spawnPty } from "node-pty";
10
- import { t } from "../i18n/index.js";
10
+ import { getLocale, t } from "../i18n/index.js";
11
11
  import { attachLocalCompanionMessageListener, buildLocalCompanionToken, clearLocalCompanionEndpoint, clearLocalCompanionOccupancy, sendLocalCompanionMessage, updateLocalCompanionOccupancy, writeLocalCompanionEndpoint, } from "../companion/local-companion-link.js";
12
12
  import { detectCliApproval, } from "./bridge-utils.js";
13
13
  import { normalizeOutput, nowIso, truncatePreview } from "../core/text-utils.js";
@@ -56,6 +56,8 @@ export class LocalCompanionProxyAdapter {
56
56
  readyWaiters = new Set();
57
57
  detachMessageListener = null;
58
58
  requestCounter = 0;
59
+ announcedApprovalRequestId;
60
+ announcedUserInputRequestId;
59
61
  endpoint = null;
60
62
  pendingRequests = new Map();
61
63
  shuttingDown = false;
@@ -181,6 +183,14 @@ export class LocalCompanionProxyAdapter {
181
183
  async setPlanMode(enabled) {
182
184
  return await this.sendRequest({ command: "set_plan_mode", enabled });
183
185
  }
186
+ async updateLocale(locale) {
187
+ if (!this.socket)
188
+ return true;
189
+ if (!this.state.supportsLocaleUpdates)
190
+ return false;
191
+ await this.sendRequest({ command: "set_locale", locale });
192
+ return true;
193
+ }
184
194
  async interrupt() {
185
195
  const result = await this.sendRequest({
186
196
  command: "interrupt",
@@ -192,10 +202,17 @@ export class LocalCompanionProxyAdapter {
192
202
  command: "reset",
193
203
  });
194
204
  }
195
- async resolveApproval(action) {
205
+ async resolveApproval(action, requestId) {
206
+ if (!this.state.supportsApprovalRequestIds) {
207
+ throw new Error("Restart the visible CLI to upgrade its companion before approving remotely.");
208
+ }
209
+ const expectedId = requestId ?? this.state.pendingApproval?.requestId;
210
+ if (!expectedId)
211
+ return false;
196
212
  const result = await this.sendRequest({
197
213
  command: "resolve_approval",
198
214
  action,
215
+ requestId: expectedId,
199
216
  });
200
217
  return Boolean(result);
201
218
  }
@@ -203,11 +220,15 @@ export class LocalCompanionProxyAdapter {
203
220
  const ok = await this.resolveApproval(action);
204
221
  return ok ? 1 : 0;
205
222
  }
206
- async submitUserInput(answers) {
223
+ async submitUserInput(answers, requestId) {
224
+ const expectedId = requestId ?? this.state.pendingUserInput?.requestId;
225
+ if (expectedId && !this.state.supportsUserInputRequestIds)
226
+ return false;
207
227
  try {
208
228
  const result = await this.sendRequest({
209
229
  command: "submit_user_input",
210
230
  answers,
231
+ requestId: expectedId,
211
232
  });
212
233
  return result === true;
213
234
  }
@@ -270,6 +291,7 @@ export class LocalCompanionProxyAdapter {
270
291
  return;
271
292
  }
272
293
  authenticated = true;
294
+ this.state.supportsLocaleUpdates = message.supportsLocaleUpdates;
273
295
  this.clearReconnectShutdownTimer();
274
296
  this.expectedCloseReason = null;
275
297
  this.socket = socket;
@@ -283,7 +305,7 @@ export class LocalCompanionProxyAdapter {
283
305
  companionPid: message.companionPid,
284
306
  companionConnectedAt,
285
307
  }, this.endpoint?.instanceId, { adapter: this.options.kind });
286
- sendLocalCompanionMessage(socket, { type: "hello_ack" });
308
+ sendLocalCompanionMessage(socket, { type: "hello_ack", locale: getLocale() });
287
309
  return;
288
310
  }
289
311
  this.handlePanelMessage(message);
@@ -311,9 +333,19 @@ export class LocalCompanionProxyAdapter {
311
333
  this.expectedCloseReason = message.reason;
312
334
  return;
313
335
  case "event":
336
+ if (message.event.type === "user_input_required" && message.event.request.requestId) {
337
+ if (this.announcedUserInputRequestId === message.event.request.requestId)
338
+ return;
339
+ this.announcedUserInputRequestId = message.event.request.requestId;
340
+ }
341
+ if (message.event.type === "approval_required" && message.event.request.requestId) {
342
+ if (this.announcedApprovalRequestId === message.event.request.requestId)
343
+ return;
344
+ this.announcedApprovalRequestId = message.event.request.requestId;
345
+ }
314
346
  this.eventSink(message.event);
315
347
  return;
316
- case "state":
348
+ case "state": {
317
349
  if (this.endpoint) {
318
350
  Object.assign(this.endpoint, buildCompanionHealthPatch(message.state, nowIso()));
319
351
  const nextSessionId = getSharedSessionIdFromAdapterState(message.state);
@@ -333,6 +365,12 @@ export class LocalCompanionProxyAdapter {
333
365
  this.state.lastInputAt = undefined;
334
366
  this.state.lastOutputAt = undefined;
335
367
  this.state.pendingApproval = null;
368
+ this.state.pendingApprovals = undefined;
369
+ this.state.supportsApprovalRequestIds = undefined;
370
+ this.state.supportsUserInputRequestIds = undefined;
371
+ this.state.supportsLocaleUpdates = undefined;
372
+ this.state.pendingUserInput = null;
373
+ this.state.pendingUserInputOrigin = undefined;
336
374
  this.state.sharedSessionId = undefined;
337
375
  this.state.sharedThreadId = undefined;
338
376
  this.state.activeRuntimeSessionId = undefined;
@@ -356,7 +394,27 @@ export class LocalCompanionProxyAdapter {
356
394
  status: this.state.status,
357
395
  timestamp: nowIso(),
358
396
  });
397
+ const question = message.state.pendingUserInput;
398
+ if (question?.requestId && question.requestId !== this.announcedUserInputRequestId) {
399
+ this.announcedUserInputRequestId = question.requestId;
400
+ this.eventSink({ type: "user_input_required", request: question, timestamp: nowIso() });
401
+ }
402
+ else if (!question) {
403
+ this.announcedUserInputRequestId = undefined;
404
+ }
405
+ if (this.state.pendingApprovals !== undefined) {
406
+ this.eventSink({ type: "approval_state_changed", requests: this.state.pendingApprovals, timestamp: nowIso() });
407
+ const head = message.state.pendingApproval;
408
+ if (head?.requestId && head.requestId !== this.announcedApprovalRequestId) {
409
+ this.announcedApprovalRequestId = head.requestId;
410
+ this.eventSink({ type: "approval_required", request: head, timestamp: nowIso() });
411
+ }
412
+ else if (!head) {
413
+ this.announcedApprovalRequestId = undefined;
414
+ }
415
+ }
359
416
  return;
417
+ }
360
418
  case "response": {
361
419
  const pending = this.pendingRequests.get(message.id);
362
420
  if (!pending) {
@@ -392,6 +450,14 @@ export class LocalCompanionProxyAdapter {
392
450
  this.state.lastOutputAt = undefined;
393
451
  this.state.pendingApproval = null;
394
452
  this.state.pendingApprovalOrigin = undefined;
453
+ this.state.pendingApprovals = undefined;
454
+ this.state.supportsApprovalRequestIds = undefined;
455
+ this.announcedApprovalRequestId = undefined;
456
+ this.announcedUserInputRequestId = undefined;
457
+ this.state.supportsUserInputRequestIds = undefined;
458
+ this.state.supportsLocaleUpdates = undefined;
459
+ this.state.pendingUserInput = null;
460
+ this.state.pendingUserInputOrigin = undefined;
395
461
  this.state.activeTurnId = undefined;
396
462
  this.state.activeTurnOrigin = undefined;
397
463
  }
@@ -509,7 +575,7 @@ export class LocalCompanionProxyAdapter {
509
575
  launchMode: this.options.companionLaunchMode,
510
576
  }));
511
577
  }
512
- if (!this.state.pid && payload.command !== "dispose") {
578
+ if (!this.state.pid && payload.command !== "dispose" && payload.command !== "set_locale") {
513
579
  await this.waitForCompanionReady();
514
580
  socket = this.socket;
515
581
  if (!socket) {
@@ -733,7 +799,10 @@ export class AbstractPtyAdapter {
733
799
  await this.dispose();
734
800
  await this.start();
735
801
  }
736
- async resolveApproval(action) {
802
+ async resolveApproval(action, requestId) {
803
+ if (requestId !== undefined && this.pendingApproval?.requestId !== requestId) {
804
+ return false;
805
+ }
737
806
  if (!this.pendingApproval) {
738
807
  return false;
739
808
  }
@@ -743,6 +812,9 @@ export class AbstractPtyAdapter {
743
812
  }
744
813
  this.pendingApproval = null;
745
814
  this.state.pendingApproval = null;
815
+ this.state.pendingApprovals = [];
816
+ this.state.pendingApprovalOrigin = undefined;
817
+ this.emit({ type: "approval_state_changed", requests: [], timestamp: nowIso() });
746
818
  return true;
747
819
  }
748
820
  async resolveAllApprovals(action) {
@@ -754,8 +826,13 @@ export class AbstractPtyAdapter {
754
826
  }
755
827
  async dispose() {
756
828
  this.clearCompletionTimer();
829
+ const hadApproval = Boolean(this.pendingApproval);
757
830
  this.pendingApproval = null;
758
831
  this.state.pendingApproval = null;
832
+ this.state.pendingApprovals = [];
833
+ this.state.pendingApprovalOrigin = undefined;
834
+ if (hadApproval)
835
+ this.emit({ type: "approval_state_changed", requests: [], timestamp: nowIso() });
759
836
  if (!this.pty) {
760
837
  this.state.status = "stopped";
761
838
  return;