@lmzhen/dsh-evolution-core 0.3.56 → 0.3.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +55 -37
- package/lib/types/skill-store.d.ts +2 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -311,6 +311,10 @@ function nodeEvolutionIo(lockAttempts = 40) {
|
|
|
311
311
|
retryDelay: 100
|
|
312
312
|
}).catch(async () => {
|
|
313
313
|
const body = await readFile(lock, "utf8").catch(() => "");
|
|
314
|
+
if (pendingSelfCleanup.size >= 64) {
|
|
315
|
+
const oldest = pendingSelfCleanup.keys().next().value;
|
|
316
|
+
if (oldest !== void 0) pendingSelfCleanup.delete(oldest);
|
|
317
|
+
}
|
|
314
318
|
pendingSelfCleanup.set(lock, body);
|
|
315
319
|
});
|
|
316
320
|
}
|
|
@@ -428,7 +432,7 @@ function nodeEvolutionIo(lockAttempts = 40) {
|
|
|
428
432
|
},
|
|
429
433
|
async rename(path, destination) {
|
|
430
434
|
await mkdir(dirname(destination), { recursive: true });
|
|
431
|
-
await
|
|
435
|
+
await renameWithRetry(path, destination);
|
|
432
436
|
},
|
|
433
437
|
async copy(path, destination) {
|
|
434
438
|
await mkdir(dirname(destination), { recursive: true });
|
|
@@ -1207,8 +1211,8 @@ async function appendEvolutionEvent(io, path, event, rotateAt = EVENT_LOG_ROTATE
|
|
|
1207
1211
|
return current;
|
|
1208
1212
|
}
|
|
1209
1213
|
}
|
|
1210
|
-
const
|
|
1211
|
-
let maxSeq =
|
|
1214
|
+
const events = await rotateIfDue(io, path, v1EventRecords(parsedBody), rotateAt);
|
|
1215
|
+
let maxSeq = events.reduce((max, entry) => Math.max(max, entry.seq), 0);
|
|
1212
1216
|
if (maxSeq === 0) for (const name of await listEventArchives(io, path)) maxSeq = Math.max(maxSeq, Number.parseInt(name.slice(7, name.length - 5), 10));
|
|
1213
1217
|
const record = {
|
|
1214
1218
|
...event,
|
|
@@ -1218,7 +1222,7 @@ async function appendEvolutionEvent(io, path, event, rotateAt = EVENT_LOG_ROTATE
|
|
|
1218
1222
|
assigned = record.seq;
|
|
1219
1223
|
return JSON.stringify({
|
|
1220
1224
|
version: 1,
|
|
1221
|
-
events: [...
|
|
1225
|
+
events: [...events, record]
|
|
1222
1226
|
}, null, 2);
|
|
1223
1227
|
});
|
|
1224
1228
|
if (assigned === 0) throw new Error(`${refuseMessage || "evolution event log is malformed and was not touched"}: ${path}`);
|
|
@@ -3109,9 +3113,11 @@ function observeEvent(signal, event) {
|
|
|
3109
3113
|
return;
|
|
3110
3114
|
}
|
|
3111
3115
|
if (event.type === "tool/call") {
|
|
3116
|
+
const data = event.data;
|
|
3117
|
+
if (data === null || typeof data !== "object" || Array.isArray(data)) return;
|
|
3112
3118
|
signal.toolCalls += 1;
|
|
3113
|
-
|
|
3114
|
-
if (
|
|
3119
|
+
const name = data.name;
|
|
3120
|
+
if (name === "skill" || name === "skill_manage") signal.skillSignal = true;
|
|
3115
3121
|
}
|
|
3116
3122
|
}
|
|
3117
3123
|
/** Compute review cadence after `turn/end`. */
|
|
@@ -4145,6 +4151,9 @@ var SkillLibrary = class {
|
|
|
4145
4151
|
}
|
|
4146
4152
|
async create(name, content, origin = "foreground") {
|
|
4147
4153
|
const normalized = name.trim();
|
|
4154
|
+
return await this.serial(() => this.createCore(normalized, content, origin));
|
|
4155
|
+
}
|
|
4156
|
+
async createCore(normalized, content, origin) {
|
|
4148
4157
|
const bad = this.badName(normalized);
|
|
4149
4158
|
if (bad) return {
|
|
4150
4159
|
ok: false,
|
|
@@ -4882,9 +4891,10 @@ var SkillLibrary = class {
|
|
|
4882
4891
|
*/
|
|
4883
4892
|
async restoreFromArchive(rawName) {
|
|
4884
4893
|
const name = rawName.trim();
|
|
4885
|
-
|
|
4894
|
+
const bad = this.badName(name);
|
|
4895
|
+
if (bad) return {
|
|
4886
4896
|
ok: false,
|
|
4887
|
-
message:
|
|
4897
|
+
message: bad
|
|
4888
4898
|
};
|
|
4889
4899
|
if (await this.io.exists(join(this.dirOf(name), "SKILL.md"))) return {
|
|
4890
4900
|
ok: false,
|
|
@@ -5013,6 +5023,9 @@ var SkillLibrary = class {
|
|
|
5013
5023
|
}
|
|
5014
5024
|
async removeSupportFile(rawName, filePath, origin = "foreground") {
|
|
5015
5025
|
const name = rawName.trim();
|
|
5026
|
+
return await this.serial(() => this.removeSupportFileCore(name, filePath, origin));
|
|
5027
|
+
}
|
|
5028
|
+
async removeSupportFileCore(name, filePath, origin) {
|
|
5016
5029
|
const badName = this.badName(name);
|
|
5017
5030
|
if (badName) return {
|
|
5018
5031
|
ok: false,
|
|
@@ -5064,36 +5077,41 @@ var SkillLibrary = class {
|
|
|
5064
5077
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
5065
5078
|
let dest = join(backupRoot, `skills-${stamp}`);
|
|
5066
5079
|
while (await this.io.exists(dest)) dest = join(backupRoot, `skills-${stamp}-${Math.random().toString(36).slice(2, 8)}`);
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
await
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
const
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
await this.io.
|
|
5081
|
-
|
|
5080
|
+
try {
|
|
5081
|
+
const names = await listNames(this.root, this.io);
|
|
5082
|
+
await Promise.all(names.map(async (name) => {
|
|
5083
|
+
await this.io.copy(this.dirOf(name), join(dest, name));
|
|
5084
|
+
}));
|
|
5085
|
+
const sidecars = [];
|
|
5086
|
+
for (const sidecar of [usageFile(this.root), suppressedFile(this.root)]) if (await this.io.exists(sidecar)) {
|
|
5087
|
+
const name = basename(sidecar);
|
|
5088
|
+
await this.io.copy(sidecar, join(dest, name));
|
|
5089
|
+
sidecars.push(name);
|
|
5090
|
+
}
|
|
5091
|
+
const archiveRoot = join(this.root, ".archive");
|
|
5092
|
+
let hasArchive = false;
|
|
5093
|
+
if (await this.io.exists(archiveRoot)) {
|
|
5094
|
+
await this.io.copy(archiveRoot, join(dest, ".archive"));
|
|
5095
|
+
hasArchive = true;
|
|
5096
|
+
}
|
|
5097
|
+
const validExtras = extras.filter((extra) => SNAPSHOT_EXTRA_NAME_RE.test(extra.name));
|
|
5098
|
+
const extraNames = validExtras.map((extra) => extra.name);
|
|
5099
|
+
await Promise.all(validExtras.map(async (extra) => {
|
|
5100
|
+
await this.io.writeText(join(dest, "extras", extra.name), extra.content);
|
|
5101
|
+
}));
|
|
5102
|
+
await this.io.writeText(join(dest, "manifest.json"), JSON.stringify({
|
|
5103
|
+
reason,
|
|
5104
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5105
|
+
skills: names,
|
|
5106
|
+
sidecars,
|
|
5107
|
+
hasArchive,
|
|
5108
|
+
extras: extraNames
|
|
5109
|
+
}, null, 2));
|
|
5110
|
+
await this.retainSnapshots(5);
|
|
5111
|
+
} catch (error) {
|
|
5112
|
+
await this.io.remove(dest).catch(() => {});
|
|
5113
|
+
throw error;
|
|
5082
5114
|
}
|
|
5083
|
-
const validExtras = extras.filter((extra) => SNAPSHOT_EXTRA_NAME_RE.test(extra.name));
|
|
5084
|
-
const extraNames = validExtras.map((extra) => extra.name);
|
|
5085
|
-
await Promise.all(validExtras.map(async (extra) => {
|
|
5086
|
-
await this.io.writeText(join(dest, "extras", extra.name), extra.content);
|
|
5087
|
-
}));
|
|
5088
|
-
await this.io.writeText(join(dest, "manifest.json"), JSON.stringify({
|
|
5089
|
-
reason,
|
|
5090
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5091
|
-
skills: names,
|
|
5092
|
-
sidecars,
|
|
5093
|
-
hasArchive,
|
|
5094
|
-
extras: extraNames
|
|
5095
|
-
}, null, 2));
|
|
5096
|
-
await this.retainSnapshots(5);
|
|
5097
5115
|
return dest;
|
|
5098
5116
|
}
|
|
5099
5117
|
/** Read and normalize a snapshot manifest; null when the file is missing or unparsable. */
|
|
@@ -321,6 +321,7 @@ export declare class SkillLibrary {
|
|
|
321
321
|
*/
|
|
322
322
|
setPinned(name: string, pinned: boolean, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
323
323
|
create(name: string, content: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
324
|
+
private createCore;
|
|
324
325
|
update(rawName: string, content: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
325
326
|
private updateCore;
|
|
326
327
|
patch(rawName: string, oldString: string, newString: string, filePath?: string, replaceAll?: boolean, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
@@ -378,6 +379,7 @@ export declare class SkillLibrary {
|
|
|
378
379
|
writeSupportFile(rawName: string, filePath: string, content: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
379
380
|
private writeSupportFileCore;
|
|
380
381
|
removeSupportFile(rawName: string, filePath: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
382
|
+
private removeSupportFileCore;
|
|
381
383
|
/**
|
|
382
384
|
* Snapshot the recoverable skills state: active tree, usage/suppression
|
|
383
385
|
* sidecars, `.archive/` and caller-supplied extras. `extras` are opaque
|
package/package.json
CHANGED