cli-wechat-bridge 1.1.6 → 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.
- package/README.md +163 -198
- package/bin/wecom-check-update.mjs +5 -0
- package/bin/wecom-claude.mjs +5 -0
- package/bin/wecom-codex.mjs +5 -0
- package/bin/wecom-daemon.mjs +5 -0
- package/bin/wecom-opencode.mjs +5 -0
- package/bin/wecom-pi.mjs +5 -0
- package/bin/wecom-setup.mjs +5 -0
- package/dist/bridge/bridge-adapters.claude.js +126 -3
- package/dist/bridge/bridge-process-reaper.js +35 -2
- package/dist/bridge/bridge-state.js +10 -3
- package/dist/bridge/wechat-bridge.js +277 -44
- package/dist/channels/wechat/wechat-outbound-queue.js +10 -3
- package/dist/channels/wecom/bridge-final-reply.js +26 -0
- package/dist/channels/wecom/setup-cli.js +6 -0
- package/dist/channels/wecom/setup.js +176 -0
- package/dist/channels/wecom/wecom-channel-port.js +45 -0
- package/dist/channels/wecom/wecom-config.js +66 -0
- package/dist/channels/wecom/wecom-media.js +141 -0
- package/dist/channels/wecom/wecom-message.js +149 -0
- package/dist/channels/wecom/wecom-transport.js +308 -0
- package/dist/companion/codex-remote-client.js +2 -1
- package/dist/companion/local-companion-start.js +49 -9
- package/dist/companion/local-companion.js +2 -1
- package/dist/core/channel-types.js +3 -1
- package/dist/core/direct-run.js +17 -0
- package/dist/core/inbound-message-claims.js +61 -0
- package/dist/daemon/daemon-link.js +3 -0
- package/dist/daemon/wechat-daemon.js +265 -36
- package/dist/i18n/messages-en.js +2 -0
- package/dist/i18n/messages-zh.js +2 -0
- package/dist/utils/doctor.js +30 -10
- package/dist/wechat/setup.js +113 -13
- package/package.json +20 -10
|
@@ -18,6 +18,8 @@ const CLAUDE_COMPACT_DEDUP_MS = 2_000;
|
|
|
18
18
|
const CLAUDE_BRACKETED_PASTE_START = "\u001b[200~";
|
|
19
19
|
const CLAUDE_BRACKETED_PASTE_END = "\u001b[201~";
|
|
20
20
|
const CLAUDE_REMOTE_ENTER_DELAY_MS = 40;
|
|
21
|
+
const CLAUDE_REMOTE_ENTER_RETRY_DELAYS_MS = [200, 500, 1_000];
|
|
22
|
+
const CLAUDE_INTERACTIVE_READY_TIMEOUT_MS = 10_000;
|
|
21
23
|
const CLAUDE_STARTUP_OUTPUT_BUFFER_LIMIT = 4_000;
|
|
22
24
|
const CLAUDE_SESSION_METADATA_READ_BYTES = 64 * 1024;
|
|
23
25
|
const CLAUDE_MAX_SANITIZED_PROJECT_PATH = 200;
|
|
@@ -337,6 +339,12 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
337
339
|
polledTranscriptSessionId = null;
|
|
338
340
|
pendingResume = null;
|
|
339
341
|
localResumeSessionEndObserved = false;
|
|
342
|
+
interactiveReady = true;
|
|
343
|
+
interactiveReadyTimer = null;
|
|
344
|
+
interactiveReadyWaiters = new Set();
|
|
345
|
+
remoteSubmitRetryTimer = null;
|
|
346
|
+
remoteSubmitRetryIndex = 0;
|
|
347
|
+
remoteSubmitText = null;
|
|
340
348
|
constructor(options) {
|
|
341
349
|
super(options);
|
|
342
350
|
const shouldRestoreInitialSession = options.sessionStartMode !== "new";
|
|
@@ -364,6 +372,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
364
372
|
if (this.pty) {
|
|
365
373
|
return;
|
|
366
374
|
}
|
|
375
|
+
this.beginInteractiveReadinessWait();
|
|
367
376
|
this.startupOutputBuffer = "";
|
|
368
377
|
this.hasAutoConfirmedWorkspaceTrustPrompt = false;
|
|
369
378
|
ensureClaudeWorkspaceTrustAccepted(this.options.cwd);
|
|
@@ -385,11 +394,15 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
385
394
|
this.state.activeRuntimeSessionId = undefined;
|
|
386
395
|
}
|
|
387
396
|
}
|
|
388
|
-
await this.startHookServer();
|
|
389
397
|
try {
|
|
398
|
+
await this.startHookServer();
|
|
390
399
|
await super.start();
|
|
400
|
+
if (!this.interactiveReady) {
|
|
401
|
+
this.setStatus("starting", "Waiting for Claude interactive session...");
|
|
402
|
+
}
|
|
391
403
|
}
|
|
392
404
|
catch (error) {
|
|
405
|
+
this.rejectInteractiveReadiness(error instanceof Error ? error : new Error(String(error)));
|
|
393
406
|
await this.stopHookServer();
|
|
394
407
|
throw error;
|
|
395
408
|
}
|
|
@@ -404,7 +417,18 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
404
417
|
if (this.pendingApproval) {
|
|
405
418
|
throw new Error("A Claude approval request is pending. Reply with /confirm or /deny.");
|
|
406
419
|
}
|
|
420
|
+
await this.waitForInteractiveReadiness();
|
|
421
|
+
if (!this.pty) {
|
|
422
|
+
throw new Error("claude adapter is not running.");
|
|
423
|
+
}
|
|
424
|
+
if (this.getState().status === "busy") {
|
|
425
|
+
throw new Error("claude is still working. Wait for the current reply or use /stop.");
|
|
426
|
+
}
|
|
427
|
+
if (this.pendingApproval) {
|
|
428
|
+
throw new Error("A Claude approval request is pending. Reply with /confirm or /deny.");
|
|
429
|
+
}
|
|
407
430
|
const normalizedText = normalizeOutput(text).trim();
|
|
431
|
+
this.clearRemoteSubmitRetry();
|
|
408
432
|
this.pendingInjectedInputs.push({
|
|
409
433
|
normalizedText,
|
|
410
434
|
createdAtMs: Date.now(),
|
|
@@ -421,6 +445,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
421
445
|
this.writeToPty(this.buildRemoteInputPayload(text));
|
|
422
446
|
await delay(CLAUDE_REMOTE_ENTER_DELAY_MS);
|
|
423
447
|
this.writeToPty("\r");
|
|
448
|
+
this.armRemoteSubmitRetry(normalizedText);
|
|
424
449
|
this.armWechatWorkingNotice();
|
|
425
450
|
}
|
|
426
451
|
async listResumeSessions(limit = 10) {
|
|
@@ -530,6 +555,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
530
555
|
return false;
|
|
531
556
|
}
|
|
532
557
|
this.clearWechatWorkingNotice(true);
|
|
558
|
+
this.clearRemoteSubmitRetry();
|
|
533
559
|
this.pendingCliApprovalHints = null;
|
|
534
560
|
this.flushPendingClaudeHookApprovals();
|
|
535
561
|
if (this.pendingApproval) {
|
|
@@ -566,7 +592,8 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
566
592
|
this.state.lastSessionSwitchAt = undefined;
|
|
567
593
|
this.state.lastSessionSwitchSource = undefined;
|
|
568
594
|
this.state.lastSessionSwitchReason = undefined;
|
|
569
|
-
await
|
|
595
|
+
await this.dispose();
|
|
596
|
+
await this.start();
|
|
570
597
|
}
|
|
571
598
|
async resolveApproval(action) {
|
|
572
599
|
if (!this.pendingApproval) {
|
|
@@ -623,6 +650,8 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
623
650
|
this.rejectPendingResume(new Error("Claude is shutting down during session switching."));
|
|
624
651
|
this.detachLocalTerminal();
|
|
625
652
|
this.clearWechatWorkingNotice(true);
|
|
653
|
+
this.clearRemoteSubmitRetry();
|
|
654
|
+
this.rejectInteractiveReadiness(new Error("Claude is shutting down."));
|
|
626
655
|
this.pendingCliApprovalHints = null;
|
|
627
656
|
this.flushPendingClaudeHookApprovals();
|
|
628
657
|
this.stopTranscriptThinkingWatch();
|
|
@@ -720,8 +749,12 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
720
749
|
handleExit(exitCode) {
|
|
721
750
|
this.detachLocalTerminal();
|
|
722
751
|
this.clearWechatWorkingNotice(true);
|
|
752
|
+
this.clearRemoteSubmitRetry();
|
|
723
753
|
this.pendingCliApprovalHints = null;
|
|
724
754
|
this.rejectPendingResume(new Error("Claude exited before the requested session switch completed."));
|
|
755
|
+
if (!this.recoveringInvalidResume) {
|
|
756
|
+
this.rejectInteractiveReadiness(new Error("Claude exited before its interactive session became ready."));
|
|
757
|
+
}
|
|
725
758
|
void this.stopHookServer();
|
|
726
759
|
if (this.recoveringInvalidResume && !this.shuttingDown) {
|
|
727
760
|
this.clearCompletionTimer();
|
|
@@ -996,6 +1029,91 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
996
1029
|
}
|
|
997
1030
|
return `${CLAUDE_BRACKETED_PASTE_START}${normalizedText}${CLAUDE_BRACKETED_PASTE_END}`;
|
|
998
1031
|
}
|
|
1032
|
+
beginInteractiveReadinessWait() {
|
|
1033
|
+
this.clearInteractiveReadinessTimer();
|
|
1034
|
+
this.interactiveReady = false;
|
|
1035
|
+
this.interactiveReadyTimer = setTimeout(() => {
|
|
1036
|
+
this.interactiveReadyTimer = null;
|
|
1037
|
+
this.markInteractiveReady();
|
|
1038
|
+
}, CLAUDE_INTERACTIVE_READY_TIMEOUT_MS);
|
|
1039
|
+
this.interactiveReadyTimer.unref?.();
|
|
1040
|
+
}
|
|
1041
|
+
waitForInteractiveReadiness() {
|
|
1042
|
+
if (this.interactiveReady) {
|
|
1043
|
+
return Promise.resolve();
|
|
1044
|
+
}
|
|
1045
|
+
return new Promise((resolve, reject) => {
|
|
1046
|
+
this.interactiveReadyWaiters.add({ resolve, reject });
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
markInteractiveReady() {
|
|
1050
|
+
if (this.interactiveReady) {
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
this.interactiveReady = true;
|
|
1054
|
+
this.clearInteractiveReadinessTimer();
|
|
1055
|
+
for (const waiter of this.interactiveReadyWaiters) {
|
|
1056
|
+
waiter.resolve();
|
|
1057
|
+
}
|
|
1058
|
+
this.interactiveReadyWaiters.clear();
|
|
1059
|
+
if (this.state.status === "starting" && !this.hasAcceptedInput) {
|
|
1060
|
+
this.setStatus("idle", "Claude interactive session is ready.");
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
rejectInteractiveReadiness(error) {
|
|
1064
|
+
this.clearInteractiveReadinessTimer();
|
|
1065
|
+
for (const waiter of this.interactiveReadyWaiters) {
|
|
1066
|
+
waiter.reject(error);
|
|
1067
|
+
}
|
|
1068
|
+
this.interactiveReadyWaiters.clear();
|
|
1069
|
+
this.interactiveReady = true;
|
|
1070
|
+
}
|
|
1071
|
+
clearInteractiveReadinessTimer() {
|
|
1072
|
+
if (!this.interactiveReadyTimer) {
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
clearTimeout(this.interactiveReadyTimer);
|
|
1076
|
+
this.interactiveReadyTimer = null;
|
|
1077
|
+
}
|
|
1078
|
+
armRemoteSubmitRetry(normalizedText) {
|
|
1079
|
+
this.clearRemoteSubmitRetry();
|
|
1080
|
+
this.remoteSubmitText = normalizedText;
|
|
1081
|
+
this.remoteSubmitRetryIndex = 0;
|
|
1082
|
+
this.scheduleRemoteSubmitRetry();
|
|
1083
|
+
}
|
|
1084
|
+
scheduleRemoteSubmitRetry() {
|
|
1085
|
+
const delayMs = CLAUDE_REMOTE_ENTER_RETRY_DELAYS_MS[this.remoteSubmitRetryIndex];
|
|
1086
|
+
if (delayMs === undefined || !this.remoteSubmitText) {
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
this.remoteSubmitRetryTimer = setTimeout(() => {
|
|
1090
|
+
this.remoteSubmitRetryTimer = null;
|
|
1091
|
+
if (!this.remoteSubmitText ||
|
|
1092
|
+
!this.pty ||
|
|
1093
|
+
this.state.status !== "busy" ||
|
|
1094
|
+
!this.pendingInjectedInputs.some((input) => input.normalizedText === this.remoteSubmitText)) {
|
|
1095
|
+
this.clearRemoteSubmitRetry();
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
this.writeToPty("\r");
|
|
1099
|
+
this.remoteSubmitRetryIndex += 1;
|
|
1100
|
+
if (this.remoteSubmitRetryIndex >= CLAUDE_REMOTE_ENTER_RETRY_DELAYS_MS.length) {
|
|
1101
|
+
this.clearRemoteSubmitRetry();
|
|
1102
|
+
this.emitClaudeNotice("Claude did not confirm the WeChat message submission. Press Enter in the local Claude terminal to retry.", "warning");
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
this.scheduleRemoteSubmitRetry();
|
|
1106
|
+
}, delayMs);
|
|
1107
|
+
this.remoteSubmitRetryTimer.unref?.();
|
|
1108
|
+
}
|
|
1109
|
+
clearRemoteSubmitRetry() {
|
|
1110
|
+
if (this.remoteSubmitRetryTimer) {
|
|
1111
|
+
clearTimeout(this.remoteSubmitRetryTimer);
|
|
1112
|
+
this.remoteSubmitRetryTimer = null;
|
|
1113
|
+
}
|
|
1114
|
+
this.remoteSubmitRetryIndex = 0;
|
|
1115
|
+
this.remoteSubmitText = null;
|
|
1116
|
+
}
|
|
999
1117
|
// Fallback heuristic for older Claude Code versions that lack PostCompact hooks.
|
|
1000
1118
|
// The structured PostCompact hook event (handled in handleClaudeHookEnvelope) is
|
|
1001
1119
|
// the reliable signal; this regex match serves as a best-effort fallback.
|
|
@@ -1044,6 +1162,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
1044
1162
|
}
|
|
1045
1163
|
this.clearCompletionTimer();
|
|
1046
1164
|
this.clearWechatWorkingNotice(true);
|
|
1165
|
+
this.clearRemoteSubmitRetry();
|
|
1047
1166
|
this.pendingCliApprovalHints = null;
|
|
1048
1167
|
this.flushPendingClaudeHookApprovals();
|
|
1049
1168
|
this.pendingApproval = null;
|
|
@@ -1079,6 +1198,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
1079
1198
|
const completedPreview = this.currentPreview;
|
|
1080
1199
|
this.clearCompletionTimer();
|
|
1081
1200
|
this.clearWechatWorkingNotice(true);
|
|
1201
|
+
this.clearRemoteSubmitRetry();
|
|
1082
1202
|
this.pendingCliApprovalHints = null;
|
|
1083
1203
|
this.flushPendingClaudeHookApprovals();
|
|
1084
1204
|
this.pendingApproval = null;
|
|
@@ -1168,6 +1288,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
1168
1288
|
}
|
|
1169
1289
|
}
|
|
1170
1290
|
handleClaudeSessionStart(payload) {
|
|
1291
|
+
this.markInteractiveReady();
|
|
1171
1292
|
if (!payload.session_id) {
|
|
1172
1293
|
return;
|
|
1173
1294
|
}
|
|
@@ -1290,6 +1411,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
1290
1411
|
}
|
|
1291
1412
|
const injectedIndex = findInjectedClaudePromptIndex(prompt, this.pendingInjectedInputs);
|
|
1292
1413
|
if (injectedIndex >= 0) {
|
|
1414
|
+
this.clearRemoteSubmitRetry();
|
|
1293
1415
|
this.pendingInjectedInputs.splice(injectedIndex, 1);
|
|
1294
1416
|
return;
|
|
1295
1417
|
}
|
|
@@ -1332,7 +1454,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
1332
1454
|
this.state.lastSessionSwitchReason = undefined;
|
|
1333
1455
|
this.emitClaudeNotice(`Saved Claude conversation ${failedResumeConversationId} is no longer available. Starting a fresh Claude session.`, "warning");
|
|
1334
1456
|
try {
|
|
1335
|
-
await
|
|
1457
|
+
await this.reset();
|
|
1336
1458
|
}
|
|
1337
1459
|
catch (error) {
|
|
1338
1460
|
// recoverFromInvalidResume is invoked fire-and-forget (void) and there is
|
|
@@ -1441,6 +1563,7 @@ export class ClaudeCompanionAdapter extends AbstractPtyAdapter {
|
|
|
1441
1563
|
this.currentPreview === "(idle)") {
|
|
1442
1564
|
return;
|
|
1443
1565
|
}
|
|
1566
|
+
this.clearRemoteSubmitRetry();
|
|
1444
1567
|
this.clearWechatWorkingNotice(true);
|
|
1445
1568
|
this.pendingCliApprovalHints = null;
|
|
1446
1569
|
this.lastAutoApprovedPayload = null;
|
|
@@ -113,7 +113,7 @@ function normalizeBridgeProcessRecord(value) {
|
|
|
113
113
|
}
|
|
114
114
|
return record;
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
function parseWindowsProcessProbeRecords(stdout) {
|
|
117
117
|
const trimmed = stdout.trim();
|
|
118
118
|
if (!trimmed) {
|
|
119
119
|
return [];
|
|
@@ -128,7 +128,13 @@ export function parseWindowsBridgeProcessProbeOutput(stdout, currentPid = proces
|
|
|
128
128
|
const values = Array.isArray(parsed) ? parsed : [parsed];
|
|
129
129
|
return values
|
|
130
130
|
.map(normalizeBridgeProcessRecord)
|
|
131
|
-
.filter((record) => Boolean(record))
|
|
131
|
+
.filter((record) => Boolean(record));
|
|
132
|
+
}
|
|
133
|
+
export function parseWindowsProcessRecordProbeOutput(stdout, currentPid = process.pid) {
|
|
134
|
+
return (parseWindowsProcessProbeRecords(stdout).find((record) => record.pid !== currentPid) ?? null);
|
|
135
|
+
}
|
|
136
|
+
export function parseWindowsBridgeProcessProbeOutput(stdout, currentPid = process.pid) {
|
|
137
|
+
return parseWindowsProcessProbeRecords(stdout)
|
|
132
138
|
.filter((record) => record.pid !== currentPid && isWechatBridgeCommandLine(record.commandLine));
|
|
133
139
|
}
|
|
134
140
|
export function parsePosixBridgeProcessProbeOutput(stdout, currentPid = process.pid) {
|
|
@@ -195,10 +201,37 @@ export function listPeerBridgeProcesses(currentPid = process.pid) {
|
|
|
195
201
|
? listWindowsBridgeProcesses(currentPid)
|
|
196
202
|
: listPosixBridgeProcesses(currentPid);
|
|
197
203
|
}
|
|
204
|
+
function getWindowsProcessRecordByPid(pid, currentPid = process.pid) {
|
|
205
|
+
const probe = spawnSync("powershell.exe", [
|
|
206
|
+
"-NoLogo",
|
|
207
|
+
"-NoProfile",
|
|
208
|
+
"-NonInteractive",
|
|
209
|
+
"-ExecutionPolicy",
|
|
210
|
+
"Bypass",
|
|
211
|
+
"-Command",
|
|
212
|
+
[
|
|
213
|
+
"$ErrorActionPreference='Stop';",
|
|
214
|
+
`Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}'`,
|
|
215
|
+
"| Select-Object ProcessId,ParentProcessId,Name,CommandLine",
|
|
216
|
+
"| ConvertTo-Json -Compress",
|
|
217
|
+
].join(" "),
|
|
218
|
+
], {
|
|
219
|
+
encoding: "utf8",
|
|
220
|
+
windowsHide: true,
|
|
221
|
+
timeout: 8_000,
|
|
222
|
+
});
|
|
223
|
+
if (probe.status !== 0 || typeof probe.stdout !== "string") {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
return parseWindowsProcessRecordProbeOutput(probe.stdout, currentPid);
|
|
227
|
+
}
|
|
198
228
|
export function getProcessRecordByPid(pid, currentPid = process.pid) {
|
|
199
229
|
if (!Number.isInteger(pid) || pid <= 0 || pid === currentPid) {
|
|
200
230
|
return null;
|
|
201
231
|
}
|
|
232
|
+
if (process.platform === "win32") {
|
|
233
|
+
return getWindowsProcessRecordByPid(pid, currentPid);
|
|
234
|
+
}
|
|
202
235
|
return listAllProcessesRaw(currentPid).find((record) => record.pid === pid) ?? null;
|
|
203
236
|
}
|
|
204
237
|
export function listWechatDaemonProcesses(params = {}) {
|
|
@@ -79,6 +79,9 @@ export function normalizeBridgeLockPayload(value) {
|
|
|
79
79
|
startedAt: record.startedAt,
|
|
80
80
|
lifecycle: record.lifecycle === "companion_bound" ? "companion_bound" : "persistent",
|
|
81
81
|
legacyLifecycleFallback: hasExplicitLifecycle ? undefined : true,
|
|
82
|
+
...(record.channelId === "wechat" || record.channelId === "wecom"
|
|
83
|
+
? { channelId: record.channelId }
|
|
84
|
+
: {}),
|
|
82
85
|
};
|
|
83
86
|
}
|
|
84
87
|
export function readBridgeLockFile() {
|
|
@@ -148,11 +151,13 @@ function buildLockConflictError(lock) {
|
|
|
148
151
|
* pid is alive but belongs to something else, and "unknown" when the command
|
|
149
152
|
* line could not be resolved (probe failure, restricted permissions).
|
|
150
153
|
*/
|
|
151
|
-
export function classifyLockHolderProcess(pid) {
|
|
152
|
-
|
|
154
|
+
export function classifyLockHolderProcess(pid, dependencies = {}) {
|
|
155
|
+
const isProcessAlive = dependencies.isPidAlive ?? isPidAlive;
|
|
156
|
+
const getProcessRecord = dependencies.getProcessRecordByPid ?? getProcessRecordByPid;
|
|
157
|
+
if (!isProcessAlive(pid)) {
|
|
153
158
|
return "unknown";
|
|
154
159
|
}
|
|
155
|
-
const record =
|
|
160
|
+
const record = getProcessRecord(pid);
|
|
156
161
|
if (!record) {
|
|
157
162
|
return "unknown";
|
|
158
163
|
}
|
|
@@ -200,6 +205,7 @@ export class BridgeStateStore {
|
|
|
200
205
|
cwd: options.cwd,
|
|
201
206
|
startedAt: new Date(this.bridgeStartedAtMs).toISOString(),
|
|
202
207
|
lifecycle: options.lifecycle,
|
|
208
|
+
channelId: options.channelId,
|
|
203
209
|
};
|
|
204
210
|
this.acquireLock();
|
|
205
211
|
const shouldRestoreSessionState = options.sessionStartMode !== "new";
|
|
@@ -231,6 +237,7 @@ export class BridgeStateStore {
|
|
|
231
237
|
resumeConversationId: persistedResumeConversationId,
|
|
232
238
|
transcriptPath: persistedTranscriptPath,
|
|
233
239
|
lastActivityAt: persisted?.lastActivityAt,
|
|
240
|
+
channelId: options.channelId,
|
|
234
241
|
pendingConfirmation: null,
|
|
235
242
|
pendingUserInput: null,
|
|
236
243
|
};
|