codex-to-im 1.0.41 → 1.0.43
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 +143 -66
- package/dist/daemon.mjs +2949 -8988
- package/dist/ui-server.mjs +292 -191
- package/package.json +2 -4
- package/references/setup-guides.md +34 -156
- package/references/token-validation.md +28 -44
- package/references/troubleshooting.md +10 -11
- package/scripts/build.js +2 -7
- package/scripts/daemon.sh +11 -30
- package/scripts/doctor.sh +35 -280
- package/scripts/supervisor-macos.sh +9 -28
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) {
|
|
@@ -4593,6 +4593,9 @@ function normalizeChannelId(value) {
|
|
|
4593
4593
|
}
|
|
4594
4594
|
|
|
4595
4595
|
// src/config.ts
|
|
4596
|
+
function isSupportedChannelProvider(value) {
|
|
4597
|
+
return value === "feishu" || value === "weixin";
|
|
4598
|
+
}
|
|
4596
4599
|
function toFeishuConfig(channel) {
|
|
4597
4600
|
return channel?.provider === "feishu" ? channel.config : void 0;
|
|
4598
4601
|
}
|
|
@@ -4668,6 +4671,8 @@ function readConfigV2File() {
|
|
|
4668
4671
|
try {
|
|
4669
4672
|
const parsed = JSON.parse(fs.readFileSync(CONFIG_V2_PATH, "utf-8"));
|
|
4670
4673
|
if (parsed && parsed.schemaVersion === 2 && parsed.runtime && Array.isArray(parsed.channels)) {
|
|
4674
|
+
parsed.runtime.provider = normalizeRuntimeProvider(parsed.runtime.provider);
|
|
4675
|
+
parsed.channels = normalizeChannelInstances(parsed.channels);
|
|
4671
4676
|
return parsed;
|
|
4672
4677
|
}
|
|
4673
4678
|
return null;
|
|
@@ -4687,9 +4692,32 @@ function defaultAliasForProvider(provider) {
|
|
|
4687
4692
|
function buildDefaultChannelId(provider) {
|
|
4688
4693
|
return `${provider}-default`;
|
|
4689
4694
|
}
|
|
4695
|
+
function normalizeRuntimeProvider(_value) {
|
|
4696
|
+
return "codex";
|
|
4697
|
+
}
|
|
4698
|
+
function normalizeChannelInstances(value) {
|
|
4699
|
+
if (!Array.isArray(value)) return [];
|
|
4700
|
+
return value.flatMap((entry) => {
|
|
4701
|
+
if (!entry || typeof entry !== "object") return [];
|
|
4702
|
+
const record = entry;
|
|
4703
|
+
if (!isSupportedChannelProvider(record.provider)) return [];
|
|
4704
|
+
const provider = record.provider;
|
|
4705
|
+
const config = record.config && typeof record.config === "object" ? record.config : {};
|
|
4706
|
+
const timestamp = nowIso();
|
|
4707
|
+
return [{
|
|
4708
|
+
id: normalizeChannelId(
|
|
4709
|
+
typeof record.id === "string" && record.id.trim() ? record.id : buildDefaultChannelId(provider)
|
|
4710
|
+
),
|
|
4711
|
+
alias: typeof record.alias === "string" && record.alias.trim() ? record.alias.trim() : defaultAliasForProvider(provider),
|
|
4712
|
+
provider,
|
|
4713
|
+
enabled: record.enabled === true,
|
|
4714
|
+
createdAt: typeof record.createdAt === "string" ? record.createdAt : timestamp,
|
|
4715
|
+
updatedAt: typeof record.updatedAt === "string" ? record.updatedAt : timestamp,
|
|
4716
|
+
config
|
|
4717
|
+
}];
|
|
4718
|
+
});
|
|
4719
|
+
}
|
|
4690
4720
|
function migrateLegacyEnvToV2(env) {
|
|
4691
|
-
const rawRuntime = env.get("CTI_RUNTIME") || "codex";
|
|
4692
|
-
const runtime = ["claude", "codex", "auto"].includes(rawRuntime) ? rawRuntime : "codex";
|
|
4693
4721
|
const enabledChannels = splitCsv(env.get("CTI_ENABLED_CHANNELS")) ?? ["feishu"];
|
|
4694
4722
|
const timestamp = nowIso();
|
|
4695
4723
|
const channels = [];
|
|
@@ -4736,7 +4764,7 @@ function migrateLegacyEnvToV2(env) {
|
|
|
4736
4764
|
return {
|
|
4737
4765
|
schemaVersion: 2,
|
|
4738
4766
|
runtime: {
|
|
4739
|
-
provider:
|
|
4767
|
+
provider: "codex",
|
|
4740
4768
|
defaultWorkspaceRoot: expandHomePath(env.get("CTI_DEFAULT_WORKSPACE_ROOT")) || void 0,
|
|
4741
4769
|
defaultModel: env.get("CTI_DEFAULT_MODEL") || void 0,
|
|
4742
4770
|
defaultMode: env.get("CTI_DEFAULT_MODE") || "code",
|
|
@@ -4747,8 +4775,7 @@ function migrateLegacyEnvToV2(env) {
|
|
|
4747
4775
|
codexSandboxMode: parseSandboxMode(env.get("CTI_CODEX_SANDBOX_MODE")) ?? "workspace-write",
|
|
4748
4776
|
codexReasoningEffort: parseReasoningEffort(env.get("CTI_CODEX_REASONING_EFFORT")) ?? "medium",
|
|
4749
4777
|
uiAllowLan: env.get("CTI_UI_ALLOW_LAN") === "true",
|
|
4750
|
-
uiAccessToken: env.get("CTI_UI_ACCESS_TOKEN") || void 0
|
|
4751
|
-
autoApprove: env.get("CTI_AUTO_APPROVE") === "true"
|
|
4778
|
+
uiAccessToken: env.get("CTI_UI_ACCESS_TOKEN") || void 0
|
|
4752
4779
|
},
|
|
4753
4780
|
channels
|
|
4754
4781
|
};
|
|
@@ -4775,13 +4802,13 @@ function expandConfig(v2) {
|
|
|
4775
4802
|
codexSandboxMode: v2.runtime.codexSandboxMode ?? "workspace-write",
|
|
4776
4803
|
codexReasoningEffort: v2.runtime.codexReasoningEffort ?? "medium",
|
|
4777
4804
|
uiAllowLan: v2.runtime.uiAllowLan === true,
|
|
4778
|
-
uiAccessToken: v2.runtime.uiAccessToken || void 0
|
|
4779
|
-
autoApprove: v2.runtime.autoApprove === true
|
|
4805
|
+
uiAccessToken: v2.runtime.uiAccessToken || void 0
|
|
4780
4806
|
};
|
|
4781
4807
|
}
|
|
4782
4808
|
function buildV2FileFromExpandedConfig(config, current) {
|
|
4783
4809
|
const hasExplicitChannels = Array.isArray(config.channels);
|
|
4784
4810
|
let channels = hasExplicitChannels ? [...config.channels || []] : [...current?.channels || []];
|
|
4811
|
+
channels = normalizeChannelInstances(channels);
|
|
4785
4812
|
return {
|
|
4786
4813
|
schemaVersion: 2,
|
|
4787
4814
|
runtime: {
|
|
@@ -4796,8 +4823,7 @@ function buildV2FileFromExpandedConfig(config, current) {
|
|
|
4796
4823
|
codexSandboxMode: config.codexSandboxMode,
|
|
4797
4824
|
codexReasoningEffort: config.codexReasoningEffort,
|
|
4798
4825
|
uiAllowLan: config.uiAllowLan,
|
|
4799
|
-
uiAccessToken: config.uiAccessToken
|
|
4800
|
-
autoApprove: config.autoApprove
|
|
4826
|
+
uiAccessToken: config.uiAccessToken
|
|
4801
4827
|
},
|
|
4802
4828
|
channels: channels.map((channel) => ({
|
|
4803
4829
|
...channel,
|
|
@@ -4827,8 +4853,7 @@ function loadConfig() {
|
|
|
4827
4853
|
codexSkipGitRepoCheck: true,
|
|
4828
4854
|
codexSandboxMode: "workspace-write",
|
|
4829
4855
|
codexReasoningEffort: "medium",
|
|
4830
|
-
uiAllowLan: false
|
|
4831
|
-
autoApprove: false
|
|
4856
|
+
uiAllowLan: false
|
|
4832
4857
|
},
|
|
4833
4858
|
channels: []
|
|
4834
4859
|
};
|
|
@@ -4894,7 +4919,6 @@ function saveConfig(config) {
|
|
|
4894
4919
|
out += formatEnvLine("CTI_WEIXIN_COMMAND_MARKDOWN_ENABLED", String(weixinConfig.feedbackMarkdownEnabled));
|
|
4895
4920
|
}
|
|
4896
4921
|
}
|
|
4897
|
-
out += formatEnvLine("CTI_AUTO_APPROVE", String(next.runtime.autoApprove === true));
|
|
4898
4922
|
ensureConfigDir();
|
|
4899
4923
|
const tmpPath = CONFIG_PATH + ".tmp";
|
|
4900
4924
|
fs.writeFileSync(tmpPath, out, { mode: 384 });
|
|
@@ -4908,13 +4932,14 @@ function findChannelInstance(channelId, config) {
|
|
|
4908
4932
|
}
|
|
4909
4933
|
function configToSettings(config) {
|
|
4910
4934
|
const m = /* @__PURE__ */ new Map();
|
|
4935
|
+
const channels = normalizeChannelInstances(config.channels || []);
|
|
4911
4936
|
const current = {
|
|
4912
4937
|
schemaVersion: 2,
|
|
4913
4938
|
runtime: {
|
|
4914
4939
|
provider: config.runtime,
|
|
4915
4940
|
defaultMode: config.defaultMode
|
|
4916
4941
|
},
|
|
4917
|
-
channels
|
|
4942
|
+
channels
|
|
4918
4943
|
};
|
|
4919
4944
|
const feishu = getChannelByProvider(current, "feishu");
|
|
4920
4945
|
const weixin = getChannelByProvider(current, "weixin");
|
|
@@ -4959,23 +4984,8 @@ function configToSettings(config) {
|
|
|
4959
4984
|
);
|
|
4960
4985
|
m.set(
|
|
4961
4986
|
"bridge_channel_instances_json",
|
|
4962
|
-
JSON.stringify(
|
|
4963
|
-
);
|
|
4964
|
-
m.set(
|
|
4965
|
-
"bridge_telegram_enabled",
|
|
4966
|
-
config.enabledChannels.includes("telegram") ? "true" : "false"
|
|
4967
|
-
);
|
|
4968
|
-
if (config.tgBotToken) m.set("telegram_bot_token", config.tgBotToken);
|
|
4969
|
-
if (config.tgAllowedUsers) m.set("telegram_bridge_allowed_users", config.tgAllowedUsers.join(","));
|
|
4970
|
-
if (config.tgChatId) m.set("telegram_chat_id", config.tgChatId);
|
|
4971
|
-
m.set(
|
|
4972
|
-
"bridge_discord_enabled",
|
|
4973
|
-
config.enabledChannels.includes("discord") ? "true" : "false"
|
|
4987
|
+
JSON.stringify(channels)
|
|
4974
4988
|
);
|
|
4975
|
-
if (config.discordBotToken) m.set("bridge_discord_bot_token", config.discordBotToken);
|
|
4976
|
-
if (config.discordAllowedUsers) m.set("bridge_discord_allowed_users", config.discordAllowedUsers.join(","));
|
|
4977
|
-
if (config.discordAllowedChannels) m.set("bridge_discord_allowed_channels", config.discordAllowedChannels.join(","));
|
|
4978
|
-
if (config.discordAllowedGuilds) m.set("bridge_discord_allowed_guilds", config.discordAllowedGuilds.join(","));
|
|
4979
4989
|
m.set(
|
|
4980
4990
|
"bridge_feishu_enabled",
|
|
4981
4991
|
feishu?.enabled === true ? "true" : "false"
|
|
@@ -4992,19 +5002,6 @@ function configToSettings(config) {
|
|
|
4992
5002
|
"bridge_feishu_command_markdown_enabled",
|
|
4993
5003
|
feishuConfig?.feedbackMarkdownEnabled === false ? "false" : "true"
|
|
4994
5004
|
);
|
|
4995
|
-
m.set(
|
|
4996
|
-
"bridge_qq_enabled",
|
|
4997
|
-
config.enabledChannels.includes("qq") ? "true" : "false"
|
|
4998
|
-
);
|
|
4999
|
-
if (config.qqAppId) m.set("bridge_qq_app_id", config.qqAppId);
|
|
5000
|
-
if (config.qqAppSecret) m.set("bridge_qq_app_secret", config.qqAppSecret);
|
|
5001
|
-
if (config.qqAllowedUsers) m.set("bridge_qq_allowed_users", config.qqAllowedUsers.join(","));
|
|
5002
|
-
if (config.qqImageEnabled !== void 0) {
|
|
5003
|
-
m.set("bridge_qq_image_enabled", String(config.qqImageEnabled));
|
|
5004
|
-
}
|
|
5005
|
-
if (config.qqMaxImageSize !== void 0) {
|
|
5006
|
-
m.set("bridge_qq_max_image_size", String(config.qqMaxImageSize));
|
|
5007
|
-
}
|
|
5008
5005
|
m.set(
|
|
5009
5006
|
"bridge_weixin_enabled",
|
|
5010
5007
|
weixin?.enabled === true ? "true" : "false"
|
|
@@ -5414,6 +5411,42 @@ function isArchivedDesktopThread(threadId) {
|
|
|
5414
5411
|
|
|
5415
5412
|
// src/session-bindings.ts
|
|
5416
5413
|
import path3 from "node:path";
|
|
5414
|
+
|
|
5415
|
+
// src/lib/bridge/binding-audit.ts
|
|
5416
|
+
function describeBinding(binding) {
|
|
5417
|
+
if (!binding) return "none";
|
|
5418
|
+
const parts = [
|
|
5419
|
+
`session=${binding.codepilotSessionId}`,
|
|
5420
|
+
`sdk=${binding.sdkSessionId || "-"}`,
|
|
5421
|
+
`mode=${binding.mode}`
|
|
5422
|
+
];
|
|
5423
|
+
if (binding.workingDirectory) {
|
|
5424
|
+
parts.push(`cwd=${binding.workingDirectory}`);
|
|
5425
|
+
}
|
|
5426
|
+
return parts.join(", ");
|
|
5427
|
+
}
|
|
5428
|
+
function recordBindingChange(store, input) {
|
|
5429
|
+
const from = describeBinding(input.fromBinding);
|
|
5430
|
+
const to = describeBinding(input.toBinding);
|
|
5431
|
+
const details = [
|
|
5432
|
+
`action=${input.action}`,
|
|
5433
|
+
`from=[${from}]`,
|
|
5434
|
+
`to=[${to}]`
|
|
5435
|
+
];
|
|
5436
|
+
if (input.source) details.push(`source=${input.source}`);
|
|
5437
|
+
if (input.reason) details.push(`reason=${input.reason}`);
|
|
5438
|
+
store.insertAuditLog({
|
|
5439
|
+
channelType: input.address.channelType,
|
|
5440
|
+
channelProvider: input.address.channelProvider || input.toBinding?.channelProvider || input.fromBinding?.channelProvider,
|
|
5441
|
+
channelAlias: input.address.channelAlias || input.toBinding?.channelAlias || input.fromBinding?.channelAlias,
|
|
5442
|
+
chatId: input.address.chatId,
|
|
5443
|
+
direction: "inbound",
|
|
5444
|
+
messageId: input.messageId || `binding-change:${Date.now()}`,
|
|
5445
|
+
summary: `Binding change: ${details.join("; ")}`
|
|
5446
|
+
});
|
|
5447
|
+
}
|
|
5448
|
+
|
|
5449
|
+
// src/session-bindings.ts
|
|
5417
5450
|
function asChannelProvider(value) {
|
|
5418
5451
|
return value === "feishu" || value === "weixin" ? value : void 0;
|
|
5419
5452
|
}
|
|
@@ -5591,6 +5624,7 @@ function updateBindingTarget(store, bindingId, targetKey) {
|
|
|
5591
5624
|
if (!binding) {
|
|
5592
5625
|
throw new Error("Binding not found.");
|
|
5593
5626
|
}
|
|
5627
|
+
const fromBinding = { ...binding };
|
|
5594
5628
|
if (targetKey.startsWith("desktop:")) {
|
|
5595
5629
|
const threadId = targetKey.slice("desktop:".length);
|
|
5596
5630
|
const desktop = getDesktopSessionByThreadId(threadId);
|
|
@@ -5616,6 +5650,20 @@ function updateBindingTarget(store, bindingId, targetKey) {
|
|
|
5616
5650
|
} else {
|
|
5617
5651
|
throw new Error("Unsupported target.");
|
|
5618
5652
|
}
|
|
5653
|
+
const toBinding = store.getChannelBinding(binding.channelType, binding.chatId);
|
|
5654
|
+
recordBindingChange(store, {
|
|
5655
|
+
action: "web_switch",
|
|
5656
|
+
address: {
|
|
5657
|
+
channelType: binding.channelType,
|
|
5658
|
+
channelProvider: binding.channelProvider,
|
|
5659
|
+
channelAlias: binding.channelAlias,
|
|
5660
|
+
chatId: binding.chatId
|
|
5661
|
+
},
|
|
5662
|
+
fromBinding,
|
|
5663
|
+
toBinding,
|
|
5664
|
+
source: "web_ui",
|
|
5665
|
+
reason: `target=${targetKey}`
|
|
5666
|
+
});
|
|
5619
5667
|
const updated = listBindingSummaries(store).find((item) => item.id === bindingId);
|
|
5620
5668
|
if (!updated) {
|
|
5621
5669
|
throw new Error("Updated binding not found.");
|
|
@@ -5627,50 +5675,102 @@ function removeBinding(store, bindingId) {
|
|
|
5627
5675
|
if (!binding) {
|
|
5628
5676
|
throw new Error("Binding not found.");
|
|
5629
5677
|
}
|
|
5678
|
+
const fromBinding = { ...binding };
|
|
5630
5679
|
store.deleteChannelBinding(bindingId);
|
|
5680
|
+
recordBindingChange(store, {
|
|
5681
|
+
action: "web_unbind",
|
|
5682
|
+
address: {
|
|
5683
|
+
channelType: binding.channelType,
|
|
5684
|
+
channelProvider: binding.channelProvider,
|
|
5685
|
+
channelAlias: binding.channelAlias,
|
|
5686
|
+
chatId: binding.chatId
|
|
5687
|
+
},
|
|
5688
|
+
fromBinding,
|
|
5689
|
+
toBinding: null,
|
|
5690
|
+
source: "web_ui"
|
|
5691
|
+
});
|
|
5631
5692
|
}
|
|
5632
5693
|
|
|
5633
5694
|
// src/service-manager.ts
|
|
5634
|
-
import
|
|
5695
|
+
import fs4 from "node:fs";
|
|
5635
5696
|
import os3 from "node:os";
|
|
5636
|
-
import
|
|
5697
|
+
import path5 from "node:path";
|
|
5637
5698
|
import { spawn } from "node:child_process";
|
|
5638
5699
|
import { fileURLToPath } from "node:url";
|
|
5639
|
-
|
|
5640
|
-
|
|
5700
|
+
|
|
5701
|
+
// src/bridge-instance-lock.ts
|
|
5702
|
+
import fs3 from "node:fs";
|
|
5703
|
+
import path4 from "node:path";
|
|
5641
5704
|
var runtimeDir = path4.join(CTI_HOME, "runtime");
|
|
5642
|
-
var
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5705
|
+
var bridgeInstanceLockFile = path4.join(runtimeDir, "bridge.instance.lock");
|
|
5706
|
+
function readJsonFile(filePath, fallback) {
|
|
5707
|
+
try {
|
|
5708
|
+
return JSON.parse(fs3.readFileSync(filePath, "utf-8"));
|
|
5709
|
+
} catch {
|
|
5710
|
+
return fallback;
|
|
5711
|
+
}
|
|
5712
|
+
}
|
|
5713
|
+
function isProcessAlive(pid) {
|
|
5714
|
+
if (!pid) return false;
|
|
5715
|
+
try {
|
|
5716
|
+
process.kill(pid, 0);
|
|
5717
|
+
return true;
|
|
5718
|
+
} catch {
|
|
5719
|
+
return false;
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
function readBridgeInstanceLock(filePath = bridgeInstanceLockFile) {
|
|
5723
|
+
const parsed = readJsonFile(filePath, null);
|
|
5724
|
+
const pid = Number(parsed?.pid);
|
|
5725
|
+
const createdAt = typeof parsed?.createdAt === "string" ? parsed.createdAt : "";
|
|
5726
|
+
if (!Number.isFinite(pid) || pid <= 0 || !createdAt) return null;
|
|
5727
|
+
return { pid, createdAt };
|
|
5728
|
+
}
|
|
5729
|
+
function clearStaleBridgeInstanceLock(filePath = bridgeInstanceLockFile, isAlive = isProcessAlive) {
|
|
5730
|
+
const existing = readBridgeInstanceLock(filePath);
|
|
5731
|
+
if (existing && isAlive(existing.pid)) return;
|
|
5732
|
+
try {
|
|
5733
|
+
fs3.unlinkSync(filePath);
|
|
5734
|
+
} catch {
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5737
|
+
|
|
5738
|
+
// src/service-manager.ts
|
|
5739
|
+
var moduleDir = path5.dirname(fileURLToPath(import.meta.url));
|
|
5740
|
+
var packageRoot = path5.resolve(moduleDir, "..");
|
|
5741
|
+
var runtimeDir2 = path5.join(CTI_HOME, "runtime");
|
|
5742
|
+
var logsDir = path5.join(CTI_HOME, "logs");
|
|
5743
|
+
var bridgePidFile = path5.join(runtimeDir2, "bridge.pid");
|
|
5744
|
+
var bridgeStatusFile = path5.join(runtimeDir2, "status.json");
|
|
5745
|
+
var bridgeStartLockFile = path5.join(runtimeDir2, "bridge.start.lock");
|
|
5746
|
+
var uiStatusFile = path5.join(runtimeDir2, "ui-server.json");
|
|
5647
5747
|
var uiPort = 4781;
|
|
5648
5748
|
var bridgeAutostartTaskName = "CodexToIMBridge";
|
|
5649
|
-
var bridgeAutostartLauncherFile =
|
|
5650
|
-
var npmUninstallLogFile =
|
|
5749
|
+
var bridgeAutostartLauncherFile = path5.join(runtimeDir2, "bridge-autostart.ps1");
|
|
5750
|
+
var npmUninstallLogFile = path5.join(runtimeDir2, "npm-uninstall.log");
|
|
5651
5751
|
var WINDOWS_HIDE = process.platform === "win32" ? { windowsHide: true } : {};
|
|
5652
5752
|
var BRIDGE_START_LOCK_STALE_MS = 3e4;
|
|
5653
5753
|
function ensureDirs() {
|
|
5654
|
-
|
|
5655
|
-
|
|
5754
|
+
fs4.mkdirSync(runtimeDir2, { recursive: true });
|
|
5755
|
+
fs4.mkdirSync(logsDir, { recursive: true });
|
|
5656
5756
|
}
|
|
5657
|
-
function
|
|
5757
|
+
function readJsonFile2(filePath, fallback) {
|
|
5658
5758
|
try {
|
|
5659
|
-
return JSON.parse(
|
|
5759
|
+
return JSON.parse(fs4.readFileSync(filePath, "utf-8"));
|
|
5660
5760
|
} catch {
|
|
5661
5761
|
return fallback;
|
|
5662
5762
|
}
|
|
5663
5763
|
}
|
|
5664
5764
|
function readPid(filePath) {
|
|
5665
5765
|
try {
|
|
5666
|
-
const raw =
|
|
5766
|
+
const raw = fs4.readFileSync(filePath, "utf-8").trim();
|
|
5667
5767
|
const pid = Number(raw);
|
|
5668
5768
|
return Number.isFinite(pid) ? pid : void 0;
|
|
5669
5769
|
} catch {
|
|
5670
5770
|
return void 0;
|
|
5671
5771
|
}
|
|
5672
5772
|
}
|
|
5673
|
-
function
|
|
5773
|
+
function isProcessAlive2(pid) {
|
|
5674
5774
|
if (!pid) return false;
|
|
5675
5775
|
try {
|
|
5676
5776
|
process.kill(pid, 0);
|
|
@@ -5679,32 +5779,37 @@ function isProcessAlive(pid) {
|
|
|
5679
5779
|
return false;
|
|
5680
5780
|
}
|
|
5681
5781
|
}
|
|
5682
|
-
function collectTrackedBridgePids(bridgePid, statusPid) {
|
|
5782
|
+
function collectTrackedBridgePids(bridgePid, statusPid, instanceLockPid) {
|
|
5683
5783
|
const unique = /* @__PURE__ */ new Set();
|
|
5684
|
-
for (const pid of [bridgePid, statusPid]) {
|
|
5784
|
+
for (const pid of [bridgePid, statusPid, instanceLockPid]) {
|
|
5685
5785
|
if (Number.isFinite(pid) && pid > 0) {
|
|
5686
5786
|
unique.add(pid);
|
|
5687
5787
|
}
|
|
5688
5788
|
}
|
|
5689
5789
|
return [...unique];
|
|
5690
5790
|
}
|
|
5691
|
-
function resolveTrackedBridgePid(bridgePid, statusPid, isAlive =
|
|
5791
|
+
function resolveTrackedBridgePid(bridgePid, statusPid, instanceLockPid, isAlive = isProcessAlive2) {
|
|
5692
5792
|
if (isAlive(bridgePid)) return bridgePid;
|
|
5693
5793
|
if (isAlive(statusPid)) return statusPid;
|
|
5694
|
-
|
|
5794
|
+
if (isAlive(instanceLockPid)) return instanceLockPid;
|
|
5795
|
+
return bridgePid ?? statusPid ?? instanceLockPid;
|
|
5695
5796
|
}
|
|
5696
5797
|
function getTrackedBridgePids(status) {
|
|
5697
|
-
const resolvedStatus = status ??
|
|
5698
|
-
return collectTrackedBridgePids(
|
|
5798
|
+
const resolvedStatus = status ?? readJsonFile2(bridgeStatusFile, { running: false });
|
|
5799
|
+
return collectTrackedBridgePids(
|
|
5800
|
+
readPid(bridgePidFile),
|
|
5801
|
+
resolvedStatus.pid,
|
|
5802
|
+
readBridgeInstanceLock()?.pid
|
|
5803
|
+
);
|
|
5699
5804
|
}
|
|
5700
5805
|
function clearBridgePidFile() {
|
|
5701
5806
|
try {
|
|
5702
|
-
|
|
5807
|
+
fs4.unlinkSync(bridgePidFile);
|
|
5703
5808
|
} catch {
|
|
5704
5809
|
}
|
|
5705
5810
|
}
|
|
5706
5811
|
function readBridgeStartLock(filePath = bridgeStartLockFile) {
|
|
5707
|
-
const parsed =
|
|
5812
|
+
const parsed = readJsonFile2(filePath, null);
|
|
5708
5813
|
const pid = Number(parsed?.pid);
|
|
5709
5814
|
const createdAt = typeof parsed?.createdAt === "string" ? parsed.createdAt : "";
|
|
5710
5815
|
if (!Number.isFinite(pid) || pid <= 0 || !createdAt) return null;
|
|
@@ -5714,7 +5819,7 @@ function isBridgeStartLockStale(lock, options = {}) {
|
|
|
5714
5819
|
if (!lock) return true;
|
|
5715
5820
|
const nowMs = options.nowMs ?? Date.now();
|
|
5716
5821
|
const staleMs = options.staleMs ?? BRIDGE_START_LOCK_STALE_MS;
|
|
5717
|
-
const isAlive = options.isAlive ??
|
|
5822
|
+
const isAlive = options.isAlive ?? isProcessAlive2;
|
|
5718
5823
|
const createdAtMs = Date.parse(lock.createdAt);
|
|
5719
5824
|
if (!Number.isFinite(createdAtMs)) return true;
|
|
5720
5825
|
if (!isAlive(lock.pid)) return true;
|
|
@@ -5730,7 +5835,7 @@ function tryAcquireBridgeStartLock(options = {}) {
|
|
|
5730
5835
|
};
|
|
5731
5836
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
5732
5837
|
try {
|
|
5733
|
-
|
|
5838
|
+
fs4.writeFileSync(filePath, JSON.stringify(payload, null, 2), { encoding: "utf-8", flag: "wx" });
|
|
5734
5839
|
return { acquired: true };
|
|
5735
5840
|
} catch (error) {
|
|
5736
5841
|
const code = error.code;
|
|
@@ -5744,7 +5849,7 @@ function tryAcquireBridgeStartLock(options = {}) {
|
|
|
5744
5849
|
return { acquired: false, holderPid: existing2?.pid };
|
|
5745
5850
|
}
|
|
5746
5851
|
try {
|
|
5747
|
-
|
|
5852
|
+
fs4.unlinkSync(filePath);
|
|
5748
5853
|
} catch {
|
|
5749
5854
|
}
|
|
5750
5855
|
}
|
|
@@ -5756,14 +5861,14 @@ function releaseBridgeStartLock(filePath = bridgeStartLockFile, ownerPid = proce
|
|
|
5756
5861
|
const existing = readBridgeStartLock(filePath);
|
|
5757
5862
|
if (!existing) {
|
|
5758
5863
|
try {
|
|
5759
|
-
|
|
5864
|
+
fs4.unlinkSync(filePath);
|
|
5760
5865
|
} catch {
|
|
5761
5866
|
}
|
|
5762
5867
|
return;
|
|
5763
5868
|
}
|
|
5764
5869
|
if (existing.pid !== ownerPid) return;
|
|
5765
5870
|
try {
|
|
5766
|
-
|
|
5871
|
+
fs4.unlinkSync(filePath);
|
|
5767
5872
|
} catch {
|
|
5768
5873
|
}
|
|
5769
5874
|
}
|
|
@@ -5820,9 +5925,13 @@ function getUiServerUrl(port2 = uiPort) {
|
|
|
5820
5925
|
return `http://127.0.0.1:${port2}`;
|
|
5821
5926
|
}
|
|
5822
5927
|
function getBridgeStatus() {
|
|
5823
|
-
const status =
|
|
5824
|
-
const pid = resolveTrackedBridgePid(
|
|
5825
|
-
|
|
5928
|
+
const status = readJsonFile2(bridgeStatusFile, { running: false });
|
|
5929
|
+
const pid = resolveTrackedBridgePid(
|
|
5930
|
+
readPid(bridgePidFile),
|
|
5931
|
+
status.pid,
|
|
5932
|
+
readBridgeInstanceLock()?.pid
|
|
5933
|
+
);
|
|
5934
|
+
if (!isProcessAlive2(pid)) {
|
|
5826
5935
|
return {
|
|
5827
5936
|
...status,
|
|
5828
5937
|
pid,
|
|
@@ -5836,8 +5945,8 @@ function getBridgeStatus() {
|
|
|
5836
5945
|
};
|
|
5837
5946
|
}
|
|
5838
5947
|
function getUiServerStatus() {
|
|
5839
|
-
const status =
|
|
5840
|
-
if (!
|
|
5948
|
+
const status = readJsonFile2(uiStatusFile, { running: false, port: uiPort });
|
|
5949
|
+
if (!isProcessAlive2(status.pid)) {
|
|
5841
5950
|
return {
|
|
5842
5951
|
...status,
|
|
5843
5952
|
running: false,
|
|
@@ -5907,7 +6016,7 @@ async function waitForBridgeStartupTurn(timeoutMs = 2e4) {
|
|
|
5907
6016
|
async function startBridge() {
|
|
5908
6017
|
ensureDirs();
|
|
5909
6018
|
const current = getBridgeStatus();
|
|
5910
|
-
const extraAlivePids = getTrackedBridgePids(current).filter((pid) => pid !== current.pid &&
|
|
6019
|
+
const extraAlivePids = getTrackedBridgePids(current).filter((pid) => pid !== current.pid && isProcessAlive2(pid));
|
|
5911
6020
|
if (current.running && extraAlivePids.length === 0) return current;
|
|
5912
6021
|
if (current.running && extraAlivePids.length > 0) {
|
|
5913
6022
|
await stopBridge();
|
|
@@ -5932,17 +6041,17 @@ async function startBridge() {
|
|
|
5932
6041
|
startLockHeld = true;
|
|
5933
6042
|
try {
|
|
5934
6043
|
const currentAfterLock = getBridgeStatus();
|
|
5935
|
-
const extraAlivePidsAfterLock = getTrackedBridgePids(currentAfterLock).filter((pid) => pid !== currentAfterLock.pid &&
|
|
6044
|
+
const extraAlivePidsAfterLock = getTrackedBridgePids(currentAfterLock).filter((pid) => pid !== currentAfterLock.pid && isProcessAlive2(pid));
|
|
5936
6045
|
if (currentAfterLock.running && extraAlivePidsAfterLock.length === 0) return currentAfterLock;
|
|
5937
6046
|
if (currentAfterLock.running && extraAlivePidsAfterLock.length > 0) {
|
|
5938
6047
|
await stopBridge();
|
|
5939
6048
|
}
|
|
5940
|
-
const daemonEntry =
|
|
5941
|
-
if (!
|
|
6049
|
+
const daemonEntry = path5.join(packageRoot, "dist", "daemon.mjs");
|
|
6050
|
+
if (!fs4.existsSync(daemonEntry)) {
|
|
5942
6051
|
throw new Error(`Daemon bundle not found at ${daemonEntry}. Run npm run build first.`);
|
|
5943
6052
|
}
|
|
5944
|
-
const stdoutFd =
|
|
5945
|
-
const stderrFd =
|
|
6053
|
+
const stdoutFd = fs4.openSync(path5.join(logsDir, "bridge-launcher.out.log"), "a");
|
|
6054
|
+
const stderrFd = fs4.openSync(path5.join(logsDir, "bridge-launcher.err.log"), "a");
|
|
5946
6055
|
const child = spawn(process.execPath, [daemonEntry], {
|
|
5947
6056
|
cwd: packageRoot,
|
|
5948
6057
|
detached: true,
|
|
@@ -5965,10 +6074,11 @@ async function startBridge() {
|
|
|
5965
6074
|
}
|
|
5966
6075
|
}
|
|
5967
6076
|
async function stopBridge() {
|
|
5968
|
-
const status =
|
|
5969
|
-
const pids = getTrackedBridgePids(status).filter((pid) =>
|
|
6077
|
+
const status = readJsonFile2(bridgeStatusFile, { running: false });
|
|
6078
|
+
const pids = getTrackedBridgePids(status).filter((pid) => isProcessAlive2(pid));
|
|
5970
6079
|
if (pids.length === 0) {
|
|
5971
6080
|
clearBridgePidFile();
|
|
6081
|
+
clearStaleBridgeInstanceLock();
|
|
5972
6082
|
return { ...getBridgeStatus(), running: false };
|
|
5973
6083
|
}
|
|
5974
6084
|
for (const pid of pids) {
|
|
@@ -5990,13 +6100,15 @@ async function stopBridge() {
|
|
|
5990
6100
|
}
|
|
5991
6101
|
const startedAt = Date.now();
|
|
5992
6102
|
while (Date.now() - startedAt < 1e4) {
|
|
5993
|
-
if (pids.every((pid) => !
|
|
6103
|
+
if (pids.every((pid) => !isProcessAlive2(pid))) {
|
|
5994
6104
|
clearBridgePidFile();
|
|
6105
|
+
clearStaleBridgeInstanceLock();
|
|
5995
6106
|
return getBridgeStatus();
|
|
5996
6107
|
}
|
|
5997
6108
|
await sleep(300);
|
|
5998
6109
|
}
|
|
5999
6110
|
clearBridgePidFile();
|
|
6111
|
+
clearStaleBridgeInstanceLock();
|
|
6000
6112
|
return getBridgeStatus();
|
|
6001
6113
|
}
|
|
6002
6114
|
async function restartBridge() {
|
|
@@ -6059,37 +6171,37 @@ async function getBridgeAutostartStatus() {
|
|
|
6059
6171
|
}
|
|
6060
6172
|
function getBridgeLogs(lines = 200) {
|
|
6061
6173
|
ensureDirs();
|
|
6062
|
-
const filePath =
|
|
6063
|
-
if (!
|
|
6064
|
-
const all =
|
|
6174
|
+
const filePath = path5.join(logsDir, "bridge.log");
|
|
6175
|
+
if (!fs4.existsSync(filePath)) return "";
|
|
6176
|
+
const all = fs4.readFileSync(filePath, "utf-8").split(/\r?\n/);
|
|
6065
6177
|
return all.slice(Math.max(0, all.length - lines)).join("\n");
|
|
6066
6178
|
}
|
|
6067
6179
|
function writeUiServerStatus(status) {
|
|
6068
6180
|
ensureDirs();
|
|
6069
|
-
|
|
6181
|
+
fs4.writeFileSync(uiStatusFile, JSON.stringify(status, null, 2), "utf-8");
|
|
6070
6182
|
}
|
|
6071
6183
|
async function installCodexIntegration() {
|
|
6072
|
-
const sourceSkill =
|
|
6073
|
-
if (!
|
|
6184
|
+
const sourceSkill = path5.join(packageRoot, "SKILL.md");
|
|
6185
|
+
if (!fs4.existsSync(sourceSkill)) {
|
|
6074
6186
|
throw new Error(`SKILL.md not found at ${sourceSkill}`);
|
|
6075
6187
|
}
|
|
6076
|
-
const skillsDir =
|
|
6077
|
-
const targetDir =
|
|
6078
|
-
|
|
6079
|
-
if (
|
|
6188
|
+
const skillsDir = path5.join(os3.homedir(), ".codex", "skills");
|
|
6189
|
+
const targetDir = path5.join(skillsDir, "codex-to-im");
|
|
6190
|
+
fs4.mkdirSync(skillsDir, { recursive: true });
|
|
6191
|
+
if (fs4.existsSync(targetDir)) {
|
|
6080
6192
|
return { targetDir, method: "existing" };
|
|
6081
6193
|
}
|
|
6082
6194
|
try {
|
|
6083
|
-
|
|
6195
|
+
fs4.symlinkSync(packageRoot, targetDir, process.platform === "win32" ? "junction" : "dir");
|
|
6084
6196
|
return { targetDir, method: "junction" };
|
|
6085
6197
|
} catch {
|
|
6086
|
-
|
|
6198
|
+
fs4.cpSync(packageRoot, targetDir, {
|
|
6087
6199
|
recursive: true,
|
|
6088
6200
|
filter: (source) => {
|
|
6089
|
-
const relative =
|
|
6201
|
+
const relative = path5.relative(packageRoot, source);
|
|
6090
6202
|
if (!relative) return true;
|
|
6091
|
-
if (relative === ".git" || relative.startsWith(`.git${
|
|
6092
|
-
if (relative === "node_modules" || relative.startsWith(`node_modules${
|
|
6203
|
+
if (relative === ".git" || relative.startsWith(`.git${path5.sep}`)) return false;
|
|
6204
|
+
if (relative === "node_modules" || relative.startsWith(`node_modules${path5.sep}`)) return false;
|
|
6093
6205
|
return true;
|
|
6094
6206
|
}
|
|
6095
6207
|
});
|
|
@@ -6097,27 +6209,27 @@ async function installCodexIntegration() {
|
|
|
6097
6209
|
}
|
|
6098
6210
|
}
|
|
6099
6211
|
function isCodexIntegrationInstalled() {
|
|
6100
|
-
const targetDir =
|
|
6101
|
-
return
|
|
6212
|
+
const targetDir = path5.join(os3.homedir(), ".codex", "skills", "codex-to-im");
|
|
6213
|
+
return fs4.existsSync(path5.join(targetDir, "SKILL.md"));
|
|
6102
6214
|
}
|
|
6103
6215
|
|
|
6104
6216
|
// src/store.ts
|
|
6105
|
-
import
|
|
6106
|
-
import
|
|
6217
|
+
import fs5 from "node:fs";
|
|
6218
|
+
import path6 from "node:path";
|
|
6107
6219
|
import crypto2 from "node:crypto";
|
|
6108
|
-
var DATA_DIR =
|
|
6109
|
-
var MESSAGES_DIR =
|
|
6220
|
+
var DATA_DIR = path6.join(CTI_HOME, "data");
|
|
6221
|
+
var MESSAGES_DIR = path6.join(DATA_DIR, "messages");
|
|
6110
6222
|
function ensureDir(dir) {
|
|
6111
|
-
|
|
6223
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
6112
6224
|
}
|
|
6113
6225
|
function atomicWrite(filePath, data) {
|
|
6114
6226
|
const tmp = filePath + ".tmp";
|
|
6115
|
-
|
|
6116
|
-
|
|
6227
|
+
fs5.writeFileSync(tmp, data, "utf-8");
|
|
6228
|
+
fs5.renameSync(tmp, filePath);
|
|
6117
6229
|
}
|
|
6118
6230
|
function readJson(filePath, fallback) {
|
|
6119
6231
|
try {
|
|
6120
|
-
const raw =
|
|
6232
|
+
const raw = fs5.readFileSync(filePath, "utf-8");
|
|
6121
6233
|
return JSON.parse(raw);
|
|
6122
6234
|
} catch {
|
|
6123
6235
|
return fallback;
|
|
@@ -6186,38 +6298,38 @@ var JsonFileStore = class {
|
|
|
6186
6298
|
this.reloadSessions();
|
|
6187
6299
|
this.reloadBindings();
|
|
6188
6300
|
const perms = readJson(
|
|
6189
|
-
|
|
6301
|
+
path6.join(DATA_DIR, "permissions.json"),
|
|
6190
6302
|
{}
|
|
6191
6303
|
);
|
|
6192
6304
|
for (const [id, p] of Object.entries(perms)) {
|
|
6193
6305
|
this.permissionLinks.set(id, p);
|
|
6194
6306
|
}
|
|
6195
6307
|
const offsets = readJson(
|
|
6196
|
-
|
|
6308
|
+
path6.join(DATA_DIR, "offsets.json"),
|
|
6197
6309
|
{}
|
|
6198
6310
|
);
|
|
6199
6311
|
for (const [k, v] of Object.entries(offsets)) {
|
|
6200
6312
|
this.offsets.set(k, v);
|
|
6201
6313
|
}
|
|
6202
6314
|
const dedup = readJson(
|
|
6203
|
-
|
|
6315
|
+
path6.join(DATA_DIR, "dedup.json"),
|
|
6204
6316
|
{}
|
|
6205
6317
|
);
|
|
6206
6318
|
for (const [k, v] of Object.entries(dedup)) {
|
|
6207
6319
|
this.dedupKeys.set(k, v);
|
|
6208
6320
|
}
|
|
6209
|
-
this.auditLog = readJson(
|
|
6321
|
+
this.auditLog = readJson(path6.join(DATA_DIR, "audit.json"), []);
|
|
6210
6322
|
}
|
|
6211
6323
|
reloadSessions() {
|
|
6212
6324
|
const sessions = readJson(
|
|
6213
|
-
|
|
6325
|
+
path6.join(DATA_DIR, "sessions.json"),
|
|
6214
6326
|
{}
|
|
6215
6327
|
);
|
|
6216
6328
|
this.sessions = new Map(Object.entries(sessions));
|
|
6217
6329
|
}
|
|
6218
6330
|
reloadBindings() {
|
|
6219
6331
|
const bindings = readJson(
|
|
6220
|
-
|
|
6332
|
+
path6.join(DATA_DIR, "bindings.json"),
|
|
6221
6333
|
{}
|
|
6222
6334
|
);
|
|
6223
6335
|
const normalized = /* @__PURE__ */ new Map();
|
|
@@ -6236,47 +6348,47 @@ var JsonFileStore = class {
|
|
|
6236
6348
|
}
|
|
6237
6349
|
persistSessions() {
|
|
6238
6350
|
writeJson(
|
|
6239
|
-
|
|
6351
|
+
path6.join(DATA_DIR, "sessions.json"),
|
|
6240
6352
|
Object.fromEntries(this.sessions)
|
|
6241
6353
|
);
|
|
6242
6354
|
}
|
|
6243
6355
|
persistBindings() {
|
|
6244
6356
|
writeJson(
|
|
6245
|
-
|
|
6357
|
+
path6.join(DATA_DIR, "bindings.json"),
|
|
6246
6358
|
Object.fromEntries(this.bindings)
|
|
6247
6359
|
);
|
|
6248
6360
|
}
|
|
6249
6361
|
persistPermissions() {
|
|
6250
6362
|
writeJson(
|
|
6251
|
-
|
|
6363
|
+
path6.join(DATA_DIR, "permissions.json"),
|
|
6252
6364
|
Object.fromEntries(this.permissionLinks)
|
|
6253
6365
|
);
|
|
6254
6366
|
}
|
|
6255
6367
|
persistOffsets() {
|
|
6256
6368
|
writeJson(
|
|
6257
|
-
|
|
6369
|
+
path6.join(DATA_DIR, "offsets.json"),
|
|
6258
6370
|
Object.fromEntries(this.offsets)
|
|
6259
6371
|
);
|
|
6260
6372
|
}
|
|
6261
6373
|
persistDedup() {
|
|
6262
6374
|
writeJson(
|
|
6263
|
-
|
|
6375
|
+
path6.join(DATA_DIR, "dedup.json"),
|
|
6264
6376
|
Object.fromEntries(this.dedupKeys)
|
|
6265
6377
|
);
|
|
6266
6378
|
}
|
|
6267
6379
|
persistAudit() {
|
|
6268
|
-
writeJson(
|
|
6380
|
+
writeJson(path6.join(DATA_DIR, "audit.json"), this.auditLog);
|
|
6269
6381
|
}
|
|
6270
6382
|
persistMessages(sessionId) {
|
|
6271
6383
|
const msgs = this.messages.get(sessionId) || [];
|
|
6272
|
-
writeJson(
|
|
6384
|
+
writeJson(path6.join(MESSAGES_DIR, `${sessionId}.json`), msgs);
|
|
6273
6385
|
}
|
|
6274
6386
|
loadMessages(sessionId) {
|
|
6275
6387
|
if (this.messages.has(sessionId)) {
|
|
6276
6388
|
return this.messages.get(sessionId);
|
|
6277
6389
|
}
|
|
6278
6390
|
const msgs = readJson(
|
|
6279
|
-
|
|
6391
|
+
path6.join(MESSAGES_DIR, `${sessionId}.json`),
|
|
6280
6392
|
[]
|
|
6281
6393
|
);
|
|
6282
6394
|
this.messages.set(sessionId, msgs);
|
|
@@ -6444,7 +6556,7 @@ var JsonFileStore = class {
|
|
|
6444
6556
|
}
|
|
6445
6557
|
this.messages.delete(sessionId);
|
|
6446
6558
|
try {
|
|
6447
|
-
|
|
6559
|
+
fs5.rmSync(path6.join(MESSAGES_DIR, `${sessionId}.json`), { force: true });
|
|
6448
6560
|
} catch {
|
|
6449
6561
|
}
|
|
6450
6562
|
this.persistSessions();
|
|
@@ -6627,8 +6739,8 @@ var JsonFileStore = class {
|
|
|
6627
6739
|
|
|
6628
6740
|
// src/weixin-login.ts
|
|
6629
6741
|
var import_qrcode = __toESM(require_lib(), 1);
|
|
6630
|
-
import
|
|
6631
|
-
import
|
|
6742
|
+
import fs7 from "node:fs";
|
|
6743
|
+
import path8 from "node:path";
|
|
6632
6744
|
import crypto4 from "node:crypto";
|
|
6633
6745
|
import { spawn as spawn2 } from "node:child_process";
|
|
6634
6746
|
|
|
@@ -6682,24 +6794,24 @@ async function pollLoginQrStatus(qrcode, baseUrl) {
|
|
|
6682
6794
|
}
|
|
6683
6795
|
|
|
6684
6796
|
// src/weixin-store.ts
|
|
6685
|
-
import
|
|
6686
|
-
import
|
|
6687
|
-
var DATA_DIR2 =
|
|
6688
|
-
var ACCOUNTS_PATH =
|
|
6689
|
-
var CONTEXT_TOKENS_PATH =
|
|
6797
|
+
import fs6 from "node:fs";
|
|
6798
|
+
import path7 from "node:path";
|
|
6799
|
+
var DATA_DIR2 = path7.join(CTI_HOME, "data");
|
|
6800
|
+
var ACCOUNTS_PATH = path7.join(DATA_DIR2, "weixin-accounts.json");
|
|
6801
|
+
var CONTEXT_TOKENS_PATH = path7.join(DATA_DIR2, "weixin-context-tokens.json");
|
|
6690
6802
|
var DEFAULT_BASE_URL2 = "https://ilinkai.weixin.qq.com";
|
|
6691
6803
|
var DEFAULT_CDN_BASE_URL2 = "https://novac2c.cdn.weixin.qq.com/c2c";
|
|
6692
6804
|
function ensureDir2(dir) {
|
|
6693
|
-
|
|
6805
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
6694
6806
|
}
|
|
6695
6807
|
function atomicWrite2(filePath, data) {
|
|
6696
6808
|
const tmpPath = `${filePath}.tmp`;
|
|
6697
|
-
|
|
6698
|
-
|
|
6809
|
+
fs6.writeFileSync(tmpPath, data, "utf-8");
|
|
6810
|
+
fs6.renameSync(tmpPath, filePath);
|
|
6699
6811
|
}
|
|
6700
6812
|
function readJson2(filePath, fallback) {
|
|
6701
6813
|
try {
|
|
6702
|
-
const raw =
|
|
6814
|
+
const raw = fs6.readFileSync(filePath, "utf-8");
|
|
6703
6815
|
return JSON.parse(raw);
|
|
6704
6816
|
} catch {
|
|
6705
6817
|
return fallback;
|
|
@@ -6789,11 +6901,11 @@ var MAX_REFRESHES = 3;
|
|
|
6789
6901
|
var QR_TTL_MS = 5 * 6e4;
|
|
6790
6902
|
var POLL_INTERVAL_MS = 3e3;
|
|
6791
6903
|
var WEB_SESSION_TTL_MS = 15 * 6e4;
|
|
6792
|
-
var RUNTIME_DIR =
|
|
6793
|
-
var HTML_PATH =
|
|
6904
|
+
var RUNTIME_DIR = path8.join(CTI_HOME, "runtime");
|
|
6905
|
+
var HTML_PATH = path8.join(RUNTIME_DIR, "weixin-login.html");
|
|
6794
6906
|
var webLoginSessions = /* @__PURE__ */ new Map();
|
|
6795
6907
|
function ensureRuntimeDir() {
|
|
6796
|
-
|
|
6908
|
+
fs7.mkdirSync(RUNTIME_DIR, { recursive: true });
|
|
6797
6909
|
}
|
|
6798
6910
|
function escapeHtml(text2) {
|
|
6799
6911
|
return text2.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
@@ -7106,7 +7218,7 @@ function buildWeixinLoginPopupHtml(sessionId) {
|
|
|
7106
7218
|
async function writeQrHtml(session) {
|
|
7107
7219
|
ensureRuntimeDir();
|
|
7108
7220
|
const qrSvg = await buildQrSvg(session.qrImageUrl);
|
|
7109
|
-
|
|
7221
|
+
fs7.writeFileSync(HTML_PATH, buildQrHtml(qrSvg), "utf-8");
|
|
7110
7222
|
}
|
|
7111
7223
|
function openQrHtml() {
|
|
7112
7224
|
try {
|
|
@@ -7367,7 +7479,7 @@ async function runWeixinLogin(config = {}) {
|
|
|
7367
7479
|
}
|
|
7368
7480
|
var isMainModule = (() => {
|
|
7369
7481
|
const entry = process.argv[1];
|
|
7370
|
-
return !!entry &&
|
|
7482
|
+
return !!entry && path8.resolve(entry) === path8.resolve(new URL(import.meta.url).pathname);
|
|
7371
7483
|
})();
|
|
7372
7484
|
if (isMainModule) {
|
|
7373
7485
|
runWeixinLogin().catch((err) => {
|
|
@@ -7377,14 +7489,14 @@ if (isMainModule) {
|
|
|
7377
7489
|
}
|
|
7378
7490
|
|
|
7379
7491
|
// src/codex-models.ts
|
|
7380
|
-
import
|
|
7492
|
+
import fs8 from "node:fs";
|
|
7381
7493
|
import os4 from "node:os";
|
|
7382
|
-
import
|
|
7383
|
-
var DEFAULT_CODEX_CONFIG_PATH =
|
|
7384
|
-
var DEFAULT_CODEX_MODELS_CACHE_PATH =
|
|
7494
|
+
import path9 from "node:path";
|
|
7495
|
+
var DEFAULT_CODEX_CONFIG_PATH = path9.join(os4.homedir(), ".codex", "config.toml");
|
|
7496
|
+
var DEFAULT_CODEX_MODELS_CACHE_PATH = path9.join(os4.homedir(), ".codex", "models_cache.json");
|
|
7385
7497
|
function readConfiguredCodexModel(configPath = DEFAULT_CODEX_CONFIG_PATH) {
|
|
7386
7498
|
try {
|
|
7387
|
-
const raw =
|
|
7499
|
+
const raw = fs8.readFileSync(configPath, "utf-8");
|
|
7388
7500
|
let inSection = false;
|
|
7389
7501
|
for (const line of raw.split(/\r?\n/)) {
|
|
7390
7502
|
const trimmed = line.trim();
|
|
@@ -7406,7 +7518,7 @@ function readConfiguredCodexModel(configPath = DEFAULT_CODEX_CONFIG_PATH) {
|
|
|
7406
7518
|
}
|
|
7407
7519
|
function listCachedCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH) {
|
|
7408
7520
|
try {
|
|
7409
|
-
const raw =
|
|
7521
|
+
const raw = fs8.readFileSync(cachePath, "utf-8");
|
|
7410
7522
|
const parsed = JSON.parse(raw);
|
|
7411
7523
|
if (!Array.isArray(parsed.models)) return [];
|
|
7412
7524
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -7661,8 +7773,7 @@ function configToPayload(config) {
|
|
|
7661
7773
|
codexReasoningEffort: config.codexReasoningEffort || "medium",
|
|
7662
7774
|
uiAllowLan: config.uiAllowLan === true,
|
|
7663
7775
|
uiAccessToken: config.uiAccessToken || "",
|
|
7664
|
-
|
|
7665
|
-
channels: (config.channels || []).map(channelToPayload)
|
|
7776
|
+
channels: (config.channels || []).filter((channel) => isSupportedChannelProvider(channel.provider)).map(channelToPayload)
|
|
7666
7777
|
};
|
|
7667
7778
|
}
|
|
7668
7779
|
function mergeConfig(payload) {
|
|
@@ -7673,7 +7784,7 @@ function mergeConfig(payload) {
|
|
|
7673
7784
|
const uiAccessToken = requestedUiAccessToken || current.uiAccessToken || (uiAllowLan ? generateAccessToken() : void 0);
|
|
7674
7785
|
return {
|
|
7675
7786
|
...current,
|
|
7676
|
-
runtime:
|
|
7787
|
+
runtime: "codex",
|
|
7677
7788
|
enabledChannels: current.enabledChannels,
|
|
7678
7789
|
defaultWorkspaceRoot: asString(payload.defaultWorkspaceRoot),
|
|
7679
7790
|
defaultModel: rawDefaultModel === void 0 ? current.defaultModel : rawDefaultModel === "" ? void 0 : availableCodexModelSlugs.has(rawDefaultModel) ? rawDefaultModel : current.defaultModel,
|
|
@@ -7686,7 +7797,6 @@ function mergeConfig(payload) {
|
|
|
7686
7797
|
codexReasoningEffort: payload.codexReasoningEffort === "minimal" || payload.codexReasoningEffort === "low" || payload.codexReasoningEffort === "high" || payload.codexReasoningEffort === "xhigh" ? payload.codexReasoningEffort : "medium",
|
|
7687
7798
|
uiAllowLan,
|
|
7688
7799
|
uiAccessToken,
|
|
7689
|
-
autoApprove: payload.autoApprove === true,
|
|
7690
7800
|
channels: current.channels
|
|
7691
7801
|
};
|
|
7692
7802
|
}
|
|
@@ -9502,8 +9612,6 @@ function renderHtml() {
|
|
|
9502
9612
|
Runtime
|
|
9503
9613
|
<select id="runtime">
|
|
9504
9614
|
<option value="codex" selected>codex</option>
|
|
9505
|
-
<option value="auto">auto</option>
|
|
9506
|
-
<option value="claude">claude</option>
|
|
9507
9615
|
</select>
|
|
9508
9616
|
</label>
|
|
9509
9617
|
<label>
|
|
@@ -9519,11 +9627,11 @@ function renderHtml() {
|
|
|
9519
9627
|
<input id="historyMessageLimit" type="number" min="1" max="20" value="8" />
|
|
9520
9628
|
</label>
|
|
9521
9629
|
<label>
|
|
9522
|
-
\
|
|
9630
|
+
\u4E0A\u6B21\u54CD\u5E94\u8DDD\u4ECA\u663E\u793A\u542F\u52A8\u65F6\u957F\uFF08\u79D2\uFF09
|
|
9523
9631
|
<input id="streamStatusIdleStartSeconds" type="number" min="1" value="180" />
|
|
9524
9632
|
</label>
|
|
9525
9633
|
<label>
|
|
9526
|
-
\
|
|
9634
|
+
\u4E0A\u6B21\u54CD\u5E94\u8DDD\u4ECA\u68C0\u67E5\u95F4\u9694\uFF08\u79D2\uFF09
|
|
9527
9635
|
<input id="streamStatusCheckIntervalSeconds" type="number" min="1" value="10" />
|
|
9528
9636
|
</label>
|
|
9529
9637
|
</div>
|
|
@@ -9555,11 +9663,8 @@ function renderHtml() {
|
|
|
9555
9663
|
</select>
|
|
9556
9664
|
</label>
|
|
9557
9665
|
</div>
|
|
9558
|
-
<div class="small">\u672A\u7ED1\u5B9A\u7684 IM \u804A\u5929\u4F1A\u5148\u8FDB\u5165\u4E34\u65F6\u8349\u7A3F\u7EBF\u7A0B\uFF08\u7B49\u540C <code>/t 0</code>\uFF09\uFF1B\u201C\u9ED8\u8BA4\u5DE5\u4F5C\u7A7A\u95F4\u201D\u53EA\u7528\u4E8E <code>/new proj1</code> \u8FD9\u7C7B\u76F8\u5BF9\u9879\u76EE\u540D\u3002\u7559\u7A7A\u65F6\u4F1A\u6309\u5F53\u524D\u7CFB\u7EDF\u81EA\u52A8\u56DE\u9000\u5230 <code>~/cx2im</code>\u3002\u9ED8\u8BA4\u6A21\u578B\u5019\u9009\u9879\u6765\u81EA\u542F\u52A8\u65F6\u8BFB\u53D6\u7684 Codex \u6A21\u578B\u7F13\u5B58\uFF1A\u9690\u85CF\u6A21\u578B\u4E0D\u4F1A\u5C55\u793A\uFF0CCLI only \u6A21\u578B\u4F1A\u6807\u6210\u201C\u4EC5 IM / CLI\u201D\u3002\u7559\u7A7A\u5219\u7EE7\u7EED\u8DDF\u968F Codex \u5F53\u524D\u9ED8\u8BA4\u6A21\u578B\u3002\u6587\u4EF6\u7CFB\u7EDF\u6743\u9650\u662F\u5168\u5C40\u9ED8\u8BA4\u503C\uFF0C\u601D\u8003\u7EA7\u522B\u53EF\u5728 IM \u4F1A\u8BDD\u91CC\u518D\u5355\u72EC\u8986\u76D6\u3002\
|
|
9559
|
-
<div class="small">\u5F53\u524D\u9700\u8981\u91CD\u542F Bridge \u7684\u914D\u7F6E\uFF1A<code>Runtime</code>\u3001<code>\
|
|
9560
|
-
<div class="checkbox-row">
|
|
9561
|
-
<label class="checkbox"><input id="autoApprove" type="checkbox" /> \u81EA\u52A8\u6279\u51C6\u5DE5\u5177\u6743\u9650</label>
|
|
9562
|
-
</div>
|
|
9666
|
+
<div class="small">\u672A\u7ED1\u5B9A\u7684 IM \u804A\u5929\u4F1A\u5148\u8FDB\u5165\u4E34\u65F6\u8349\u7A3F\u7EBF\u7A0B\uFF08\u7B49\u540C <code>/t 0</code>\uFF09\uFF1B\u201C\u9ED8\u8BA4\u5DE5\u4F5C\u7A7A\u95F4\u201D\u53EA\u7528\u4E8E <code>/new proj1</code> \u8FD9\u7C7B\u76F8\u5BF9\u9879\u76EE\u540D\u3002\u7559\u7A7A\u65F6\u4F1A\u6309\u5F53\u524D\u7CFB\u7EDF\u81EA\u52A8\u56DE\u9000\u5230 <code>~/cx2im</code>\u3002\u9ED8\u8BA4\u6A21\u578B\u5019\u9009\u9879\u6765\u81EA\u542F\u52A8\u65F6\u8BFB\u53D6\u7684 Codex \u6A21\u578B\u7F13\u5B58\uFF1A\u9690\u85CF\u6A21\u578B\u4E0D\u4F1A\u5C55\u793A\uFF0CCLI only \u6A21\u578B\u4F1A\u6807\u6210\u201C\u4EC5 IM / CLI\u201D\u3002\u7559\u7A7A\u5219\u7EE7\u7EED\u8DDF\u968F Codex \u5F53\u524D\u9ED8\u8BA4\u6A21\u578B\u3002\u6587\u4EF6\u7CFB\u7EDF\u6743\u9650\u662F\u5168\u5C40\u9ED8\u8BA4\u503C\uFF0C\u601D\u8003\u7EA7\u522B\u53EF\u5728 IM \u4F1A\u8BDD\u91CC\u518D\u5355\u72EC\u8986\u76D6\u3002\u4E0A\u6B21\u54CD\u5E94\u8DDD\u4ECA\u914D\u7F6E\u53EA\u5F71\u54CD\u98DE\u4E66\u957F\u4EFB\u52A1\u5E95\u90E8\u201C\u4E0A\u6B21\u54CD\u5E94\u8DDD\u4ECA X\u201D\u7684\u51FA\u73B0\u65F6\u673A\u3002</div>
|
|
9667
|
+
<div class="small">\u5F53\u524D\u9700\u8981\u91CD\u542F Bridge \u7684\u914D\u7F6E\uFF1A<code>Runtime</code>\u3001<code>\u5141\u8BB8\u5728\u672A\u4FE1\u4EFB Git \u76EE\u5F55\u8FD0\u884C Codex</code>\u3002\u901A\u9053\u5B9E\u4F8B\u7684\u63A5\u5165\u914D\u7F6E\u8BF7\u5728\u201C\u901A\u9053\u201D\u9875\u7EF4\u62A4\u3002</div>
|
|
9563
9668
|
<div class="checkbox-row">
|
|
9564
9669
|
<label class="checkbox"><input id="codexSkipGitRepoCheck" type="checkbox" checked /> \u5141\u8BB8\u5728\u672A\u4FE1\u4EFB Git \u76EE\u5F55\u8FD0\u884C Codex</label>
|
|
9565
9670
|
</div>
|
|
@@ -9884,7 +9989,6 @@ function renderHtml() {
|
|
|
9884
9989
|
codexReasoningEffort: document.getElementById('codexReasoningEffort').value,
|
|
9885
9990
|
uiAllowLan: document.getElementById('uiAllowLan').checked,
|
|
9886
9991
|
uiAccessToken: document.getElementById('uiAccessToken').value,
|
|
9887
|
-
autoApprove: document.getElementById('autoApprove').checked,
|
|
9888
9992
|
};
|
|
9889
9993
|
}
|
|
9890
9994
|
|
|
@@ -10054,20 +10158,18 @@ function renderHtml() {
|
|
|
10054
10158
|
defaultModel: '\u9ED8\u8BA4\u6A21\u578B',
|
|
10055
10159
|
defaultMode: '\u9ED8\u8BA4\u6A21\u5F0F',
|
|
10056
10160
|
historyMessageLimit: '/history \u8FD4\u56DE\u6761\u6570',
|
|
10057
|
-
streamStatusIdleStartSeconds: '\
|
|
10058
|
-
streamStatusCheckIntervalSeconds: '\
|
|
10161
|
+
streamStatusIdleStartSeconds: '\u4E0A\u6B21\u54CD\u5E94\u8DDD\u4ECA\u663E\u793A\u542F\u52A8\u65F6\u957F',
|
|
10162
|
+
streamStatusCheckIntervalSeconds: '\u4E0A\u6B21\u54CD\u5E94\u8DDD\u4ECA\u68C0\u67E5\u95F4\u9694',
|
|
10059
10163
|
codexSkipGitRepoCheck: '\u5141\u8BB8\u5728\u672A\u4FE1\u4EFB Git \u76EE\u5F55\u8FD0\u884C Codex',
|
|
10060
10164
|
codexSandboxMode: 'Codex \u6587\u4EF6\u7CFB\u7EDF\u6743\u9650',
|
|
10061
10165
|
codexReasoningEffort: 'Codex \u601D\u8003\u7EA7\u522B',
|
|
10062
10166
|
uiAllowLan: '\u5141\u8BB8\u5C40\u57DF\u7F51\u8BBF\u95EE Web \u63A7\u5236\u53F0',
|
|
10063
10167
|
uiAccessToken: '\u5C40\u57DF\u7F51\u8BBF\u95EE token',
|
|
10064
|
-
autoApprove: '\u81EA\u52A8\u6279\u51C6\u5DE5\u5177\u6743\u9650',
|
|
10065
10168
|
};
|
|
10066
10169
|
|
|
10067
10170
|
const BRIDGE_RESTART_FIELDS = new Set([
|
|
10068
10171
|
'runtime',
|
|
10069
10172
|
'codexSkipGitRepoCheck',
|
|
10070
|
-
'autoApprove',
|
|
10071
10173
|
]);
|
|
10072
10174
|
|
|
10073
10175
|
const AUTO_SYNC_FIELDS = new Set([]);
|
|
@@ -10659,7 +10761,6 @@ function renderHtml() {
|
|
|
10659
10761
|
document.getElementById('codexReasoningEffort').value = config.codexReasoningEffort || 'medium';
|
|
10660
10762
|
document.getElementById('uiAllowLan').checked = config.uiAllowLan === true;
|
|
10661
10763
|
document.getElementById('uiAccessToken').value = config.uiAccessToken || '';
|
|
10662
|
-
document.getElementById('autoApprove').checked = config.autoApprove === true;
|
|
10663
10764
|
renderUiAccess();
|
|
10664
10765
|
ensureActiveChannelId();
|
|
10665
10766
|
renderChannelsWorkspace();
|