bookworm-smart-assistant/scripts/user-overrides.js

171 lines
4.7 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.

#!/usr/bin/env node
/**
* 逃生舱状态管理 (Phase 0)
*
* 管理 /force, /checks, /reset 用户覆盖。
*
* 状态文件: debug/user-overrides.json
* 自动过期: 1 小时(匹配 session-memory.js MAX_SESSION_AGE
* /force: 单次生效compliance-gate 放行后自动清除)
* /checks off: 会话级(手动 /checks on 或 /reset 或过期后恢复)
*/
const fs = require('fs');
const path = require('path');
// 路径解析
let overridesPath, debugDir;
try {
const { PATHS } = require('./paths.config.js');
overridesPath = PATHS.userOverridesJson;
debugDir = PATHS.debugDir;
} catch {
const root = path.resolve(__dirname, '..');
debugDir = path.join(root, 'debug');
overridesPath = path.join(debugDir, 'user-overrides.json');
}
const MAX_AGE_MS = 60 * 60 * 1000; // 1 小时
// ─── 内部辅助 ─────────────────────────────────────────
function ensureDir() {
try {
if (!fs.existsSync(debugDir)) fs.mkdirSync(debugDir, { recursive: true });
} catch {}
}
/**
* 读取覆盖状态(检查过期)
* @returns {Object} overrides 状态
*/
function readState() {
try {
if (!fs.existsSync(overridesPath)) return null;
const raw = fs.readFileSync(overridesPath, 'utf8');
const state = JSON.parse(raw);
// 检查过期
if (state.expiresAt && new Date(state.expiresAt).getTime() < Date.now()) {
// 过期 → 清除文件
try { fs.unlinkSync(overridesPath); } catch {}
return null;
}
return state;
} catch {
return null;
}
}
/**
* 写入覆盖状态
* @param {Object} overrides - { force, checksOff, forceSkill }
*/
function writeState(overrides) {
ensureDir();
const now = new Date();
const state = {
createdAt: now.toISOString(),
expiresAt: new Date(now.getTime() + MAX_AGE_MS).toISOString(),
overrides: {
force: overrides.force || false,
checksOff: overrides.checksOff || false,
forceSkill: overrides.forceSkill || null,
},
};
fs.writeFileSync(overridesPath, JSON.stringify(state, null, 2) + '\n');
}
// ─── 公开 API ─────────────────────────────────────────
/**
* 设置 force 模式(单次生效)
* @param {string} [skillName] - 可选指定技能
*/
function setForce(skillName) {
const current = readState();
const overrides = current ? current.overrides : { force: false, checksOff: false, forceSkill: null };
overrides.force = true;
overrides.forceSkill = skillName || null;
writeState(overrides);
}
/**
* 设置 checks 开关
* @param {boolean} enabled - true=开启检查, false=关闭检查
*/
function setChecks(enabled) {
const current = readState();
const overrides = current ? current.overrides : { force: false, checksOff: false, forceSkill: null };
overrides.checksOff = !enabled;
writeState(overrides);
}
/**
* 重置所有覆盖
*/
function resetAll() {
try {
if (fs.existsSync(overridesPath)) fs.unlinkSync(overridesPath);
} catch {}
}
/**
* 检查 force 是否激活
* @returns {{ active: boolean, skill?: string }}
*/
function isForceActive() {
const state = readState();
if (!state || !state.overrides || !state.overrides.force) {
return { active: false };
}
return { active: true, skill: state.overrides.forceSkill || undefined };
}
/**
* 检查 checks 是否被关闭
* @returns {boolean}
*/
function isChecksDisabled() {
const state = readState();
if (!state || !state.overrides) return false;
return state.overrides.checksOff === true;
}
/**
* 清除 force 标志compliance-gate 放行后调用)
*/
function clearForce() {
const state = readState();
if (!state || !state.overrides) return;
state.overrides.force = false;
state.overrides.forceSkill = null;
writeState(state.overrides);
}
// ─── 导出 ─────────────────────────────────────────────
module.exports = {
setForce,
setChecks,
resetAll,
isForceActive,
isChecksDisabled,
clearForce,
};
// CLI: 直接运行时打印当前状态
if (require.main === module) {
const state = readState();
console.log('=== User Overrides ===');
console.log(`Path: ${overridesPath}`);
if (!state) {
console.log('Status: No active overrides');
} else {
console.log(`Created: ${state.createdAt}`);
console.log(`Expires: ${state.expiresAt}`);
console.log(`Force: ${state.overrides.force ? 'ON' + (state.overrides.forceSkill ? ` (${state.overrides.forceSkill})` : '') : 'OFF'}`);
console.log(`Checks: ${state.overrides.checksOff ? 'DISABLED' : 'ENABLED'}`);
}
}