@lmzhen/dsh-evolution-core 0.1.0-rc.50 → 0.1.0-rc.52

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 CHANGED
@@ -2,14 +2,12 @@ import { basename, dirname, join } from "node:path";
2
2
  import { cp, lstat, mkdir, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
3
3
  import { createHash, randomBytes } from "node:crypto";
4
4
  import { homedir } from "node:os";
5
- import { readFileSync } from "node:fs";
6
5
  //#region lib/types/io.js
7
6
  /**
8
- * Structural IO seam for the legacy facade stores.
7
+ * Structural IO seam for the evolution plugin family.
9
8
  *
10
- * The facade accepts any object exposing this small async file-tree surface.
11
- * Native DSH packages pass `ctx.evolutionIo.provider()`; standalone consumers
12
- * (and the facade's own tests) can use `nodeEvolutionIo`.
9
+ * Every evolution package passes `ctx.evolutionIo.provider()`; standalone
10
+ * consumers (and the core's own tests) can use `nodeEvolutionIo`.
13
11
  */
14
12
  /**
15
13
  * Run `task` inside `io.transact` when the backend provides it; otherwise fall
@@ -1326,84 +1324,6 @@ var MemoryStore = class {
1326
1324
  limit: this.limitFor(target)
1327
1325
  };
1328
1326
  }
1329
- async replace(target, oldText, facts) {
1330
- return this.mutate(target, oldText, "replace", facts);
1331
- }
1332
- async remove(target, oldText) {
1333
- return this.mutate(target, oldText, "remove", void 0);
1334
- }
1335
- async mutate(target, oldText, action, facts) {
1336
- const needle = oldText.trim();
1337
- if (!needle) {
1338
- const current = await this.read(target);
1339
- return {
1340
- ok: false,
1341
- message: `old_text cannot be empty.${previewEntries(current)}`,
1342
- entries: current,
1343
- chars: current.join(ENTRY_DELIMITER).length,
1344
- limit: this.limitFor(target)
1345
- };
1346
- }
1347
- const refusal = await this.oversizedRefusal(target);
1348
- if (refusal) return refusal;
1349
- const content = action === "replace" ? (facts ?? "").trim() : "";
1350
- if (action === "replace" && !content) return {
1351
- ok: false,
1352
- message: "facts is required for replace; use remove to delete.",
1353
- entries: [],
1354
- chars: 0,
1355
- limit: this.limitFor(target)
1356
- };
1357
- if (action === "replace") {
1358
- const threat = scanMemoryThreats(content);
1359
- if (threat) return {
1360
- ok: false,
1361
- message: threat,
1362
- entries: [],
1363
- chars: 0,
1364
- limit: this.limitFor(target)
1365
- };
1366
- }
1367
- if (await this.detectDrift(target)) {
1368
- const backup = await this.backupFile(target);
1369
- return {
1370
- ok: false,
1371
- message: `External drift detected in memory file.${backup ? ` A backup was saved to ${basename(backup)}.` : ""} Resolve the drift before retrying.`,
1372
- entries: [],
1373
- chars: 0,
1374
- limit: this.limitFor(target)
1375
- };
1376
- }
1377
- const entries = await this.read(target);
1378
- const matches = entries.map((entry, index) => ({
1379
- entry,
1380
- index
1381
- })).filter(({ entry }) => entry.includes(needle));
1382
- if (matches.length === 0) return this.failure(target, `No entry matching "${needle}" found.`, entries);
1383
- if (new Set(matches.map((m) => m.entry)).size > 1) return {
1384
- ok: false,
1385
- message: `Multiple distinct entries matched "${needle}". Be more specific.`,
1386
- entries,
1387
- chars: entries.join(ENTRY_DELIMITER).length,
1388
- limit: this.limitFor(target)
1389
- };
1390
- const index = matches[0]?.index ?? -1;
1391
- const next = [...entries];
1392
- if (action === "remove") next.splice(index, 1);
1393
- else next[index] = content;
1394
- const total = next.join(ENTRY_DELIMITER).length;
1395
- const mutateLimit = this.limitFor(target);
1396
- if (mutateLimit > 0 && total > mutateLimit) return this.failure(target, `Resulting memory would exceed the ${mutateLimit} char limit.`, entries);
1397
- await this.write(target, next);
1398
- this.resetFailures();
1399
- return {
1400
- ok: true,
1401
- message: `Entry ${action === "remove" ? "removed" : "replaced"}.${this.storageHint(target, total)}`,
1402
- entries: next,
1403
- chars: total,
1404
- limit: this.limitFor(target)
1405
- };
1406
- }
1407
1327
  async applyBatch(target, operations) {
1408
1328
  if (operations.length === 0) return {
1409
1329
  ok: false,
@@ -2796,67 +2716,11 @@ var SkillLibrary = class {
2796
2716
  //#endregion
2797
2717
  //#region lib/types/state-store.js
2798
2718
  /**
2799
- * Small crash-safe JSON state store for plugin-owned sidecar state.
2800
- * Writes are atomic (temp + rename). Reads are synchronous for startup use.
2719
+ * Evolution home path helper: `$DSH_HOME/evolution` for plugin-owned sidecar
2720
+ * state (reports, activity store, feedback file, state-domain data).
2801
2721
  */
2802
2722
  function evolutionHome(env = process.env) {
2803
2723
  return join(env.DSH_HOME ?? join(homedir(), ".dsh"), "evolution");
2804
2724
  }
2805
- var JsonState = class JsonState {
2806
- initial;
2807
- path;
2808
- value;
2809
- constructor(name, initial, env = process.env) {
2810
- this.initial = initial;
2811
- this.path = join(evolutionHome(env), name);
2812
- this.value = this.loadSync();
2813
- }
2814
- /**
2815
- * Deep-merge persisted state over the initial defaults. Nested plain
2816
- * objects merge recursively (so a new default field added under an existing
2817
- * object is preserved), while arrays and primitives take the on-disk value
2818
- * wholesale. Keeps forward-compatible defaults across schema additions.
2819
- */
2820
- static mergeDeep(initial, persisted) {
2821
- const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
2822
- if (!isRecord(initial) || !isRecord(persisted)) return isRecord(persisted) ? persisted : persisted == null ? initial : persisted;
2823
- const out = { ...initial };
2824
- for (const [key, value] of Object.entries(persisted)) out[key] = key in initial ? JsonState.mergeDeep(initial[key], value) : value;
2825
- return out;
2826
- }
2827
- loadSync() {
2828
- try {
2829
- const raw = readFileSync(this.path, "utf8");
2830
- const parsed = JSON.parse(raw);
2831
- return JsonState.mergeDeep(this.initial, parsed);
2832
- } catch {
2833
- return { ...this.initial };
2834
- }
2835
- }
2836
- get() {
2837
- return this.value;
2838
- }
2839
- set(value) {
2840
- this.value = value;
2841
- }
2842
- update(mutator) {
2843
- mutator(this.value);
2844
- }
2845
- async flush() {
2846
- await mkdir(dirname(this.path), { recursive: true });
2847
- const tmp = `${this.path}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
2848
- await writeFile(tmp, JSON.stringify(this.value, null, 2), "utf8");
2849
- await rename(tmp, this.path);
2850
- }
2851
- /** Merge-on-load helper for persisted maps/records. */
2852
- async reload() {
2853
- try {
2854
- const raw = await readFile(this.path, "utf8");
2855
- this.value = JsonState.mergeDeep(this.initial, JSON.parse(raw));
2856
- } catch {
2857
- this.value = { ...this.initial };
2858
- }
2859
- }
2860
- };
2861
2725
  //#endregion
2862
- export { COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_USER_CHAR_LIMIT, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EvolutionGateSet, JsonState, LOW_QUALITY_THRESHOLD, MAX_DESCRIPTION_LENGTH, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MEMORY_REVIEW_PROMPT, MUTATIONS_FILE_VERSION, MemoryStore, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, QUALITY_WEIGHTS, SKILL_NAME_RE, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, advanceReview, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpUse, bumpView, computeDedupGroups, computeLifecycleTransitions, computeQualityScores, computeScopeView, contentHash, createGateSet, emptyRecord, evaluateThreat, evolutionHome, evolutionIoAdapter, foldTurn, getRecord, latestActivityAt, lifecycleCandidate, loadMutations, loadSuppressedNames, loadUsage, markAgentCreated, memoryRoot, mutateUsage, mutationsFile, nodeEvolutionIo, normalizeUsageRecord, observeEvent, parseCuratorNominations, parseFrontmatter, recordMutation, relatedSkillNames, renderCuratorReportMarkdown, resolveOrigins, reviewPrompt, saveSuppressedNames, saveUsage, scanContentThreats, scanMemoryThreats, scanThreats, skillsRoot, suppressedFile, transactIo, updateSuppressedNames, usageFile, validateFrontmatter, verifyPromptBundle };
2726
+ export { COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_USER_CHAR_LIMIT, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EvolutionGateSet, LOW_QUALITY_THRESHOLD, MAX_DESCRIPTION_LENGTH, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MEMORY_REVIEW_PROMPT, MUTATIONS_FILE_VERSION, MemoryStore, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, QUALITY_WEIGHTS, SKILL_NAME_RE, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, advanceReview, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpUse, bumpView, computeDedupGroups, computeLifecycleTransitions, computeQualityScores, computeScopeView, contentHash, createGateSet, emptyRecord, evaluateThreat, evolutionHome, evolutionIoAdapter, foldTurn, getRecord, latestActivityAt, lifecycleCandidate, loadMutations, loadSuppressedNames, loadUsage, markAgentCreated, memoryRoot, mutateUsage, mutationsFile, nodeEvolutionIo, normalizeUsageRecord, observeEvent, parseCuratorNominations, parseFrontmatter, recordMutation, relatedSkillNames, renderCuratorReportMarkdown, resolveOrigins, reviewPrompt, saveSuppressedNames, saveUsage, scanContentThreats, scanMemoryThreats, scanThreats, skillsRoot, suppressedFile, transactIo, updateSuppressedNames, usageFile, validateFrontmatter, verifyPromptBundle };
package/lib/types/io.d.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  /**
2
- * Structural IO seam for the legacy facade stores.
2
+ * Structural IO seam for the evolution plugin family.
3
3
  *
4
- * The facade accepts any object exposing this small async file-tree surface.
5
- * Native DSH packages pass `ctx.evolutionIo.provider()`; standalone consumers
6
- * (and the facade's own tests) can use `nodeEvolutionIo`.
4
+ * Every evolution package passes `ctx.evolutionIo.provider()`; standalone
5
+ * consumers (and the core's own tests) can use `nodeEvolutionIo`.
7
6
  */
8
7
  export interface EvolutionIoLike {
9
8
  readText(path: string): Promise<string | null>;
@@ -72,9 +72,6 @@ export declare class MemoryStore {
72
72
  */
73
73
  private oversizedRefusal;
74
74
  add(target: MemoryTarget, facts: string): Promise<MemoryApplyResult>;
75
- replace(target: MemoryTarget, oldText: string, facts: string): Promise<MemoryApplyResult>;
76
- remove(target: MemoryTarget, oldText: string): Promise<MemoryApplyResult>;
77
- private mutate;
78
75
  applyBatch(target: MemoryTarget, operations: MemoryOperation[]): Promise<MemoryApplyResult>;
79
76
  renderContext(): Promise<string>;
80
77
  /**
@@ -1,26 +1,6 @@
1
1
  /**
2
- * Small crash-safe JSON state store for plugin-owned sidecar state.
3
- * Writes are atomic (temp + rename). Reads are synchronous for startup use.
2
+ * Evolution home path helper: `$DSH_HOME/evolution` for plugin-owned sidecar
3
+ * state (reports, activity store, feedback file, state-domain data).
4
4
  */
5
5
  export declare function evolutionHome(env?: NodeJS.ProcessEnv): string;
6
- export declare class JsonState<T> {
7
- private readonly initial;
8
- readonly path: string;
9
- private value;
10
- constructor(name: string, initial: T, env?: NodeJS.ProcessEnv);
11
- /**
12
- * Deep-merge persisted state over the initial defaults. Nested plain
13
- * objects merge recursively (so a new default field added under an existing
14
- * object is preserved), while arrays and primitives take the on-disk value
15
- * wholesale. Keeps forward-compatible defaults across schema additions.
16
- */
17
- private static mergeDeep;
18
- private loadSync;
19
- get(): T;
20
- set(value: T): void;
21
- update(mutator: (value: T) => void): void;
22
- flush(): Promise<void>;
23
- /** Merge-on-load helper for persisted maps/records. */
24
- reload(): Promise<void>;
25
- }
26
6
  //# sourceMappingURL=state-store.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-core",
3
3
  "description": "Shared stores, prompts, signals and lifecycle logic for the dsh-evolution plugin family (community build)",
4
- "version": "0.1.0-rc.50",
4
+ "version": "0.1.0-rc.52",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },