opencode-copilot-account-switcher 0.14.19 → 0.14.20

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.
@@ -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?.();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-copilot-account-switcher",
3
- "version": "0.14.19",
3
+ "version": "0.14.20",
4
4
  "description": "GitHub Copilot account switcher plugin for OpenCode",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",