Files
codex-market-app/electron/lib/codex_data_dir.js
T

95 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// codex_data_dir.js —— 会话相关功能使用的 Codex 数据目录,可由用户覆盖默认 ~/.codex。
const { app } = require("electron");
const fs = require("fs");
const os = require("os");
const path = require("path");
const DEFAULT_DIR = path.join(os.homedir(), ".codex");
let loaded = false;
let configuredDir = null;
function configFile() {
return path.join(app.getPath("userData"), "codex-data-dir.json");
}
function normalize(dir) {
if (typeof dir !== "string" || !dir.trim() || !path.isAbsolute(dir.trim())) return null;
return path.resolve(dir.trim());
}
function load() {
if (loaded) return;
loaded = true;
try {
configuredDir = normalize(JSON.parse(fs.readFileSync(configFile(), "utf-8")).path);
} catch {}
}
function get() {
load();
return configuredDir || DEFAULT_DIR;
}
function isCodexDataDir(dir) {
try {
const names = fs.readdirSync(dir);
return names.includes("sessions") || names.includes("archived_sessions") || names.includes("config.toml") ||
names.includes("auth.json") || names.some((name) => /^state_.*\.sqlite(?:-(?:wal|shm))?$/.test(name));
} catch {
return false;
}
}
function isDirectory(dir) {
try {
return fs.statSync(dir).isDirectory();
} catch {
return false;
}
}
function writeAtomic(file, text) {
fs.mkdirSync(path.dirname(file), { recursive: true });
const tmp = file + ".tmp-" + process.pid + "-" + Date.now();
const fd = fs.openSync(tmp, "w", 0o600);
try {
fs.writeFileSync(fd, text, "utf-8");
fs.fsyncSync(fd);
} finally {
fs.closeSync(fd);
}
try {
fs.renameSync(tmp, file);
} finally {
try { fs.rmSync(tmp, { force: true }); } catch {}
}
}
function set(dir) {
const next = normalize(dir);
if (!next || !isDirectory(next)) {
throw new Error("请选择存在的 Codex 数据目录");
}
if (!isCodexDataDir(next)) {
throw new Error("所选目录未找到 Codex 数据(sessions、config.toml 或 state_*.sqlite)");
}
configuredDir = next === DEFAULT_DIR ? null : next;
loaded = true;
writeAtomic(configFile(), JSON.stringify({ path: configuredDir || "", updatedAt: new Date().toISOString() }, null, 2));
return info();
}
function reset() {
configuredDir = null;
loaded = true;
writeAtomic(configFile(), JSON.stringify({ path: "", updatedAt: new Date().toISOString() }, null, 2));
return info();
}
function info() {
const dir = get();
return { path: dir, isDefault: dir === DEFAULT_DIR, exists: isDirectory(dir) };
}
module.exports = { get, set, reset, info, isCodexDataDir };