mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
配置统一:权限策略、硬防御、Tool Search、提示词封面以及新迁入的 RTK、pi-compaction、pi-worktree、pi-hermes-memory 配置全部由扩展 直接读取已安装组合包内的 config/,pi install / pi update 即完成部署; 删除 rebuild-bundle-config.mjs 与 bundle-manifest.json,my-pi/ 只保留 日志与缓存。update.sh 成功升级后将默认 git 来源的已安装副本 reset 回发布版本。AGENTS.md 新增「组合包配置原则」。 脚本整合:search_config.sh / ssh_config.sh 合并为 configure.sh search|ssh;install.sh / update.sh 共享函数抽到 scripts/lib.sh,远程 安装器改为先下载到临时文件再执行,下载失败可被检测。 权限:hard-guards 新增 protectedWrites,写入 Pi 凭据/设置、已安装 组合包与扩展目录、pi-ssh 凭据库时一律人工确认(跳过 AutoReview、 yolo 与 Session grant,无 UI 时拒绝);放行 ls、LSP 查询、ctx 只读、 web_search、Chrome 只读与 git 只读命令,skill_manage 改为 ask。 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
96 lines
3.7 KiB
TypeScript
96 lines
3.7 KiB
TypeScript
import { readFile } from "node:fs/promises";
|
|
import { fileURLToPath } from "node:url";
|
|
import type { PiCompactionConfig } from "./types.js";
|
|
|
|
// Bundle-level `config/` is the single source of truth: the extension reads
|
|
// `config/pi-compaction.json` from inside the installed bundle (resolved
|
|
// relative to this source file). It never reads `settings.json` and never
|
|
// writes config at runtime.
|
|
export const CONFIG_PATH = fileURLToPath(
|
|
new URL("../../config/pi-compaction.json", import.meta.url),
|
|
);
|
|
|
|
export const DEFAULT_CONFIG: PiCompactionConfig = {
|
|
enabled: true,
|
|
softRatio: 0.72,
|
|
hardRatio: 0.9,
|
|
targetRatio: 0.55,
|
|
deterministic: {
|
|
enabled: true,
|
|
maxStubTokens: 1_024,
|
|
},
|
|
semantic: {
|
|
enabled: true,
|
|
model: "default",
|
|
thinking: "low",
|
|
concurrency: 1,
|
|
minInputChars: 4_000,
|
|
maxInputChars: 24_000,
|
|
maxRetries: 2,
|
|
},
|
|
native: {
|
|
enabled: true,
|
|
},
|
|
};
|
|
|
|
function ratio(value: unknown, fallback: number): number {
|
|
return typeof value === "number" && Number.isFinite(value) && value > 0 && value < 1 ? value : fallback;
|
|
}
|
|
|
|
function integer(value: unknown, fallback: number, min = 0, max = Number.MAX_SAFE_INTEGER): number {
|
|
return typeof value === "number" && Number.isInteger(value) && value >= min && value <= max ? value : fallback;
|
|
}
|
|
|
|
function object(value: unknown): Record<string, unknown> {
|
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
? value as Record<string, unknown>
|
|
: {};
|
|
}
|
|
|
|
export function normalizeConfig(value: unknown): PiCompactionConfig {
|
|
const input = object(value);
|
|
const deterministic = object(input.deterministic);
|
|
const semantic = object(input.semantic);
|
|
const native = object(input.native);
|
|
const softRatio = ratio(input.softRatio, DEFAULT_CONFIG.softRatio);
|
|
const hardRatio = Math.max(softRatio + 0.01, ratio(input.hardRatio, DEFAULT_CONFIG.hardRatio));
|
|
const targetRatio = Math.min(softRatio - 0.01, ratio(input.targetRatio, DEFAULT_CONFIG.targetRatio));
|
|
const thinking = ["off", "minimal", "low", "medium", "high", "xhigh"].includes(String(semantic.thinking))
|
|
? semantic.thinking as PiCompactionConfig["semantic"]["thinking"]
|
|
: DEFAULT_CONFIG.semantic.thinking;
|
|
|
|
return {
|
|
enabled: typeof input.enabled === "boolean" ? input.enabled : DEFAULT_CONFIG.enabled,
|
|
softRatio,
|
|
hardRatio: Math.min(0.99, hardRatio),
|
|
targetRatio: Math.max(0.1, targetRatio),
|
|
deterministic: {
|
|
enabled: typeof deterministic.enabled === "boolean" ? deterministic.enabled : DEFAULT_CONFIG.deterministic.enabled,
|
|
maxStubTokens: integer(deterministic.maxStubTokens, DEFAULT_CONFIG.deterministic.maxStubTokens, 32, 4_096),
|
|
},
|
|
semantic: {
|
|
enabled: typeof semantic.enabled === "boolean" ? semantic.enabled : DEFAULT_CONFIG.semantic.enabled,
|
|
model: typeof semantic.model === "string" && semantic.model.trim() ? semantic.model.trim() : DEFAULT_CONFIG.semantic.model,
|
|
thinking,
|
|
concurrency: integer(semantic.concurrency, DEFAULT_CONFIG.semantic.concurrency, 1, 4),
|
|
minInputChars: integer(semantic.minInputChars, DEFAULT_CONFIG.semantic.minInputChars, 0, 1_000_000),
|
|
maxInputChars: integer(semantic.maxInputChars, DEFAULT_CONFIG.semantic.maxInputChars, 1_000, 1_000_000),
|
|
maxRetries: integer(semantic.maxRetries, DEFAULT_CONFIG.semantic.maxRetries, 0, 5),
|
|
},
|
|
native: {
|
|
enabled: typeof native.enabled === "boolean" ? native.enabled : DEFAULT_CONFIG.native.enabled,
|
|
},
|
|
};
|
|
}
|
|
|
|
export async function loadConfig(
|
|
configPath: string = CONFIG_PATH,
|
|
): Promise<PiCompactionConfig> {
|
|
try {
|
|
const parsed = JSON.parse(await readFile(configPath, "utf8"));
|
|
return normalizeConfig(parsed);
|
|
} catch {
|
|
return structuredClone(DEFAULT_CONFIG);
|
|
}
|
|
}
|