@unlinearity/cli-wechat-bridge 1.1.6 → 1.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 (85) hide show
  1. package/LICENSE.txt +661 -661
  2. package/README.md +467 -475
  3. package/bin/_run-entry.mjs +29 -6
  4. package/bin/wechat-check-update.mjs +6 -1
  5. package/bin/wechat-claude.mjs +6 -1
  6. package/bin/wechat-codex.mjs +6 -1
  7. package/bin/wechat-daemon.mjs +6 -1
  8. package/bin/wechat-opencode.mjs +6 -1
  9. package/bin/wechat-pi.mjs +6 -1
  10. package/bin/wechat-setup.mjs +6 -1
  11. package/bin/wecom-check-update.mjs +10 -0
  12. package/bin/wecom-claude.mjs +10 -0
  13. package/bin/wecom-codex.mjs +10 -0
  14. package/bin/wecom-daemon.mjs +10 -0
  15. package/bin/wecom-opencode.mjs +10 -0
  16. package/bin/wecom-pi.mjs +10 -0
  17. package/bin/wecom-setup.mjs +10 -0
  18. package/dist/bridge/adapter-control.js +58 -0
  19. package/dist/bridge/bridge-adapters.claude.js +161 -4
  20. package/dist/bridge/bridge-adapters.codex.js +118 -7
  21. package/dist/bridge/bridge-adapters.core.js +25 -1
  22. package/dist/bridge/bridge-adapters.opencode.js +156 -1
  23. package/dist/bridge/bridge-adapters.pi.js +45 -0
  24. package/dist/bridge/bridge-adapters.shared.js +6 -0
  25. package/dist/bridge/bridge-controller.js +6 -0
  26. package/dist/bridge/bridge-final-reply.js +6 -0
  27. package/dist/bridge/bridge-process-reaper.js +41 -2
  28. package/dist/bridge/bridge-state.js +16 -3
  29. package/dist/bridge/bridge-utils.js +6 -31
  30. package/dist/bridge/claude-hook.js +6 -0
  31. package/dist/bridge/claude-native-controls.js +133 -0
  32. package/dist/bridge/native-terminal-control.js +259 -0
  33. package/dist/bridge/wechat-bridge.js +380 -171
  34. package/dist/bridge/wechat-forwarding.js +6 -0
  35. package/dist/bridge/wechat-outbound-queue.js +6 -0
  36. package/dist/channels/wechat/bridge-final-reply.js +13 -22
  37. package/dist/channels/wechat/index.js +6 -0
  38. package/dist/channels/wechat/wechat-driver.js +191 -0
  39. package/dist/channels/wechat/wechat-forwarding.js +18 -0
  40. package/dist/channels/wechat/wechat-outbound-queue.js +49 -3
  41. package/dist/channels/wecom/bridge-final-reply.js +32 -0
  42. package/dist/channels/wecom/setup-cli.js +12 -0
  43. package/dist/channels/wecom/setup.js +182 -0
  44. package/dist/channels/wecom/wecom-channel-port.js +45 -0
  45. package/dist/channels/wecom/wecom-config.js +72 -0
  46. package/dist/channels/wecom/wecom-driver.js +106 -0
  47. package/dist/channels/wecom/wecom-media.js +147 -0
  48. package/dist/channels/wecom/wecom-message.js +149 -0
  49. package/dist/channels/wecom/wecom-transport.js +314 -0
  50. package/dist/commands/check-update.js +6 -0
  51. package/dist/companion/codex-remote-client.js +30 -3
  52. package/dist/companion/codex-visible-client-link.js +107 -0
  53. package/dist/companion/local-companion-link.js +6 -0
  54. package/dist/companion/local-companion-start.js +62 -11
  55. package/dist/companion/local-companion.js +25 -1
  56. package/dist/companion/opencode-tui-bridge-plugin.js +6 -0
  57. package/dist/companion/pi-tui-bridge-extension.js +62 -3
  58. package/dist/core/bridge-control.js +10 -0
  59. package/dist/core/bridge-defer.js +25 -0
  60. package/dist/core/channel-driver.js +1 -0
  61. package/dist/core/channel-types.js +3 -1
  62. package/dist/core/conversation-routing.js +58 -0
  63. package/dist/core/direct-run.js +23 -0
  64. package/dist/core/inbound-message-claims.js +67 -0
  65. package/dist/core/outbound-target.js +32 -0
  66. package/dist/core/text-utils.js +6 -0
  67. package/dist/core/turn-coordinator.js +85 -0
  68. package/dist/daemon/daemon-link.js +9 -0
  69. package/dist/daemon/emoji-bindings.js +6 -0
  70. package/dist/daemon/wechat-daemon.js +675 -122
  71. package/dist/i18n/index.js +6 -0
  72. package/dist/i18n/messages-en.js +9 -1
  73. package/dist/i18n/messages-zh.js +9 -1
  74. package/dist/runtime/create-runtime-host.js +6 -0
  75. package/dist/runtime/legacy-adapter-runtime.js +15 -0
  76. package/dist/runtime/runtime-types.js +3 -0
  77. package/dist/utils/atomic-file.js +6 -0
  78. package/dist/utils/doctor.js +36 -10
  79. package/dist/utils/version-checker.js +17 -11
  80. package/dist/wechat/channel-config.js +6 -0
  81. package/dist/wechat/setup.js +119 -13
  82. package/dist/wechat/wechat-channel.js +6 -0
  83. package/dist/wechat/wechat-transport.js +169 -58
  84. package/package.json +13 -3
  85. package/scripts/ensure-node-pty-permissions.mjs +73 -73
