cli-wechat-bridge 1.1.5 → 1.1.7

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 (52) hide show
  1. package/README.md +212 -232
  2. package/bin/_run-entry.mjs +20 -5
  3. package/bin/wecom-check-update.mjs +5 -0
  4. package/bin/wecom-claude.mjs +5 -0
  5. package/bin/wecom-codex.mjs +5 -0
  6. package/bin/wecom-daemon.mjs +5 -0
  7. package/bin/wecom-opencode.mjs +5 -0
  8. package/bin/wecom-pi.mjs +5 -0
  9. package/bin/wecom-setup.mjs +5 -0
  10. package/dist/bridge/bridge-adapters.claude.js +128 -4
  11. package/dist/bridge/bridge-adapters.codex.js +214 -23
  12. package/dist/bridge/bridge-adapters.core.js +2 -1
  13. package/dist/bridge/bridge-adapters.pi.js +1 -1
  14. package/dist/bridge/bridge-adapters.shared.js +2 -1
  15. package/dist/bridge/bridge-final-reply.js +2 -65
  16. package/dist/bridge/bridge-process-reaper.js +35 -2
  17. package/dist/bridge/bridge-state.js +11 -4
  18. package/dist/bridge/bridge-utils.js +4 -96
  19. package/dist/bridge/wechat-bridge.js +476 -206
  20. package/dist/bridge/wechat-forwarding.js +2 -58
  21. package/dist/bridge/wechat-outbound-queue.js +2 -0
  22. package/dist/channels/wechat/bridge-final-reply.js +65 -0
  23. package/dist/channels/wechat/channel-message.js +24 -0
  24. package/dist/channels/wechat/index.js +5 -0
  25. package/dist/channels/wechat/wechat-channel-port.js +67 -0
  26. package/dist/channels/wechat/wechat-forwarding.js +79 -0
  27. package/dist/channels/wechat/wechat-outbound-queue.js +79 -0
  28. package/dist/channels/wecom/bridge-final-reply.js +26 -0
  29. package/dist/channels/wecom/setup-cli.js +6 -0
  30. package/dist/channels/wecom/setup.js +176 -0
  31. package/dist/channels/wecom/wecom-channel-port.js +45 -0
  32. package/dist/channels/wecom/wecom-config.js +66 -0
  33. package/dist/channels/wecom/wecom-media.js +141 -0
  34. package/dist/channels/wecom/wecom-message.js +149 -0
  35. package/dist/channels/wecom/wecom-transport.js +308 -0
  36. package/dist/companion/codex-remote-client.js +2 -1
  37. package/dist/companion/local-companion-start.js +49 -9
  38. package/dist/companion/local-companion.js +2 -1
  39. package/dist/core/bridge-control.js +32 -0
  40. package/dist/core/bridge-event-forwarder.js +50 -0
  41. package/dist/core/bridge-message-router.js +32 -0
  42. package/dist/core/channel-types.js +3 -0
  43. package/dist/core/direct-run.js +17 -0
  44. package/dist/core/inbound-message-claims.js +61 -0
  45. package/dist/core/text-utils.js +63 -0
  46. package/dist/daemon/daemon-link.js +3 -0
  47. package/dist/daemon/wechat-daemon.js +466 -172
  48. package/dist/i18n/messages-en.js +4 -2
  49. package/dist/i18n/messages-zh.js +4 -2
  50. package/dist/utils/doctor.js +30 -10
  51. package/dist/wechat/setup.js +113 -13
  52. package/package.json +117 -107
@@ -1,9 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
- const ANSI_ESCAPE_RE =
5
- // eslint-disable-next-line no-control-regex
6
- /\x1b(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
4
+ import { parseBridgeControlCommand, } from "../core/bridge-control.js";
5
+ import { normalizeOutput, summarizeOutput, truncatePreview, } from "../core/text-utils.js";
6
+ export { buildInstanceId, buildOneTimeCode, formatDuration, normalizeOutput, nowIso, stripAnsi, summarizeOutput, truncatePreview, } from "../core/text-utils.js";
7
7
  // Messages older than bridge start minus this grace window are treated as
8
8
  // pre-start backlog and skipped. The window must absorb realistic clock skew
9
9
  // between the local machine and WeChat server timestamps: with a small value,
@@ -99,29 +99,6 @@ const INLINE_REFERENCE_ONLY_FILE_EXTENSIONS = new Set([
99
99
  const INLINE_MAAS_URL_RE = /https?:\/\/[^\s]*?\/([A-Za-z]:\\.+?(?:\.\s*[A-Za-z0-9]{2,8})+)(?:\?[^\n]*)?/g;
100
100
  const INLINE_WINDOWS_PATH_RE = /(^|[^\w])`?([A-Za-z]:\\(?:[^\\/:*?"<>|\r\n`]+\\)*[^\\/:*?"<>|\r\n`]+?(?:\.\s*[A-Za-z0-9]{2,8})+)`?(?=$|[^\w])/gm;
101
101
  const INLINE_HOME_RELATIVE_PATH_RE = /(^|[^\w])`?((?:~[\\/])?(?:Desktop|Documents|Downloads|Pictures|Videos|Music)[\\/](?:[^\\/:*?"<>|\r\n`]+[\\/])*[^\\/:*?"<>|\r\n`]+?(?:\.\s*[A-Za-z0-9]{2,8})+)`?(?=$|[^\w])/gim;
102
- export function nowIso() {
103
- return new Date().toISOString();
104
- }
105
- export function stripAnsi(text) {
106
- return text.replace(ANSI_ESCAPE_RE, "");
107
- }
108
- export function normalizeOutput(text) {
109
- return stripAnsi(text)
110
- // eslint-disable-next-line no-control-regex
111
- .replace(/\u0000/g, "")
112
- .replace(/\r\n/g, "\n")
113
- .replace(/\r/g, "\n");
114
- }
115
- export function truncatePreview(text, maxLength = 140) {
116
- const normalized = normalizeOutput(text).trim().replace(/\s+/g, " ");
117
- if (!normalized) {
118
- return "(empty)";
119
- }
120
- if (normalized.length <= maxLength) {
121
- return normalized;
122
- }
123
- return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
124
- }
125
102
  export function isThinkingForwardEnabled() {
126
103
  if (process.env.CLI_BRIDGE_THINKING_FORWARD === "1") {
127
104
  return true;
@@ -150,51 +127,8 @@ export function formatThinkingForWechat(text, maxLength = 500) {
150
127
  }
151
128
  return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
152
129
  }
153
- export function buildOneTimeCode(length = 6) {
154
- const alphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
155
- let code = "";
156
- while (code.length < length) {
157
- code += alphabet[Math.floor(Math.random() * alphabet.length)];
158
- }
159
- return code;
160
- }
161
- export function buildInstanceId() {
162
- return `bridge-${Date.now().toString(36)}-${buildOneTimeCode(6).toLowerCase()}`;
163
- }
164
130
  export function parseSystemCommand(text) {
165
- const trimmed = text.trim();
166
- if (!trimmed.startsWith("/")) {
167
- return null;
168
- }
169
- const [rawCommand, ...rest] = trimmed.split(/\s+/);
170
- if (!rawCommand) {
171
- return null;
172
- }
173
- const command = rawCommand.toLowerCase();
174
- const argument = rest.join(" ").trim();
175
- switch (command) {
176
- case "/status":
177
- return { type: "status" };
178
- case "/resume":
179
- return argument ? { type: "resume", target: argument } : { type: "resume" };
180
- case "/new":
181
- case "/new-session":
182
- return { type: "new_session" };
183
- case "/stop":
184
- return { type: "stop" };
185
- case "/reset":
186
- return { type: "reset" };
187
- case "/confirm":
188
- case "/yes":
189
- return { type: "confirm" };
190
- case "/deny":
191
- case "/no":
192
- return { type: "deny" };
193
- case "/answer":
194
- return argument ? { type: "answer", raw: argument } : null;
195
- default:
196
- return null;
197
- }
131
+ return parseBridgeControlCommand(text);
198
132
  }
199
133
  export function parseWechatControlCommand(text, options) {
200
134
  const systemCommand = parseSystemCommand(text);
@@ -474,32 +408,6 @@ export function detectCliApproval(text) {
474
408
  denyInput: matched.denyInput,
475
409
  };
476
410
  }
477
- export function formatDuration(durationMs) {
478
- if (!Number.isFinite(durationMs) || durationMs < 0) {
479
- return "0s";
480
- }
481
- const totalSeconds = Math.floor(durationMs / 1000);
482
- const minutes = Math.floor(totalSeconds / 60);
483
- const seconds = totalSeconds % 60;
484
- if (!minutes) {
485
- return `${seconds}s`;
486
- }
487
- return `${minutes}m ${seconds}s`;
488
- }
489
- export function summarizeOutput(text, maxLength = 280) {
490
- const normalized = normalizeOutput(text)
491
- .split("\n")
492
- .map((line) => line.trim())
493
- .filter(Boolean);
494
- if (!normalized.length) {
495
- return "(no output)";
496
- }
497
- const summary = normalized.slice(-6).join("\n");
498
- if (summary.length <= maxLength) {
499
- return summary;
500
- }
501
- return summary.slice(summary.length - maxLength);
502
- }
503
411
  export function formatStatusReport(bridgeState, adapterState) {
504
412
  const pending = bridgeState.pendingConfirmation;
505
413
  const pendingUserInput = bridgeState.pendingUserInput;