UNPKG

@lark-project/cli

Version:

飞书项目插件开发工具

74 lines (73 loc) 3.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkLocalConfigDrift = exports.writeLocalConfigLastSet = void 0; const crypto_1 = require("crypto"); const fs_extra_1 = require("fs-extra"); const write_local_point_config_1 = require("./write-local-point-config"); const workspace_1 = require("../v2/utils/workspace"); // canonical hash 用于 drift 比较——JSON.stringify 不带 indent,规避 indent / 行尾差异。 // 不规范 key 顺序:用户手动调换 key 顺序也算"改了文件",提示是合理的。 function canonicalHash(raw) { return (0, crypto_1.createHash)('sha256').update(JSON.stringify(raw)).digest('hex'); } /** * `lpm local-config set` 成功后调用:从磁盘 point.config.local.json 读一次最终落盘内容、 * 算 canonical hash 写到 .lpm-cache/config/last-set.json,作为后续 drift 检测的基线。 * * **必须从磁盘读、不能传内存对象**:writeJSONSync 写磁盘时会过滤 undefined 字段, * 内存对象与磁盘读出来的 hash 可能不一致——若拿内存对象算 baseline,set 完 * 立刻跑 start 会误报 drift,反向训练 AI 忽略 stderr 信号。 * * 写入失败静默——drift 检查只是辅助信号,不能拖累 set 的主流程。 */ function writeLocalConfigLastSet() { try { const localPath = (0, write_local_point_config_1.getLocalConfigPath)(); if (!(0, fs_extra_1.existsSync)(localPath)) return; const parsed = JSON.parse((0, fs_extra_1.readFileSync)(localPath, 'utf8')); (0, workspace_1.ensureWorkspace)(); const paths = (0, workspace_1.workspacePaths)(); (0, fs_extra_1.writeJSONSync)(paths.configLastSet, { syncedAt: new Date().toISOString(), hash: canonicalHash(parsed), }, { spaces: 2 }); } catch (_a) { // intentional swallow } } exports.writeLocalConfigLastSet = writeLocalConfigLastSet; /** * Stage Config plan → apply 边界守护:检测 point.config.local.json 是否 * 在上次 `lpm local-config set` 之后被改动过、还没同步到 backend。 * * 触发条件:本地配置文件存在 + last-set sentinel 存在 + canonical hash 不匹配 * → 输出一行 stderr hint。**不阻断主流程**——挂在 start / build / diff 前 * 是为了把"agent 改完文件就停"的信号显式化,而非强制 gate。 * * 设计 fail-safe:所有 IO / parse 异常静默吞掉——drift 检查只是辅助提示, * 不能让它把 start / build / diff 弄挂。永不调 process.exit()。 */ function checkLocalConfigDrift() { try { const localPath = (0, write_local_point_config_1.getLocalConfigPath)(); if (!(0, fs_extra_1.existsSync)(localPath)) return; const paths = (0, workspace_1.workspacePaths)(); if (!(0, fs_extra_1.existsSync)(paths.configLastSet)) return; const current = JSON.parse((0, fs_extra_1.readFileSync)(localPath, 'utf8')); const sentinel = JSON.parse((0, fs_extra_1.readFileSync)(paths.configLastSet, 'utf8')); if (!(sentinel === null || sentinel === void 0 ? void 0 : sentinel.hash)) return; if (canonicalHash(current) === sentinel.hash) return; process.stderr.write('[hint] point.config.local.json 已修改但未同步到 backend。\n' + ' Run `lpm local-config set --from point.config.local.json` first.\n'); } catch (_a) { // intentional swallow — drift check is best-effort } } exports.checkLocalConfigDrift = checkLocalConfigDrift;