codex-to-im 1.0.41 → 1.0.42

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.
@@ -1572,10 +1572,10 @@ var require_segments = __commonJS({
1572
1572
  const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled());
1573
1573
  const nodes = buildNodes(segs);
1574
1574
  const graph = buildGraph(nodes, version);
1575
- const path9 = dijkstra.find_path(graph.map, "start", "end");
1575
+ const path10 = dijkstra.find_path(graph.map, "start", "end");
1576
1576
  const optimizedSegs = [];
1577
- for (let i = 1; i < path9.length - 1; i++) {
1578
- optimizedSegs.push(graph.table[path9[i]].node);
1577
+ for (let i = 1; i < path10.length - 1; i++) {
1578
+ optimizedSegs.push(graph.table[path10[i]].node);
1579
1579
  }
1580
1580
  return exports.fromArray(mergeSegments(optimizedSegs));
1581
1581
  };
@@ -4011,7 +4011,7 @@ var require_utils2 = __commonJS({
4011
4011
  // node_modules/qrcode/lib/renderer/png.js
4012
4012
  var require_png2 = __commonJS({
4013
4013
  "node_modules/qrcode/lib/renderer/png.js"(exports) {
4014
- var fs8 = __require("fs");
4014
+ var fs9 = __require("fs");
4015
4015
  var PNG = require_png().PNG;
4016
4016
  var Utils = require_utils2();
4017
4017
  exports.render = function render(qrData, options) {
@@ -4052,7 +4052,7 @@ var require_png2 = __commonJS({
4052
4052
  });
4053
4053
  png.pack();
4054
4054
  };
4055
- exports.renderToFile = function renderToFile(path9, qrData, options, cb) {
4055
+ exports.renderToFile = function renderToFile(path10, qrData, options, cb) {
4056
4056
  if (typeof cb === "undefined") {
4057
4057
  cb = options;
4058
4058
  options = void 0;
@@ -4063,7 +4063,7 @@ var require_png2 = __commonJS({
4063
4063
  called = true;
4064
4064
  cb.apply(null, args);
4065
4065
  };
4066
- const stream = fs8.createWriteStream(path9);
4066
+ const stream = fs9.createWriteStream(path10);
4067
4067
  stream.on("error", done);
4068
4068
  stream.on("close", done);
4069
4069
  exports.renderToFileStream(stream, qrData, options);
@@ -4125,14 +4125,14 @@ var require_utf8 = __commonJS({
4125
4125
  }
4126
4126
  return output;
4127
4127
  };
4128
- exports.renderToFile = function renderToFile(path9, qrData, options, cb) {
4128
+ exports.renderToFile = function renderToFile(path10, qrData, options, cb) {
4129
4129
  if (typeof cb === "undefined") {
4130
4130
  cb = options;
4131
4131
  options = void 0;
4132
4132
  }
4133
- const fs8 = __require("fs");
4133
+ const fs9 = __require("fs");
4134
4134
  const utf8 = exports.render(qrData, options);
4135
- fs8.writeFile(path9, utf8, cb);
4135
+ fs9.writeFile(path10, utf8, cb);
4136
4136
  };
4137
4137
  }
4138
4138
  });
@@ -4253,7 +4253,7 @@ var require_svg_tag = __commonJS({
4253
4253
  return str;
4254
4254
  }
4255
4255
  function qrToPath(data, size, margin) {
4256
- let path9 = "";
4256
+ let path10 = "";
4257
4257
  let moveBy = 0;
4258
4258
  let newRow = false;
4259
4259
  let lineLength = 0;
@@ -4264,19 +4264,19 @@ var require_svg_tag = __commonJS({
4264
4264
  if (data[i]) {
4265
4265
  lineLength++;
4266
4266
  if (!(i > 0 && col > 0 && data[i - 1])) {
4267
- path9 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
4267
+ path10 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
4268
4268
  moveBy = 0;
4269
4269
  newRow = false;
4270
4270
  }
4271
4271
  if (!(col + 1 < size && data[i + 1])) {
4272
- path9 += svgCmd("h", lineLength);
4272
+ path10 += svgCmd("h", lineLength);
4273
4273
  lineLength = 0;
4274
4274
  }
4275
4275
  } else {
4276
4276
  moveBy++;
4277
4277
  }
4278
4278
  }
4279
- return path9;
4279
+ return path10;
4280
4280
  }
4281
4281
  exports.render = function render(qrData, options, cb) {
4282
4282
  const opts = Utils.getOptions(options);
@@ -4284,10 +4284,10 @@ var require_svg_tag = __commonJS({
4284
4284
  const data = qrData.modules.data;
4285
4285
  const qrcodesize = size + opts.margin * 2;
4286
4286
  const bg = !opts.color.light.a ? "" : "<path " + getColorAttrib(opts.color.light, "fill") + ' d="M0 0h' + qrcodesize + "v" + qrcodesize + 'H0z"/>';
4287
- const path9 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
4287
+ const path10 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
4288
4288
  const viewBox = 'viewBox="0 0 ' + qrcodesize + " " + qrcodesize + '"';
4289
4289
  const width = !opts.width ? "" : 'width="' + opts.width + '" height="' + opts.width + '" ';
4290
- const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path9 + "</svg>\n";
4290
+ const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path10 + "</svg>\n";
4291
4291
  if (typeof cb === "function") {
4292
4292
  cb(null, svgTag);
4293
4293
  }
@@ -4301,15 +4301,15 @@ var require_svg = __commonJS({
4301
4301
  "node_modules/qrcode/lib/renderer/svg.js"(exports) {
4302
4302
  var svgTagRenderer = require_svg_tag();
4303
4303
  exports.render = svgTagRenderer.render;
4304
- exports.renderToFile = function renderToFile(path9, qrData, options, cb) {
4304
+ exports.renderToFile = function renderToFile(path10, qrData, options, cb) {
4305
4305
  if (typeof cb === "undefined") {
4306
4306
  cb = options;
4307
4307
  options = void 0;
4308
4308
  }
4309
- const fs8 = __require("fs");
4309
+ const fs9 = __require("fs");
4310
4310
  const svgTag = exports.render(qrData, options);
4311
4311
  const xmlStr = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + svgTag;
4312
- fs8.writeFile(path9, xmlStr, cb);
4312
+ fs9.writeFile(path10, xmlStr, cb);
4313
4313
  };
4314
4314
  }
4315
4315
  });
@@ -4467,8 +4467,8 @@ var require_server = __commonJS({
4467
4467
  cb
4468
4468
  };
4469
4469
  }
4470
- function getTypeFromFilename(path9) {
4471
- return path9.slice((path9.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
4470
+ function getTypeFromFilename(path10) {
4471
+ return path10.slice((path10.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
4472
4472
  }
4473
4473
  function getRendererFromType(type) {
4474
4474
  switch (type) {
@@ -4532,17 +4532,17 @@ var require_server = __commonJS({
4532
4532
  const renderer = getRendererFromType(params.opts.type);
4533
4533
  return render(renderer.renderToBuffer, text2, params);
4534
4534
  };
4535
- exports.toFile = function toFile(path9, text2, opts, cb) {
4536
- if (typeof path9 !== "string" || !(typeof text2 === "string" || typeof text2 === "object")) {
4535
+ exports.toFile = function toFile(path10, text2, opts, cb) {
4536
+ if (typeof path10 !== "string" || !(typeof text2 === "string" || typeof text2 === "object")) {
4537
4537
  throw new Error("Invalid argument");
4538
4538
  }
4539
4539
  if (arguments.length < 3 && !canPromise()) {
4540
4540
  throw new Error("Too few arguments provided");
4541
4541
  }
4542
4542
  const params = checkParams(text2, opts, cb);
4543
- const type = params.opts.type || getTypeFromFilename(path9);
4543
+ const type = params.opts.type || getTypeFromFilename(path10);
4544
4544
  const renderer = getRendererFromType(type);
4545
- const renderToFile = renderer.renderToFile.bind(null, path9);
4545
+ const renderToFile = renderer.renderToFile.bind(null, path10);
4546
4546
  return render(renderToFile, text2, params);
4547
4547
  };
4548
4548
  exports.toFileStream = function toFileStream(stream, text2, opts) {
@@ -5631,46 +5631,85 @@ function removeBinding(store, bindingId) {
5631
5631
  }
5632
5632
 
5633
5633
  // src/service-manager.ts
5634
- import fs3 from "node:fs";
5634
+ import fs4 from "node:fs";
5635
5635
  import os3 from "node:os";
5636
- import path4 from "node:path";
5636
+ import path5 from "node:path";
5637
5637
  import { spawn } from "node:child_process";
5638
5638
  import { fileURLToPath } from "node:url";
5639
- var moduleDir = path4.dirname(fileURLToPath(import.meta.url));
5640
- var packageRoot = path4.resolve(moduleDir, "..");
5639
+
5640
+ // src/bridge-instance-lock.ts
5641
+ import fs3 from "node:fs";
5642
+ import path4 from "node:path";
5641
5643
  var runtimeDir = path4.join(CTI_HOME, "runtime");
5642
- var logsDir = path4.join(CTI_HOME, "logs");
5643
- var bridgePidFile = path4.join(runtimeDir, "bridge.pid");
5644
- var bridgeStatusFile = path4.join(runtimeDir, "status.json");
5645
- var bridgeStartLockFile = path4.join(runtimeDir, "bridge.start.lock");
5646
- var uiStatusFile = path4.join(runtimeDir, "ui-server.json");
5644
+ var bridgeInstanceLockFile = path4.join(runtimeDir, "bridge.instance.lock");
5645
+ function readJsonFile(filePath, fallback) {
5646
+ try {
5647
+ return JSON.parse(fs3.readFileSync(filePath, "utf-8"));
5648
+ } catch {
5649
+ return fallback;
5650
+ }
5651
+ }
5652
+ function isProcessAlive(pid) {
5653
+ if (!pid) return false;
5654
+ try {
5655
+ process.kill(pid, 0);
5656
+ return true;
5657
+ } catch {
5658
+ return false;
5659
+ }
5660
+ }
5661
+ function readBridgeInstanceLock(filePath = bridgeInstanceLockFile) {
5662
+ const parsed = readJsonFile(filePath, null);
5663
+ const pid = Number(parsed?.pid);
5664
+ const createdAt = typeof parsed?.createdAt === "string" ? parsed.createdAt : "";
5665
+ if (!Number.isFinite(pid) || pid <= 0 || !createdAt) return null;
5666
+ return { pid, createdAt };
5667
+ }
5668
+ function clearStaleBridgeInstanceLock(filePath = bridgeInstanceLockFile, isAlive = isProcessAlive) {
5669
+ const existing = readBridgeInstanceLock(filePath);
5670
+ if (existing && isAlive(existing.pid)) return;
5671
+ try {
5672
+ fs3.unlinkSync(filePath);
5673
+ } catch {
5674
+ }
5675
+ }
5676
+
5677
+ // src/service-manager.ts
5678
+ var moduleDir = path5.dirname(fileURLToPath(import.meta.url));
5679
+ var packageRoot = path5.resolve(moduleDir, "..");
5680
+ var runtimeDir2 = path5.join(CTI_HOME, "runtime");
5681
+ var logsDir = path5.join(CTI_HOME, "logs");
5682
+ var bridgePidFile = path5.join(runtimeDir2, "bridge.pid");
5683
+ var bridgeStatusFile = path5.join(runtimeDir2, "status.json");
5684
+ var bridgeStartLockFile = path5.join(runtimeDir2, "bridge.start.lock");
5685
+ var uiStatusFile = path5.join(runtimeDir2, "ui-server.json");
5647
5686
  var uiPort = 4781;
5648
5687
  var bridgeAutostartTaskName = "CodexToIMBridge";
5649
- var bridgeAutostartLauncherFile = path4.join(runtimeDir, "bridge-autostart.ps1");
5650
- var npmUninstallLogFile = path4.join(runtimeDir, "npm-uninstall.log");
5688
+ var bridgeAutostartLauncherFile = path5.join(runtimeDir2, "bridge-autostart.ps1");
5689
+ var npmUninstallLogFile = path5.join(runtimeDir2, "npm-uninstall.log");
5651
5690
  var WINDOWS_HIDE = process.platform === "win32" ? { windowsHide: true } : {};
5652
5691
  var BRIDGE_START_LOCK_STALE_MS = 3e4;
5653
5692
  function ensureDirs() {
5654
- fs3.mkdirSync(runtimeDir, { recursive: true });
5655
- fs3.mkdirSync(logsDir, { recursive: true });
5693
+ fs4.mkdirSync(runtimeDir2, { recursive: true });
5694
+ fs4.mkdirSync(logsDir, { recursive: true });
5656
5695
  }
5657
- function readJsonFile(filePath, fallback) {
5696
+ function readJsonFile2(filePath, fallback) {
5658
5697
  try {
5659
- return JSON.parse(fs3.readFileSync(filePath, "utf-8"));
5698
+ return JSON.parse(fs4.readFileSync(filePath, "utf-8"));
5660
5699
  } catch {
5661
5700
  return fallback;
5662
5701
  }
5663
5702
  }
5664
5703
  function readPid(filePath) {
5665
5704
  try {
5666
- const raw = fs3.readFileSync(filePath, "utf-8").trim();
5705
+ const raw = fs4.readFileSync(filePath, "utf-8").trim();
5667
5706
  const pid = Number(raw);
5668
5707
  return Number.isFinite(pid) ? pid : void 0;
5669
5708
  } catch {
5670
5709
  return void 0;
5671
5710
  }
5672
5711
  }
5673
- function isProcessAlive(pid) {
5712
+ function isProcessAlive2(pid) {
5674
5713
  if (!pid) return false;
5675
5714
  try {
5676
5715
  process.kill(pid, 0);
@@ -5679,32 +5718,37 @@ function isProcessAlive(pid) {
5679
5718
  return false;
5680
5719
  }
5681
5720
  }
5682
- function collectTrackedBridgePids(bridgePid, statusPid) {
5721
+ function collectTrackedBridgePids(bridgePid, statusPid, instanceLockPid) {
5683
5722
  const unique = /* @__PURE__ */ new Set();
5684
- for (const pid of [bridgePid, statusPid]) {
5723
+ for (const pid of [bridgePid, statusPid, instanceLockPid]) {
5685
5724
  if (Number.isFinite(pid) && pid > 0) {
5686
5725
  unique.add(pid);
5687
5726
  }
5688
5727
  }
5689
5728
  return [...unique];
5690
5729
  }
5691
- function resolveTrackedBridgePid(bridgePid, statusPid, isAlive = isProcessAlive) {
5730
+ function resolveTrackedBridgePid(bridgePid, statusPid, instanceLockPid, isAlive = isProcessAlive2) {
5692
5731
  if (isAlive(bridgePid)) return bridgePid;
5693
5732
  if (isAlive(statusPid)) return statusPid;
5694
- return bridgePid ?? statusPid;
5733
+ if (isAlive(instanceLockPid)) return instanceLockPid;
5734
+ return bridgePid ?? statusPid ?? instanceLockPid;
5695
5735
  }
5696
5736
  function getTrackedBridgePids(status) {
5697
- const resolvedStatus = status ?? readJsonFile(bridgeStatusFile, { running: false });
5698
- return collectTrackedBridgePids(readPid(bridgePidFile), resolvedStatus.pid);
5737
+ const resolvedStatus = status ?? readJsonFile2(bridgeStatusFile, { running: false });
5738
+ return collectTrackedBridgePids(
5739
+ readPid(bridgePidFile),
5740
+ resolvedStatus.pid,
5741
+ readBridgeInstanceLock()?.pid
5742
+ );
5699
5743
  }
5700
5744
  function clearBridgePidFile() {
5701
5745
  try {
5702
- fs3.unlinkSync(bridgePidFile);
5746
+ fs4.unlinkSync(bridgePidFile);
5703
5747
  } catch {
5704
5748
  }
5705
5749
  }
5706
5750
  function readBridgeStartLock(filePath = bridgeStartLockFile) {
5707
- const parsed = readJsonFile(filePath, null);
5751
+ const parsed = readJsonFile2(filePath, null);
5708
5752
  const pid = Number(parsed?.pid);
5709
5753
  const createdAt = typeof parsed?.createdAt === "string" ? parsed.createdAt : "";
5710
5754
  if (!Number.isFinite(pid) || pid <= 0 || !createdAt) return null;
@@ -5714,7 +5758,7 @@ function isBridgeStartLockStale(lock, options = {}) {
5714
5758
  if (!lock) return true;
5715
5759
  const nowMs = options.nowMs ?? Date.now();
5716
5760
  const staleMs = options.staleMs ?? BRIDGE_START_LOCK_STALE_MS;
5717
- const isAlive = options.isAlive ?? isProcessAlive;
5761
+ const isAlive = options.isAlive ?? isProcessAlive2;
5718
5762
  const createdAtMs = Date.parse(lock.createdAt);
5719
5763
  if (!Number.isFinite(createdAtMs)) return true;
5720
5764
  if (!isAlive(lock.pid)) return true;
@@ -5730,7 +5774,7 @@ function tryAcquireBridgeStartLock(options = {}) {
5730
5774
  };
5731
5775
  for (let attempt = 0; attempt < 2; attempt += 1) {
5732
5776
  try {
5733
- fs3.writeFileSync(filePath, JSON.stringify(payload, null, 2), { encoding: "utf-8", flag: "wx" });
5777
+ fs4.writeFileSync(filePath, JSON.stringify(payload, null, 2), { encoding: "utf-8", flag: "wx" });
5734
5778
  return { acquired: true };
5735
5779
  } catch (error) {
5736
5780
  const code = error.code;
@@ -5744,7 +5788,7 @@ function tryAcquireBridgeStartLock(options = {}) {
5744
5788
  return { acquired: false, holderPid: existing2?.pid };
5745
5789
  }
5746
5790
  try {
5747
- fs3.unlinkSync(filePath);
5791
+ fs4.unlinkSync(filePath);
5748
5792
  } catch {
5749
5793
  }
5750
5794
  }
@@ -5756,14 +5800,14 @@ function releaseBridgeStartLock(filePath = bridgeStartLockFile, ownerPid = proce
5756
5800
  const existing = readBridgeStartLock(filePath);
5757
5801
  if (!existing) {
5758
5802
  try {
5759
- fs3.unlinkSync(filePath);
5803
+ fs4.unlinkSync(filePath);
5760
5804
  } catch {
5761
5805
  }
5762
5806
  return;
5763
5807
  }
5764
5808
  if (existing.pid !== ownerPid) return;
5765
5809
  try {
5766
- fs3.unlinkSync(filePath);
5810
+ fs4.unlinkSync(filePath);
5767
5811
  } catch {
5768
5812
  }
5769
5813
  }
@@ -5820,9 +5864,13 @@ function getUiServerUrl(port2 = uiPort) {
5820
5864
  return `http://127.0.0.1:${port2}`;
5821
5865
  }
5822
5866
  function getBridgeStatus() {
5823
- const status = readJsonFile(bridgeStatusFile, { running: false });
5824
- const pid = resolveTrackedBridgePid(readPid(bridgePidFile), status.pid);
5825
- if (!isProcessAlive(pid)) {
5867
+ const status = readJsonFile2(bridgeStatusFile, { running: false });
5868
+ const pid = resolveTrackedBridgePid(
5869
+ readPid(bridgePidFile),
5870
+ status.pid,
5871
+ readBridgeInstanceLock()?.pid
5872
+ );
5873
+ if (!isProcessAlive2(pid)) {
5826
5874
  return {
5827
5875
  ...status,
5828
5876
  pid,
@@ -5836,8 +5884,8 @@ function getBridgeStatus() {
5836
5884
  };
5837
5885
  }
5838
5886
  function getUiServerStatus() {
5839
- const status = readJsonFile(uiStatusFile, { running: false, port: uiPort });
5840
- if (!isProcessAlive(status.pid)) {
5887
+ const status = readJsonFile2(uiStatusFile, { running: false, port: uiPort });
5888
+ if (!isProcessAlive2(status.pid)) {
5841
5889
  return {
5842
5890
  ...status,
5843
5891
  running: false,
@@ -5907,7 +5955,7 @@ async function waitForBridgeStartupTurn(timeoutMs = 2e4) {
5907
5955
  async function startBridge() {
5908
5956
  ensureDirs();
5909
5957
  const current = getBridgeStatus();
5910
- const extraAlivePids = getTrackedBridgePids(current).filter((pid) => pid !== current.pid && isProcessAlive(pid));
5958
+ const extraAlivePids = getTrackedBridgePids(current).filter((pid) => pid !== current.pid && isProcessAlive2(pid));
5911
5959
  if (current.running && extraAlivePids.length === 0) return current;
5912
5960
  if (current.running && extraAlivePids.length > 0) {
5913
5961
  await stopBridge();
@@ -5932,17 +5980,17 @@ async function startBridge() {
5932
5980
  startLockHeld = true;
5933
5981
  try {
5934
5982
  const currentAfterLock = getBridgeStatus();
5935
- const extraAlivePidsAfterLock = getTrackedBridgePids(currentAfterLock).filter((pid) => pid !== currentAfterLock.pid && isProcessAlive(pid));
5983
+ const extraAlivePidsAfterLock = getTrackedBridgePids(currentAfterLock).filter((pid) => pid !== currentAfterLock.pid && isProcessAlive2(pid));
5936
5984
  if (currentAfterLock.running && extraAlivePidsAfterLock.length === 0) return currentAfterLock;
5937
5985
  if (currentAfterLock.running && extraAlivePidsAfterLock.length > 0) {
5938
5986
  await stopBridge();
5939
5987
  }
5940
- const daemonEntry = path4.join(packageRoot, "dist", "daemon.mjs");
5941
- if (!fs3.existsSync(daemonEntry)) {
5988
+ const daemonEntry = path5.join(packageRoot, "dist", "daemon.mjs");
5989
+ if (!fs4.existsSync(daemonEntry)) {
5942
5990
  throw new Error(`Daemon bundle not found at ${daemonEntry}. Run npm run build first.`);
5943
5991
  }
5944
- const stdoutFd = fs3.openSync(path4.join(logsDir, "bridge-launcher.out.log"), "a");
5945
- const stderrFd = fs3.openSync(path4.join(logsDir, "bridge-launcher.err.log"), "a");
5992
+ const stdoutFd = fs4.openSync(path5.join(logsDir, "bridge-launcher.out.log"), "a");
5993
+ const stderrFd = fs4.openSync(path5.join(logsDir, "bridge-launcher.err.log"), "a");
5946
5994
  const child = spawn(process.execPath, [daemonEntry], {
5947
5995
  cwd: packageRoot,
5948
5996
  detached: true,
@@ -5965,10 +6013,11 @@ async function startBridge() {
5965
6013
  }
5966
6014
  }
5967
6015
  async function stopBridge() {
5968
- const status = readJsonFile(bridgeStatusFile, { running: false });
5969
- const pids = getTrackedBridgePids(status).filter((pid) => isProcessAlive(pid));
6016
+ const status = readJsonFile2(bridgeStatusFile, { running: false });
6017
+ const pids = getTrackedBridgePids(status).filter((pid) => isProcessAlive2(pid));
5970
6018
  if (pids.length === 0) {
5971
6019
  clearBridgePidFile();
6020
+ clearStaleBridgeInstanceLock();
5972
6021
  return { ...getBridgeStatus(), running: false };
5973
6022
  }
5974
6023
  for (const pid of pids) {
@@ -5990,13 +6039,15 @@ async function stopBridge() {
5990
6039
  }
5991
6040
  const startedAt = Date.now();
5992
6041
  while (Date.now() - startedAt < 1e4) {
5993
- if (pids.every((pid) => !isProcessAlive(pid))) {
6042
+ if (pids.every((pid) => !isProcessAlive2(pid))) {
5994
6043
  clearBridgePidFile();
6044
+ clearStaleBridgeInstanceLock();
5995
6045
  return getBridgeStatus();
5996
6046
  }
5997
6047
  await sleep(300);
5998
6048
  }
5999
6049
  clearBridgePidFile();
6050
+ clearStaleBridgeInstanceLock();
6000
6051
  return getBridgeStatus();
6001
6052
  }
6002
6053
  async function restartBridge() {
@@ -6059,37 +6110,37 @@ async function getBridgeAutostartStatus() {
6059
6110
  }
6060
6111
  function getBridgeLogs(lines = 200) {
6061
6112
  ensureDirs();
6062
- const filePath = path4.join(logsDir, "bridge.log");
6063
- if (!fs3.existsSync(filePath)) return "";
6064
- const all = fs3.readFileSync(filePath, "utf-8").split(/\r?\n/);
6113
+ const filePath = path5.join(logsDir, "bridge.log");
6114
+ if (!fs4.existsSync(filePath)) return "";
6115
+ const all = fs4.readFileSync(filePath, "utf-8").split(/\r?\n/);
6065
6116
  return all.slice(Math.max(0, all.length - lines)).join("\n");
6066
6117
  }
6067
6118
  function writeUiServerStatus(status) {
6068
6119
  ensureDirs();
6069
- fs3.writeFileSync(uiStatusFile, JSON.stringify(status, null, 2), "utf-8");
6120
+ fs4.writeFileSync(uiStatusFile, JSON.stringify(status, null, 2), "utf-8");
6070
6121
  }
6071
6122
  async function installCodexIntegration() {
6072
- const sourceSkill = path4.join(packageRoot, "SKILL.md");
6073
- if (!fs3.existsSync(sourceSkill)) {
6123
+ const sourceSkill = path5.join(packageRoot, "SKILL.md");
6124
+ if (!fs4.existsSync(sourceSkill)) {
6074
6125
  throw new Error(`SKILL.md not found at ${sourceSkill}`);
6075
6126
  }
6076
- const skillsDir = path4.join(os3.homedir(), ".codex", "skills");
6077
- const targetDir = path4.join(skillsDir, "codex-to-im");
6078
- fs3.mkdirSync(skillsDir, { recursive: true });
6079
- if (fs3.existsSync(targetDir)) {
6127
+ const skillsDir = path5.join(os3.homedir(), ".codex", "skills");
6128
+ const targetDir = path5.join(skillsDir, "codex-to-im");
6129
+ fs4.mkdirSync(skillsDir, { recursive: true });
6130
+ if (fs4.existsSync(targetDir)) {
6080
6131
  return { targetDir, method: "existing" };
6081
6132
  }
6082
6133
  try {
6083
- fs3.symlinkSync(packageRoot, targetDir, process.platform === "win32" ? "junction" : "dir");
6134
+ fs4.symlinkSync(packageRoot, targetDir, process.platform === "win32" ? "junction" : "dir");
6084
6135
  return { targetDir, method: "junction" };
6085
6136
  } catch {
6086
- fs3.cpSync(packageRoot, targetDir, {
6137
+ fs4.cpSync(packageRoot, targetDir, {
6087
6138
  recursive: true,
6088
6139
  filter: (source) => {
6089
- const relative = path4.relative(packageRoot, source);
6140
+ const relative = path5.relative(packageRoot, source);
6090
6141
  if (!relative) return true;
6091
- if (relative === ".git" || relative.startsWith(`.git${path4.sep}`)) return false;
6092
- if (relative === "node_modules" || relative.startsWith(`node_modules${path4.sep}`)) return false;
6142
+ if (relative === ".git" || relative.startsWith(`.git${path5.sep}`)) return false;
6143
+ if (relative === "node_modules" || relative.startsWith(`node_modules${path5.sep}`)) return false;
6093
6144
  return true;
6094
6145
  }
6095
6146
  });
@@ -6097,27 +6148,27 @@ async function installCodexIntegration() {
6097
6148
  }
6098
6149
  }
6099
6150
  function isCodexIntegrationInstalled() {
6100
- const targetDir = path4.join(os3.homedir(), ".codex", "skills", "codex-to-im");
6101
- return fs3.existsSync(path4.join(targetDir, "SKILL.md"));
6151
+ const targetDir = path5.join(os3.homedir(), ".codex", "skills", "codex-to-im");
6152
+ return fs4.existsSync(path5.join(targetDir, "SKILL.md"));
6102
6153
  }
6103
6154
 
6104
6155
  // src/store.ts
6105
- import fs4 from "node:fs";
6106
- import path5 from "node:path";
6156
+ import fs5 from "node:fs";
6157
+ import path6 from "node:path";
6107
6158
  import crypto2 from "node:crypto";
6108
- var DATA_DIR = path5.join(CTI_HOME, "data");
6109
- var MESSAGES_DIR = path5.join(DATA_DIR, "messages");
6159
+ var DATA_DIR = path6.join(CTI_HOME, "data");
6160
+ var MESSAGES_DIR = path6.join(DATA_DIR, "messages");
6110
6161
  function ensureDir(dir) {
6111
- fs4.mkdirSync(dir, { recursive: true });
6162
+ fs5.mkdirSync(dir, { recursive: true });
6112
6163
  }
6113
6164
  function atomicWrite(filePath, data) {
6114
6165
  const tmp = filePath + ".tmp";
6115
- fs4.writeFileSync(tmp, data, "utf-8");
6116
- fs4.renameSync(tmp, filePath);
6166
+ fs5.writeFileSync(tmp, data, "utf-8");
6167
+ fs5.renameSync(tmp, filePath);
6117
6168
  }
6118
6169
  function readJson(filePath, fallback) {
6119
6170
  try {
6120
- const raw = fs4.readFileSync(filePath, "utf-8");
6171
+ const raw = fs5.readFileSync(filePath, "utf-8");
6121
6172
  return JSON.parse(raw);
6122
6173
  } catch {
6123
6174
  return fallback;
@@ -6186,38 +6237,38 @@ var JsonFileStore = class {
6186
6237
  this.reloadSessions();
6187
6238
  this.reloadBindings();
6188
6239
  const perms = readJson(
6189
- path5.join(DATA_DIR, "permissions.json"),
6240
+ path6.join(DATA_DIR, "permissions.json"),
6190
6241
  {}
6191
6242
  );
6192
6243
  for (const [id, p] of Object.entries(perms)) {
6193
6244
  this.permissionLinks.set(id, p);
6194
6245
  }
6195
6246
  const offsets = readJson(
6196
- path5.join(DATA_DIR, "offsets.json"),
6247
+ path6.join(DATA_DIR, "offsets.json"),
6197
6248
  {}
6198
6249
  );
6199
6250
  for (const [k, v] of Object.entries(offsets)) {
6200
6251
  this.offsets.set(k, v);
6201
6252
  }
6202
6253
  const dedup = readJson(
6203
- path5.join(DATA_DIR, "dedup.json"),
6254
+ path6.join(DATA_DIR, "dedup.json"),
6204
6255
  {}
6205
6256
  );
6206
6257
  for (const [k, v] of Object.entries(dedup)) {
6207
6258
  this.dedupKeys.set(k, v);
6208
6259
  }
6209
- this.auditLog = readJson(path5.join(DATA_DIR, "audit.json"), []);
6260
+ this.auditLog = readJson(path6.join(DATA_DIR, "audit.json"), []);
6210
6261
  }
6211
6262
  reloadSessions() {
6212
6263
  const sessions = readJson(
6213
- path5.join(DATA_DIR, "sessions.json"),
6264
+ path6.join(DATA_DIR, "sessions.json"),
6214
6265
  {}
6215
6266
  );
6216
6267
  this.sessions = new Map(Object.entries(sessions));
6217
6268
  }
6218
6269
  reloadBindings() {
6219
6270
  const bindings = readJson(
6220
- path5.join(DATA_DIR, "bindings.json"),
6271
+ path6.join(DATA_DIR, "bindings.json"),
6221
6272
  {}
6222
6273
  );
6223
6274
  const normalized = /* @__PURE__ */ new Map();
@@ -6236,47 +6287,47 @@ var JsonFileStore = class {
6236
6287
  }
6237
6288
  persistSessions() {
6238
6289
  writeJson(
6239
- path5.join(DATA_DIR, "sessions.json"),
6290
+ path6.join(DATA_DIR, "sessions.json"),
6240
6291
  Object.fromEntries(this.sessions)
6241
6292
  );
6242
6293
  }
6243
6294
  persistBindings() {
6244
6295
  writeJson(
6245
- path5.join(DATA_DIR, "bindings.json"),
6296
+ path6.join(DATA_DIR, "bindings.json"),
6246
6297
  Object.fromEntries(this.bindings)
6247
6298
  );
6248
6299
  }
6249
6300
  persistPermissions() {
6250
6301
  writeJson(
6251
- path5.join(DATA_DIR, "permissions.json"),
6302
+ path6.join(DATA_DIR, "permissions.json"),
6252
6303
  Object.fromEntries(this.permissionLinks)
6253
6304
  );
6254
6305
  }
6255
6306
  persistOffsets() {
6256
6307
  writeJson(
6257
- path5.join(DATA_DIR, "offsets.json"),
6308
+ path6.join(DATA_DIR, "offsets.json"),
6258
6309
  Object.fromEntries(this.offsets)
6259
6310
  );
6260
6311
  }
6261
6312
  persistDedup() {
6262
6313
  writeJson(
6263
- path5.join(DATA_DIR, "dedup.json"),
6314
+ path6.join(DATA_DIR, "dedup.json"),
6264
6315
  Object.fromEntries(this.dedupKeys)
6265
6316
  );
6266
6317
  }
6267
6318
  persistAudit() {
6268
- writeJson(path5.join(DATA_DIR, "audit.json"), this.auditLog);
6319
+ writeJson(path6.join(DATA_DIR, "audit.json"), this.auditLog);
6269
6320
  }
6270
6321
  persistMessages(sessionId) {
6271
6322
  const msgs = this.messages.get(sessionId) || [];
6272
- writeJson(path5.join(MESSAGES_DIR, `${sessionId}.json`), msgs);
6323
+ writeJson(path6.join(MESSAGES_DIR, `${sessionId}.json`), msgs);
6273
6324
  }
6274
6325
  loadMessages(sessionId) {
6275
6326
  if (this.messages.has(sessionId)) {
6276
6327
  return this.messages.get(sessionId);
6277
6328
  }
6278
6329
  const msgs = readJson(
6279
- path5.join(MESSAGES_DIR, `${sessionId}.json`),
6330
+ path6.join(MESSAGES_DIR, `${sessionId}.json`),
6280
6331
  []
6281
6332
  );
6282
6333
  this.messages.set(sessionId, msgs);
@@ -6444,7 +6495,7 @@ var JsonFileStore = class {
6444
6495
  }
6445
6496
  this.messages.delete(sessionId);
6446
6497
  try {
6447
- fs4.rmSync(path5.join(MESSAGES_DIR, `${sessionId}.json`), { force: true });
6498
+ fs5.rmSync(path6.join(MESSAGES_DIR, `${sessionId}.json`), { force: true });
6448
6499
  } catch {
6449
6500
  }
6450
6501
  this.persistSessions();
@@ -6627,8 +6678,8 @@ var JsonFileStore = class {
6627
6678
 
6628
6679
  // src/weixin-login.ts
6629
6680
  var import_qrcode = __toESM(require_lib(), 1);
6630
- import fs6 from "node:fs";
6631
- import path7 from "node:path";
6681
+ import fs7 from "node:fs";
6682
+ import path8 from "node:path";
6632
6683
  import crypto4 from "node:crypto";
6633
6684
  import { spawn as spawn2 } from "node:child_process";
6634
6685
 
@@ -6682,24 +6733,24 @@ async function pollLoginQrStatus(qrcode, baseUrl) {
6682
6733
  }
6683
6734
 
6684
6735
  // src/weixin-store.ts
6685
- import fs5 from "node:fs";
6686
- import path6 from "node:path";
6687
- var DATA_DIR2 = path6.join(CTI_HOME, "data");
6688
- var ACCOUNTS_PATH = path6.join(DATA_DIR2, "weixin-accounts.json");
6689
- var CONTEXT_TOKENS_PATH = path6.join(DATA_DIR2, "weixin-context-tokens.json");
6736
+ import fs6 from "node:fs";
6737
+ import path7 from "node:path";
6738
+ var DATA_DIR2 = path7.join(CTI_HOME, "data");
6739
+ var ACCOUNTS_PATH = path7.join(DATA_DIR2, "weixin-accounts.json");
6740
+ var CONTEXT_TOKENS_PATH = path7.join(DATA_DIR2, "weixin-context-tokens.json");
6690
6741
  var DEFAULT_BASE_URL2 = "https://ilinkai.weixin.qq.com";
6691
6742
  var DEFAULT_CDN_BASE_URL2 = "https://novac2c.cdn.weixin.qq.com/c2c";
6692
6743
  function ensureDir2(dir) {
6693
- fs5.mkdirSync(dir, { recursive: true });
6744
+ fs6.mkdirSync(dir, { recursive: true });
6694
6745
  }
6695
6746
  function atomicWrite2(filePath, data) {
6696
6747
  const tmpPath = `${filePath}.tmp`;
6697
- fs5.writeFileSync(tmpPath, data, "utf-8");
6698
- fs5.renameSync(tmpPath, filePath);
6748
+ fs6.writeFileSync(tmpPath, data, "utf-8");
6749
+ fs6.renameSync(tmpPath, filePath);
6699
6750
  }
6700
6751
  function readJson2(filePath, fallback) {
6701
6752
  try {
6702
- const raw = fs5.readFileSync(filePath, "utf-8");
6753
+ const raw = fs6.readFileSync(filePath, "utf-8");
6703
6754
  return JSON.parse(raw);
6704
6755
  } catch {
6705
6756
  return fallback;
@@ -6789,11 +6840,11 @@ var MAX_REFRESHES = 3;
6789
6840
  var QR_TTL_MS = 5 * 6e4;
6790
6841
  var POLL_INTERVAL_MS = 3e3;
6791
6842
  var WEB_SESSION_TTL_MS = 15 * 6e4;
6792
- var RUNTIME_DIR = path7.join(CTI_HOME, "runtime");
6793
- var HTML_PATH = path7.join(RUNTIME_DIR, "weixin-login.html");
6843
+ var RUNTIME_DIR = path8.join(CTI_HOME, "runtime");
6844
+ var HTML_PATH = path8.join(RUNTIME_DIR, "weixin-login.html");
6794
6845
  var webLoginSessions = /* @__PURE__ */ new Map();
6795
6846
  function ensureRuntimeDir() {
6796
- fs6.mkdirSync(RUNTIME_DIR, { recursive: true });
6847
+ fs7.mkdirSync(RUNTIME_DIR, { recursive: true });
6797
6848
  }
6798
6849
  function escapeHtml(text2) {
6799
6850
  return text2.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
@@ -7106,7 +7157,7 @@ function buildWeixinLoginPopupHtml(sessionId) {
7106
7157
  async function writeQrHtml(session) {
7107
7158
  ensureRuntimeDir();
7108
7159
  const qrSvg = await buildQrSvg(session.qrImageUrl);
7109
- fs6.writeFileSync(HTML_PATH, buildQrHtml(qrSvg), "utf-8");
7160
+ fs7.writeFileSync(HTML_PATH, buildQrHtml(qrSvg), "utf-8");
7110
7161
  }
7111
7162
  function openQrHtml() {
7112
7163
  try {
@@ -7367,7 +7418,7 @@ async function runWeixinLogin(config = {}) {
7367
7418
  }
7368
7419
  var isMainModule = (() => {
7369
7420
  const entry = process.argv[1];
7370
- return !!entry && path7.resolve(entry) === path7.resolve(new URL(import.meta.url).pathname);
7421
+ return !!entry && path8.resolve(entry) === path8.resolve(new URL(import.meta.url).pathname);
7371
7422
  })();
7372
7423
  if (isMainModule) {
7373
7424
  runWeixinLogin().catch((err) => {
@@ -7377,14 +7428,14 @@ if (isMainModule) {
7377
7428
  }
7378
7429
 
7379
7430
  // src/codex-models.ts
7380
- import fs7 from "node:fs";
7431
+ import fs8 from "node:fs";
7381
7432
  import os4 from "node:os";
7382
- import path8 from "node:path";
7383
- var DEFAULT_CODEX_CONFIG_PATH = path8.join(os4.homedir(), ".codex", "config.toml");
7384
- var DEFAULT_CODEX_MODELS_CACHE_PATH = path8.join(os4.homedir(), ".codex", "models_cache.json");
7433
+ import path9 from "node:path";
7434
+ var DEFAULT_CODEX_CONFIG_PATH = path9.join(os4.homedir(), ".codex", "config.toml");
7435
+ var DEFAULT_CODEX_MODELS_CACHE_PATH = path9.join(os4.homedir(), ".codex", "models_cache.json");
7385
7436
  function readConfiguredCodexModel(configPath = DEFAULT_CODEX_CONFIG_PATH) {
7386
7437
  try {
7387
- const raw = fs7.readFileSync(configPath, "utf-8");
7438
+ const raw = fs8.readFileSync(configPath, "utf-8");
7388
7439
  let inSection = false;
7389
7440
  for (const line of raw.split(/\r?\n/)) {
7390
7441
  const trimmed = line.trim();
@@ -7406,7 +7457,7 @@ function readConfiguredCodexModel(configPath = DEFAULT_CODEX_CONFIG_PATH) {
7406
7457
  }
7407
7458
  function listCachedCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH) {
7408
7459
  try {
7409
- const raw = fs7.readFileSync(cachePath, "utf-8");
7460
+ const raw = fs8.readFileSync(cachePath, "utf-8");
7410
7461
  const parsed = JSON.parse(raw);
7411
7462
  if (!Array.isArray(parsed.models)) return [];
7412
7463
  const seen = /* @__PURE__ */ new Set();