添加注释
This commit is contained in:
@@ -18,6 +18,7 @@ const initializePromise = Promise.all([
|
|||||||
toolContextStore.initialize(),
|
toolContextStore.initialize(),
|
||||||
]);
|
]);
|
||||||
const SKILLS_ROOT_DIR = ".opencode/skills";
|
const SKILLS_ROOT_DIR = ".opencode/skills";
|
||||||
|
// learned skill 与正式技能树同路径组织,但历史版本单独落到 data/history/skills 下。
|
||||||
const SKILLS_HISTORY_DIR = join(config.PERSISTENCE_HISTORY_DIR, "skills");
|
const SKILLS_HISTORY_DIR = join(config.PERSISTENCE_HISTORY_DIR, "skills");
|
||||||
const LEARNED_PATTERNS_MARKER = "## Learned Patterns";
|
const LEARNED_PATTERNS_MARKER = "## Learned Patterns";
|
||||||
let writeQueue: Promise<void> = Promise.resolve();
|
let writeQueue: Promise<void> = Promise.resolve();
|
||||||
@@ -120,6 +121,7 @@ const appendLearnedSkillPattern = async (skillPath: string, pattern: string) =>
|
|||||||
: `${current.trimEnd()}\n\n${LEARNED_PATTERNS_MARKER}\n- ${pattern}\n`;
|
: `${current.trimEnd()}\n\n${LEARNED_PATTERNS_MARKER}\n- ${pattern}\n`;
|
||||||
|
|
||||||
await ensureDirectory(join(SKILLS_ROOT_DIR, skillPath));
|
await ensureDirectory(join(SKILLS_ROOT_DIR, skillPath));
|
||||||
|
// 追加 learned pattern 前先备份旧版 SKILL.md,避免共享技能被异常写坏。
|
||||||
await atomicWriteFileWithHistory(target, next, {
|
await atomicWriteFileWithHistory(target, next, {
|
||||||
historyDir: SKILLS_HISTORY_DIR,
|
historyDir: SKILLS_HISTORY_DIR,
|
||||||
rootDir: SKILLS_ROOT_DIR,
|
rootDir: SKILLS_ROOT_DIR,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const SUSPICIOUS_MEMORY_PATTERNS = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export class MemoryStore {
|
export class MemoryStore {
|
||||||
|
// Memory 文件可能被多次连续追加,串行化可避免并发覆盖掉刚写入的条目。
|
||||||
private writeQueue: Promise<void> = Promise.resolve();
|
private writeQueue: Promise<void> = Promise.resolve();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -46,6 +47,7 @@ export class MemoryStore {
|
|||||||
await ensureDirectory(this.baseDir);
|
await ensureDirectory(this.baseDir);
|
||||||
await ensureDirectory(join(this.baseDir, "users"));
|
await ensureDirectory(join(this.baseDir, "users"));
|
||||||
await ensureDirectory(join(this.baseDir, "workspaces"));
|
await ensureDirectory(join(this.baseDir, "workspaces"));
|
||||||
|
// 历史备份与正式数据分目录存放,便于排查和手工恢复。
|
||||||
await ensureDirectory(this.historyDir);
|
await ensureDirectory(this.historyDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +66,7 @@ export class MemoryStore {
|
|||||||
|
|
||||||
const entry: MemoryEntry = { content };
|
const entry: MemoryEntry = { content };
|
||||||
entries.unshift(entry);
|
entries.unshift(entry);
|
||||||
|
// 每次覆盖 memory 文件前先保留上一版,写入失败时由底层工具恢复。
|
||||||
await atomicWriteFileWithHistory(
|
await atomicWriteFileWithHistory(
|
||||||
this.filePath(scope, key),
|
this.filePath(scope, key),
|
||||||
renderMemoryMarkdown(scope, entries),
|
renderMemoryMarkdown(scope, entries),
|
||||||
|
|||||||
@@ -36,12 +36,14 @@ export const atomicWriteFileWithHistory = async (
|
|||||||
|
|
||||||
let backupPath: string | null = null;
|
let backupPath: string | null = null;
|
||||||
if (previous !== null) {
|
if (previous !== null) {
|
||||||
|
// 仅在覆盖已有文件时保留历史版本,避免为首次创建产生空备份。
|
||||||
backupPath = buildHistoryBackupPath(path, options);
|
backupPath = buildHistoryBackupPath(path, options);
|
||||||
await atomicWriteFile(backupPath, previous);
|
await atomicWriteFile(backupPath, previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await atomicWriteFile(path, content);
|
await atomicWriteFile(path, content);
|
||||||
|
// 给调用方预留一个写后钩子;若后续步骤失败,这里仍会回滚到旧内容。
|
||||||
await options.afterWrite?.();
|
await options.afterWrite?.();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
try {
|
try {
|
||||||
@@ -158,6 +160,7 @@ const buildHistoryBackupPath = (path: string, options: HistoricalWriteOptions) =
|
|||||||
const relativePath = relative(options.rootDir, path);
|
const relativePath = relative(options.rootDir, path);
|
||||||
const scopedPath =
|
const scopedPath =
|
||||||
relativePath && !relativePath.startsWith("..") ? relativePath : basename(path);
|
relativePath && !relativePath.startsWith("..") ? relativePath : basename(path);
|
||||||
|
// 备份目录尽量复用原始相对路径,便于按业务目录回看历史。
|
||||||
const backupName = `${basename(path)}.${Date.now().toString(36)}.bak`;
|
const backupName = `${basename(path)}.${Date.now().toString(36)}.bak`;
|
||||||
return join(options.historyDir, dirname(scopedPath), backupName);
|
return join(options.historyDir, dirname(scopedPath), backupName);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user