@@ -0,0 +1,85 @@
1
+ import { clearTurn, resolveConversationTarget, rollbackTurn, tryBeginTurn, } from "./conversation-routing.js";
2
+ /**
3
+ * Owns the active remote turn for one dispatch surface: a standalone bridge
4
+ * or one daemon adapter slot. Wraps the turn ownership state machine (busy
5
+ * rejection, dispatch rollback, conditional completion) so standalone and
6
+ * daemon share identical gating semantics instead of re-implementing them.
7
+ */
8
+ export class TurnCoordinator {
9
+ state;
10
+ restoreLastConversationOnFailure;
11
+ constructor(options = {}) {
12
+ this.state = {
13
+ activeTask: null,
14
+ lastConversation: options.initialLastConversation ?? null,
15
+ };
16
+ this.restoreLastConversationOnFailure = options.restoreLastConversationOnFailure ?? false;
17
+ }
18
+ get activeTask() {
19
+ return this.state.activeTask;
20
+ }
21
+ get hasActiveTask() {
22
+ return this.state.activeTask !== null;
23
+ }
24
+ get activeConversation() {
25
+ return this.state.activeConversation;
26
+ }
27
+ get lastConversation() {
28
+ return this.state.lastConversation;
29
+ }
30
+ beginTurn(task, conversation) {
31
+ return tryBeginTurn(this.state, task, conversation);
32
+ }
33
+ rollback(lease, options = {}) {
34
+ return rollbackTurn(this.state, lease, options);
35
+ }
36
+ complete(expectedTask) {
37
+ return clearTurn(this.state, expectedTask);
38
+ }
39
+ /**
40
+ * Replaces the active task unconditionally. Used when a command path
41
+ * (approval confirmation, resume) takes over a continuing turn rather
42
+ * than dispatching fresh input.
43
+ */
44
+ setActiveTask(task) {
45
+ this.state.activeTask = task;
46
+ }
47
+ /** Binds a conversation as both active and remembered target. */
48
+ bindConversation(conversation) {
49
+ this.state.activeConversation = conversation;
50
+ this.state.lastConversation = conversation;
51
+ }
52
+ /** Records a conversation as the remembered fallback target only. */
53
+ observeConversation(conversation) {
54
+ this.state.lastConversation = conversation;
55
+ }
56
+ resolveTarget(fallback) {
57
+ return resolveConversationTarget({
58
+ active: this.state.activeConversation,
59
+ last: this.state.lastConversation,
60
+ fallback,
61
+ });
62
+ }
63
+ /**
64
+ * Busy-rejecting dispatch transaction: acquire the turn lease, forward the
65
+ * input, and roll the lease back when forwarding throws. A busy input runs
66
+ * `onBusy` (reminder) and returns without touching ownership.
67
+ */
68
+ async dispatch(params) {
69
+ const lease = this.beginTurn(params.task, params.conversation);
70
+ if (!lease) {
71
+ await params.onBusy?.();
72
+ return { status: "busy" };
73
+ }
74
+ try {
75
+ await params.forward();
76
+ }
77
+ catch (error) {
78
+ this.rollback(lease, {
79
+ restoreLastConversation: this.restoreLastConversationOnFailure,
80
+ });
81
+ throw error;
82
+ }
83
+ return { status: "dispatched", task: params.task };
84
+ }
85
+ }
@@ -1,3 +1,9 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // Copyright (c) 2026 UNLINEARITY <unlinearity@gmail.com>
3
+ // Source: https://github.com/UNLINEARITY/CLI-WeChat-Bridge
4
+ // This file is part of CLI-WeChat-Bridge. Modifications and derivative works
5
+ // must be released under AGPL-3.0-or-later with full source code; see
6
+ // LICENSE.txt. Network services built on it must offer source to users.
1
7
  import crypto from "node:crypto";
2
8
  import fs from "node:fs";
3
9
  import net from "node:net";
@@ -23,6 +29,9 @@ function normalizeDaemonEndpoint(value) {
23
29
  token: record.token,
24
30
  cwd: record.cwd,
25
31
  startedAt: record.startedAt,
32
+ ...(record.channelId === "wechat" || record.channelId === "wecom"
33
+ ? { channelId: record.channelId }
34
+ : {}),
26
35
  };
27
36
  }
28
37
  export function buildDaemonToken() {
@@ -1,3 +1,9 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // Copyright (c) 2026 UNLINEARITY <unlinearity@gmail.com>
3
+ // Source: https://github.com/UNLINEARITY/CLI-WeChat-Bridge
4
+ // This file is part of CLI-WeChat-Bridge. Modifications and derivative works
5
+ // must be released under AGPL-3.0-or-later with full source code; see
6
+ // LICENSE.txt. Network services built on it must offer source to users.
1
7
  import fs from "node:fs";
2
8
  import { EMOJI_BINDINGS_FILE } from "../wechat/channel-config.js";
3
9
  import { t } from "../i18n/index.js";