@lmzhen/dsh-evolution-core 0.1.0-rc.40 → 0.1.0-rc.42

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
@@ -1662,7 +1662,7 @@ function validateSupportPath(filePath) {
1662
1662
  * so a patch can replace exactly the matched span and keep every other byte
1663
1663
  * intact. Returns null when no fuzzy match exists.
1664
1664
  */
1665
- function fuzzyIndexOf(content, pattern) {
1665
+ function fuzzyIndexOf(content, pattern, from = 0) {
1666
1666
  const isSpace = (char) => char !== void 0 && /[ \t]/.test(char);
1667
1667
  const escaped = (char) => {
1668
1668
  if (char === "n") return "\n";
@@ -1670,7 +1670,7 @@ function fuzzyIndexOf(content, pattern) {
1670
1670
  if (char === "r") return "\r";
1671
1671
  return null;
1672
1672
  };
1673
- for (let start = 0; start < content.length; start += 1) {
1673
+ for (let start = from; start < content.length; start += 1) {
1674
1674
  let contentIndex = start;
1675
1675
  let patternIndex = 0;
1676
1676
  while (patternIndex < pattern.length && contentIndex < content.length) {
@@ -1707,15 +1707,23 @@ function trimPatternBoundaries(pattern) {
1707
1707
  }
1708
1708
  /** Replace only the fuzzy-matched span, preserving all surrounding bytes. */
1709
1709
  function fuzzyReplace(content, oldString, newString, replaceAll) {
1710
- const match = fuzzyIndexOf(content, oldString);
1711
- if (match === null) return content;
1712
- const [start, end] = match;
1713
- const patched = content.slice(0, start) + newString + content.slice(end);
1714
- return replaceAll ? fuzzyReplace(patched, oldString, newString, true) : patched;
1710
+ let current = content;
1711
+ let scanFrom = 0;
1712
+ for (;;) {
1713
+ const match = fuzzyIndexOf(current, oldString, scanFrom);
1714
+ if (match === null) return current;
1715
+ const [start, end] = match;
1716
+ const next = current.slice(0, start) + newString + current.slice(end);
1717
+ if (!replaceAll) return next;
1718
+ current = next;
1719
+ scanFrom = start + newString.length;
1720
+ }
1715
1721
  }
1716
1722
  function fuzzyPatch(content, oldString, newString, replaceAll = false) {
1723
+ if (oldString === "") return null;
1717
1724
  if (content.includes(oldString)) return replaceAll ? content.split(oldString).join(newString) : content.replace(oldString, newString);
1718
1725
  const boundary = trimPatternBoundaries(oldString);
1726
+ if (boundary === "") return null;
1719
1727
  if (boundary !== oldString) {
1720
1728
  if (fuzzyIndexOf(content, boundary) !== null) {
1721
1729
  const patched = fuzzyReplace(content, boundary, newString, replaceAll);
@@ -1976,7 +1984,7 @@ var SkillLibrary = class {
1976
1984
  message: `File not found: ${patchLabel}`
1977
1985
  };
1978
1986
  const patched = fuzzyPatch(md, oldString, newString, replaceAll);
1979
- if (!patched) return {
1987
+ if (patched === null) return {
1980
1988
  ok: false,
1981
1989
  message: `Could not find old_string in "${name}/${patchLabel}". Use update for a full rewrite.`
1982
1990
  };
@@ -1,15 +1,28 @@
1
1
  /**
2
- * Durable session events emitted by the evolution family.
3
- * These are non-surface events: they never enter model history, but make
4
- * self-evolution activity replayable and observable by UI/projections.
2
+ * Process-local events emitted by the evolution family on the cordis event
3
+ * bus. Consumers subscribe with `ctx.on(...)`; producers dispatch with
4
+ * `ctx.emit(...)`.
5
+ *
6
+ * These are deliberately NOT session events: a persisted session log may only
7
+ * contain types from the host's generated `KNOWN_SESSION_EVENT_TYPES` set —
8
+ * the persistence read path refuses to interpret a log carrying any other
9
+ * type unless the envelope marks it `ignorable`, and `Session.append` offers
10
+ * no channel to write that marker. Appending any `evolution/*` type therefore
11
+ * made the whole session unresumable (A-line P0-1, fixed in rc.42 by moving
12
+ * these events off `session.append`). Plan-outcome durability lives in the
13
+ * evolution-activity store, not the session log.
5
14
  */
6
15
  export interface EvolutionReviewScheduledEvent {
16
+ /** Owning session (payload v2): process events carry no session envelope. */
17
+ sessionId: string;
7
18
  kind: 'memory' | 'skill' | 'combined';
8
19
  toolCalls: number;
9
20
  userChars: number;
10
21
  assistantChars: number;
11
22
  }
12
23
  export interface EvolutionPlanAppliedEvent {
24
+ /** Owning session (payload v2): process events carry no session envelope. */
25
+ sessionId: string;
13
26
  planId: string;
14
27
  /** Stable fingerprint of the policy snapshot that produced this plan. */
15
28
  policyFingerprint?: string | undefined;
@@ -25,15 +38,10 @@ export interface EvolutionSkillMutatedEvent {
25
38
  filePath?: string;
26
39
  archivedPath?: string;
27
40
  }
28
- declare module '@deepseek-ai/dsh-session/types' {
29
- interface SessionEventMap {
30
- 'evolution/review-scheduled': EvolutionReviewScheduledEvent;
31
- 'evolution/plan-applied': EvolutionPlanAppliedEvent;
32
- 'evolution/skill-mutated': EvolutionSkillMutatedEvent;
33
- }
34
- }
35
41
  declare module '@deepseek-ai/cordis' {
36
42
  interface Events {
43
+ 'evolution/review-scheduled'(event: EvolutionReviewScheduledEvent): void;
44
+ 'evolution/plan-applied'(event: EvolutionPlanAppliedEvent): void;
37
45
  'evolution/skill-mutated'(event: EvolutionSkillMutatedEvent): void;
38
46
  }
39
47
  }
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.40",
4
+ "version": "0.1.0-rc.42",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },