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.
- package/dist/cli.mjs +106 -57
- package/dist/daemon.mjs +132 -23
- package/dist/ui-server.mjs +181 -130
- package/package.json +1 -1
package/dist/ui-server.mjs
CHANGED
|
@@ -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
|
|
1575
|
+
const path10 = dijkstra.find_path(graph.map, "start", "end");
|
|
1576
1576
|
const optimizedSegs = [];
|
|
1577
|
-
for (let i = 1; i <
|
|
1578
|
-
optimizedSegs.push(graph.table[
|
|
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
|
|
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(
|
|
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 =
|
|
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(
|
|
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
|
|
4133
|
+
const fs9 = __require("fs");
|
|
4134
4134
|
const utf8 = exports.render(qrData, options);
|
|
4135
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
4272
|
+
path10 += svgCmd("h", lineLength);
|
|
4273
4273
|
lineLength = 0;
|
|
4274
4274
|
}
|
|
4275
4275
|
} else {
|
|
4276
4276
|
moveBy++;
|
|
4277
4277
|
}
|
|
4278
4278
|
}
|
|
4279
|
-
return
|
|
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
|
|
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 +
|
|
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(
|
|
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
|
|
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
|
-
|
|
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(
|
|
4471
|
-
return
|
|
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(
|
|
4536
|
-
if (typeof
|
|
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(
|
|
4543
|
+
const type = params.opts.type || getTypeFromFilename(path10);
|
|
4544
4544
|
const renderer = getRendererFromType(type);
|
|
4545
|
-
const renderToFile = renderer.renderToFile.bind(null,
|
|
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
|
|
5634
|
+
import fs4 from "node:fs";
|
|
5635
5635
|
import os3 from "node:os";
|
|
5636
|
-
import
|
|
5636
|
+
import path5 from "node:path";
|
|
5637
5637
|
import { spawn } from "node:child_process";
|
|
5638
5638
|
import { fileURLToPath } from "node:url";
|
|
5639
|
-
|
|
5640
|
-
|
|
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
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
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 =
|
|
5650
|
-
var npmUninstallLogFile =
|
|
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
|
-
|
|
5655
|
-
|
|
5693
|
+
fs4.mkdirSync(runtimeDir2, { recursive: true });
|
|
5694
|
+
fs4.mkdirSync(logsDir, { recursive: true });
|
|
5656
5695
|
}
|
|
5657
|
-
function
|
|
5696
|
+
function readJsonFile2(filePath, fallback) {
|
|
5658
5697
|
try {
|
|
5659
|
-
return JSON.parse(
|
|
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 =
|
|
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
|
|
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 =
|
|
5730
|
+
function resolveTrackedBridgePid(bridgePid, statusPid, instanceLockPid, isAlive = isProcessAlive2) {
|
|
5692
5731
|
if (isAlive(bridgePid)) return bridgePid;
|
|
5693
5732
|
if (isAlive(statusPid)) return statusPid;
|
|
5694
|
-
|
|
5733
|
+
if (isAlive(instanceLockPid)) return instanceLockPid;
|
|
5734
|
+
return bridgePid ?? statusPid ?? instanceLockPid;
|
|
5695
5735
|
}
|
|
5696
5736
|
function getTrackedBridgePids(status) {
|
|
5697
|
-
const resolvedStatus = status ??
|
|
5698
|
-
return collectTrackedBridgePids(
|
|
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
|
-
|
|
5746
|
+
fs4.unlinkSync(bridgePidFile);
|
|
5703
5747
|
} catch {
|
|
5704
5748
|
}
|
|
5705
5749
|
}
|
|
5706
5750
|
function readBridgeStartLock(filePath = bridgeStartLockFile) {
|
|
5707
|
-
const parsed =
|
|
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 ??
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
5824
|
-
const pid = resolveTrackedBridgePid(
|
|
5825
|
-
|
|
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 =
|
|
5840
|
-
if (!
|
|
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 &&
|
|
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 &&
|
|
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 =
|
|
5941
|
-
if (!
|
|
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 =
|
|
5945
|
-
const stderrFd =
|
|
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 =
|
|
5969
|
-
const pids = getTrackedBridgePids(status).filter((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) => !
|
|
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 =
|
|
6063
|
-
if (!
|
|
6064
|
-
const all =
|
|
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
|
-
|
|
6120
|
+
fs4.writeFileSync(uiStatusFile, JSON.stringify(status, null, 2), "utf-8");
|
|
6070
6121
|
}
|
|
6071
6122
|
async function installCodexIntegration() {
|
|
6072
|
-
const sourceSkill =
|
|
6073
|
-
if (!
|
|
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 =
|
|
6077
|
-
const targetDir =
|
|
6078
|
-
|
|
6079
|
-
if (
|
|
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
|
-
|
|
6134
|
+
fs4.symlinkSync(packageRoot, targetDir, process.platform === "win32" ? "junction" : "dir");
|
|
6084
6135
|
return { targetDir, method: "junction" };
|
|
6085
6136
|
} catch {
|
|
6086
|
-
|
|
6137
|
+
fs4.cpSync(packageRoot, targetDir, {
|
|
6087
6138
|
recursive: true,
|
|
6088
6139
|
filter: (source) => {
|
|
6089
|
-
const relative =
|
|
6140
|
+
const relative = path5.relative(packageRoot, source);
|
|
6090
6141
|
if (!relative) return true;
|
|
6091
|
-
if (relative === ".git" || relative.startsWith(`.git${
|
|
6092
|
-
if (relative === "node_modules" || relative.startsWith(`node_modules${
|
|
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 =
|
|
6101
|
-
return
|
|
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
|
|
6106
|
-
import
|
|
6156
|
+
import fs5 from "node:fs";
|
|
6157
|
+
import path6 from "node:path";
|
|
6107
6158
|
import crypto2 from "node:crypto";
|
|
6108
|
-
var DATA_DIR =
|
|
6109
|
-
var MESSAGES_DIR =
|
|
6159
|
+
var DATA_DIR = path6.join(CTI_HOME, "data");
|
|
6160
|
+
var MESSAGES_DIR = path6.join(DATA_DIR, "messages");
|
|
6110
6161
|
function ensureDir(dir) {
|
|
6111
|
-
|
|
6162
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
6112
6163
|
}
|
|
6113
6164
|
function atomicWrite(filePath, data) {
|
|
6114
6165
|
const tmp = filePath + ".tmp";
|
|
6115
|
-
|
|
6116
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
6260
|
+
this.auditLog = readJson(path6.join(DATA_DIR, "audit.json"), []);
|
|
6210
6261
|
}
|
|
6211
6262
|
reloadSessions() {
|
|
6212
6263
|
const sessions = readJson(
|
|
6213
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6290
|
+
path6.join(DATA_DIR, "sessions.json"),
|
|
6240
6291
|
Object.fromEntries(this.sessions)
|
|
6241
6292
|
);
|
|
6242
6293
|
}
|
|
6243
6294
|
persistBindings() {
|
|
6244
6295
|
writeJson(
|
|
6245
|
-
|
|
6296
|
+
path6.join(DATA_DIR, "bindings.json"),
|
|
6246
6297
|
Object.fromEntries(this.bindings)
|
|
6247
6298
|
);
|
|
6248
6299
|
}
|
|
6249
6300
|
persistPermissions() {
|
|
6250
6301
|
writeJson(
|
|
6251
|
-
|
|
6302
|
+
path6.join(DATA_DIR, "permissions.json"),
|
|
6252
6303
|
Object.fromEntries(this.permissionLinks)
|
|
6253
6304
|
);
|
|
6254
6305
|
}
|
|
6255
6306
|
persistOffsets() {
|
|
6256
6307
|
writeJson(
|
|
6257
|
-
|
|
6308
|
+
path6.join(DATA_DIR, "offsets.json"),
|
|
6258
6309
|
Object.fromEntries(this.offsets)
|
|
6259
6310
|
);
|
|
6260
6311
|
}
|
|
6261
6312
|
persistDedup() {
|
|
6262
6313
|
writeJson(
|
|
6263
|
-
|
|
6314
|
+
path6.join(DATA_DIR, "dedup.json"),
|
|
6264
6315
|
Object.fromEntries(this.dedupKeys)
|
|
6265
6316
|
);
|
|
6266
6317
|
}
|
|
6267
6318
|
persistAudit() {
|
|
6268
|
-
writeJson(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
6631
|
-
import
|
|
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
|
|
6686
|
-
import
|
|
6687
|
-
var DATA_DIR2 =
|
|
6688
|
-
var ACCOUNTS_PATH =
|
|
6689
|
-
var CONTEXT_TOKENS_PATH =
|
|
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
|
-
|
|
6744
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
6694
6745
|
}
|
|
6695
6746
|
function atomicWrite2(filePath, data) {
|
|
6696
6747
|
const tmpPath = `${filePath}.tmp`;
|
|
6697
|
-
|
|
6698
|
-
|
|
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 =
|
|
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 =
|
|
6793
|
-
var HTML_PATH =
|
|
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
|
-
|
|
6847
|
+
fs7.mkdirSync(RUNTIME_DIR, { recursive: true });
|
|
6797
6848
|
}
|
|
6798
6849
|
function escapeHtml(text2) {
|
|
6799
6850
|
return text2.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
@@ -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
|
-
|
|
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 &&
|
|
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
|
|
7431
|
+
import fs8 from "node:fs";
|
|
7381
7432
|
import os4 from "node:os";
|
|
7382
|
-
import
|
|
7383
|
-
var DEFAULT_CODEX_CONFIG_PATH =
|
|
7384
|
-
var DEFAULT_CODEX_MODELS_CACHE_PATH =
|
|
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 =
|
|
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 =
|
|
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();
|