opencode-copilot-account-switcher 0.14.19 → 0.14.21
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/dist/wechat/bridge.d.ts
CHANGED
|
@@ -7,18 +7,25 @@ type SessionMessages = Array<{
|
|
|
7
7
|
parts: Part[];
|
|
8
8
|
}>;
|
|
9
9
|
type SessionLite = Pick<Session, "id" | "title" | "directory" | "time">;
|
|
10
|
+
type SdkFieldsResult<T> = {
|
|
11
|
+
data: T | undefined;
|
|
12
|
+
error?: unknown;
|
|
13
|
+
request?: unknown;
|
|
14
|
+
response?: unknown;
|
|
15
|
+
};
|
|
16
|
+
type SdkReadResult<T> = T | SdkFieldsResult<T>;
|
|
10
17
|
type WechatBridgeClient = {
|
|
11
18
|
session: {
|
|
12
|
-
list: () => Promise<SessionLite[]
|
|
13
|
-
status: () => Promise<Record<string, SessionStatus | undefined
|
|
14
|
-
todo: (sessionID: string) => Promise<Todo[]
|
|
15
|
-
messages: (sessionID: string) => Promise<SessionMessages
|
|
19
|
+
list: () => Promise<SdkReadResult<SessionLite[]>>;
|
|
20
|
+
status: () => Promise<SdkReadResult<Record<string, SessionStatus | undefined>>>;
|
|
21
|
+
todo: (sessionID: string) => Promise<SdkReadResult<Todo[]>>;
|
|
22
|
+
messages: (sessionID: string) => Promise<SdkReadResult<SessionMessages>>;
|
|
16
23
|
};
|
|
17
24
|
question: {
|
|
18
|
-
list: () => Promise<QuestionRequest[]
|
|
25
|
+
list: () => Promise<SdkReadResult<QuestionRequest[]>>;
|
|
19
26
|
};
|
|
20
27
|
permission: {
|
|
21
|
-
list: () => Promise<PermissionRequest[]
|
|
28
|
+
list: () => Promise<SdkReadResult<PermissionRequest[]>>;
|
|
22
29
|
};
|
|
23
30
|
};
|
|
24
31
|
export type InstanceUnavailableKind = "sessionStatus" | "questionList" | "permissionList";
|
package/dist/wechat/bridge.js
CHANGED
|
@@ -66,6 +66,23 @@ function withTimeout(task, timeoutMs, name) {
|
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
+
function isSdkFieldsResult(value) {
|
|
70
|
+
return typeof value === "object"
|
|
71
|
+
&& value !== null
|
|
72
|
+
&& ("data" in value || "error" in value);
|
|
73
|
+
}
|
|
74
|
+
function unwrapSdkReadResult(value, name) {
|
|
75
|
+
if (!isSdkFieldsResult(value)) {
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
if (value.error != null) {
|
|
79
|
+
throw value.error instanceof Error ? value.error : new Error(`${name} failed`);
|
|
80
|
+
}
|
|
81
|
+
if (value.data === undefined) {
|
|
82
|
+
throw new Error(`${name} returned no data`);
|
|
83
|
+
}
|
|
84
|
+
return value.data;
|
|
85
|
+
}
|
|
69
86
|
export function createWechatBridge(input) {
|
|
70
87
|
const collectStatusSnapshot = async () => {
|
|
71
88
|
const liveReadTimeoutMs = typeof input.liveReadTimeoutMs === "number" && Number.isFinite(input.liveReadTimeoutMs)
|
|
@@ -73,10 +90,10 @@ export function createWechatBridge(input) {
|
|
|
73
90
|
: DEFAULT_LIVE_READ_TIMEOUT_MS;
|
|
74
91
|
const unavailable = new Set();
|
|
75
92
|
const [sessionListResult, statusResult, questionResult, permissionResult] = await Promise.allSettled([
|
|
76
|
-
withTimeout(() => input.client.session.list(), liveReadTimeoutMs, "session.list"),
|
|
77
|
-
withTimeout(() => input.client.session.status(), liveReadTimeoutMs, "session.status"),
|
|
78
|
-
withTimeout(() => input.client.question.list(), liveReadTimeoutMs, "question.list"),
|
|
79
|
-
withTimeout(() => input.client.permission.list(), liveReadTimeoutMs, "permission.list"),
|
|
93
|
+
withTimeout(async () => unwrapSdkReadResult(await input.client.session.list(), "session.list"), liveReadTimeoutMs, "session.list"),
|
|
94
|
+
withTimeout(async () => unwrapSdkReadResult(await input.client.session.status(), "session.status"), liveReadTimeoutMs, "session.status"),
|
|
95
|
+
withTimeout(async () => unwrapSdkReadResult(await input.client.question.list(), "question.list"), liveReadTimeoutMs, "question.list"),
|
|
96
|
+
withTimeout(async () => unwrapSdkReadResult(await input.client.permission.list(), "permission.list"), liveReadTimeoutMs, "permission.list"),
|
|
80
97
|
]);
|
|
81
98
|
const sessions = sessionListResult.status === "fulfilled" ? sessionListResult.value : [];
|
|
82
99
|
const recentSessions = pickRecentSessions(sessions, 3);
|
|
@@ -94,8 +111,8 @@ export function createWechatBridge(input) {
|
|
|
94
111
|
: (unavailable.add("permissionList"), groupPermissionsBySession([]));
|
|
95
112
|
const sessionDigests = await Promise.all(recentSessions.map(async (session) => {
|
|
96
113
|
const [todoResult, messagesResult] = await Promise.allSettled([
|
|
97
|
-
withTimeout(() => input.client.session.todo(session.id), liveReadTimeoutMs, `session.todo:${session.id}`),
|
|
98
|
-
withTimeout(() => input.client.session.messages(session.id), liveReadTimeoutMs, `session.messages:${session.id}`),
|
|
114
|
+
withTimeout(async () => unwrapSdkReadResult(await input.client.session.todo(session.id), `session.todo:${session.id}`), liveReadTimeoutMs, `session.todo:${session.id}`),
|
|
115
|
+
withTimeout(async () => unwrapSdkReadResult(await input.client.session.messages(session.id), `session.messages:${session.id}`), liveReadTimeoutMs, `session.messages:${session.id}`),
|
|
99
116
|
]);
|
|
100
117
|
const sessionUnavailable = [];
|
|
101
118
|
const todos = todoResult.status === "fulfilled" ? todoResult.value : (sessionUnavailable.push("todo"), []);
|
|
@@ -22,6 +22,7 @@ type LaunchOptions = {
|
|
|
22
22
|
pid?: number | undefined;
|
|
23
23
|
unref?: (() => void) | undefined;
|
|
24
24
|
};
|
|
25
|
+
retireBrokerImpl?: (metadata: BrokerMetadata) => Promise<void> | void;
|
|
25
26
|
pingImpl?: (endpoint: string) => Promise<boolean>;
|
|
26
27
|
onLockAcquired?: (lock: LaunchLockContent) => void;
|
|
27
28
|
};
|
|
@@ -154,6 +154,47 @@ async function isBrokerAlive(brokerFilePath, pingImpl, expectedVersion) {
|
|
|
154
154
|
}
|
|
155
155
|
return metadata;
|
|
156
156
|
}
|
|
157
|
+
async function readVersionMismatchedBroker(brokerFilePath, expectedVersion) {
|
|
158
|
+
const metadata = await readBrokerMetadata(brokerFilePath);
|
|
159
|
+
if (!metadata) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
if (!isNonEmptyString(expectedVersion) || metadata.version === expectedVersion) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
return metadata;
|
|
166
|
+
}
|
|
167
|
+
async function defaultRetireBrokerImpl(metadata, pingImpl) {
|
|
168
|
+
if (metadata.pid === process.pid) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const reachable = await pingImpl(metadata.endpoint);
|
|
172
|
+
if (!reachable) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (!isProcessAlive(metadata.pid)) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
process.kill(metadata.pid, "SIGTERM");
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const startedAt = Date.now();
|
|
185
|
+
while (Date.now() - startedAt < 5000) {
|
|
186
|
+
if (!isProcessAlive(metadata.pid)) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
await delay(50);
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
process.kill(metadata.pid, "SIGKILL");
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// process already exited
|
|
196
|
+
}
|
|
197
|
+
}
|
|
157
198
|
function defaultSpawnImpl(endpoint, stateRoot) {
|
|
158
199
|
const entry = fileURLToPath(new URL("./broker-entry.js", import.meta.url));
|
|
159
200
|
const child = spawn(resolveBrokerSpawnCommand(), [entry, `--endpoint=${endpoint}`, `--state-root=${stateRoot}`], {
|
|
@@ -174,6 +215,7 @@ export async function connectOrSpawnBroker(options = {}) {
|
|
|
174
215
|
const expectedVersion = options.expectedVersion ?? await readCurrentPackageVersion();
|
|
175
216
|
const pingImpl = options.pingImpl ?? defaultPingImpl;
|
|
176
217
|
const spawnImpl = options.spawnImpl ?? defaultSpawnImpl;
|
|
218
|
+
const retireBrokerImpl = options.retireBrokerImpl ?? ((metadata) => defaultRetireBrokerImpl(metadata, pingImpl));
|
|
177
219
|
const endpointFactory = options.endpointFactory ?? (() => createDefaultBrokerEndpoint({ stateRoot }));
|
|
178
220
|
await mkdir(stateRoot, { recursive: true, mode: 0o700 });
|
|
179
221
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
@@ -192,6 +234,10 @@ export async function connectOrSpawnBroker(options = {}) {
|
|
|
192
234
|
if (secondCheck) {
|
|
193
235
|
return secondCheck;
|
|
194
236
|
}
|
|
237
|
+
const versionMismatchedBroker = await readVersionMismatchedBroker(brokerJsonFile, expectedVersion);
|
|
238
|
+
if (versionMismatchedBroker) {
|
|
239
|
+
await retireBrokerImpl(versionMismatchedBroker);
|
|
240
|
+
}
|
|
195
241
|
const endpoint = endpointFactory();
|
|
196
242
|
const child = spawnImpl(endpoint, stateRoot);
|
|
197
243
|
void child?.unref?.();
|