@unlinearity/cli-wechat-bridge 1.2.0 → 1.2.2
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.
- package/README.md +25 -10
- package/bin/wechat-check-update.mjs +0 -0
- package/bin/wechat-claude.mjs +0 -0
- package/bin/wechat-codex.mjs +0 -0
- package/bin/wechat-daemon.mjs +0 -0
- package/bin/wechat-opencode.mjs +0 -0
- package/bin/wechat-pi.mjs +0 -0
- package/bin/wechat-setup.mjs +0 -0
- package/bin/wecom-check-update.mjs +0 -0
- package/bin/wecom-claude.mjs +0 -0
- package/bin/wecom-codex.mjs +0 -0
- package/bin/wecom-daemon.mjs +0 -0
- package/bin/wecom-opencode.mjs +0 -0
- package/bin/wecom-pi.mjs +0 -0
- package/bin/wecom-setup.mjs +0 -0
- package/dist/bridge/adapter-control.js +19 -12
- package/dist/bridge/bridge-adapters.claude.js +219 -115
- package/dist/bridge/bridge-adapters.codex.js +295 -90
- package/dist/bridge/bridge-adapters.core.js +84 -7
- package/dist/bridge/bridge-adapters.opencode.js +344 -74
- package/dist/bridge/bridge-adapters.pi.js +23 -18
- package/dist/bridge/bridge-adapters.shared.js +9 -9
- package/dist/bridge/bridge-session-resume.js +13 -6
- package/dist/bridge/bridge-utils.js +94 -144
- package/dist/bridge/claude-hooks.js +60 -3
- package/dist/bridge/claude-native-controls.js +32 -13
- package/dist/bridge/codex-visible-thread-proxy.js +140 -0
- package/dist/bridge/language-control.js +33 -0
- package/dist/bridge/native-terminal-control.js +38 -10
- package/dist/bridge/opencode-v2-compat.js +458 -0
- package/dist/bridge/wechat-bridge.js +57 -42
- package/dist/channels/channel-driver-factory.js +44 -0
- package/dist/channels/local/local-channel-port.js +40 -0
- package/dist/channels/local/local-driver.js +217 -0
- package/dist/channels/wechat/wechat-driver.js +11 -2
- package/dist/channels/wecom/wecom-driver.js +8 -1
- package/dist/companion/local-companion.js +27 -7
- package/dist/companion/opencode-v2-tui-bridge-plugin.js +93 -0
- package/dist/companion/pi-tui-bridge-extension.js +10 -4
- package/dist/core/bridge-control.js +3 -0
- package/dist/core/bridge-defer.js +3 -2
- package/dist/core/bridge-event-forwarder.js +3 -0
- package/dist/core/channel-types.js +5 -1
- package/dist/daemon/wechat-daemon.js +202 -124
- package/dist/i18n/index.js +25 -11
- package/dist/i18n/messages-en.js +244 -1
- package/dist/i18n/messages-zh.js +244 -1
- package/dist/runtime/legacy-adapter-runtime.js +7 -4
- package/dist/wechat/channel-config.js +3 -2
- package/package.json +4 -2
|
@@ -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;
|