@lmzhen/dsh-evolution-core 0.3.52 → 0.3.53

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
@@ -2719,6 +2719,14 @@ async function recordMutation(root, io, record, cap = 500) {
2719
2719
  * standard row id fails loud by default, and `DSH_EVOLUTION_ALLOW_ROW_COLLISIONS=1`
2720
2720
  * downgrades it to a warning that keeps both (the row mounts twice).
2721
2721
  *
2722
+ * V10-14 / 0.3.53 (P1-2): BOTH composers now inject the Hermes 60-char catalog
2723
+ * cap onto the standard-sourced `- id: tool-skill` row of the composed preset
2724
+ * (see injectCatalogDescriptionCap) — the session-visible tool-skill instance
2725
+ * mounts in the preset's own standing scope, where no profile-root patch can
2726
+ * reach it. 0.3.53 moved the injection INTO the composer so
2727
+ * `/evolution preset install` (the npm user's only preset path) gets it too;
2728
+ * install-layered applies the byte-identical rule, pinned by installer.spec.
2729
+ *
2722
2730
  * Row ids are read from `- id:` lines; an id present in both fragments would
2723
2731
  * mount twice and could shadow the platform row, so it fails loud.
2724
2732
  * @param standardComposition - the runtime `standard` preset composition.
@@ -2730,7 +2738,47 @@ function composePresetComposition(standardComposition, deltaComposition) {
2730
2738
  const collisions = [...compositionRowIds(deltaComposition)].filter((id) => standardIds.has(id)).sort();
2731
2739
  if (collisions.length > 0 && process.env.DSH_EVOLUTION_ALLOW_ROW_COLLISIONS !== "1") throw new Error(`evolution preset composition: delta rows collide with runtime standard rows: ${collisions.join(", ")}`);
2732
2740
  if (collisions.length > 0) console.warn(`evolution preset composition: warning — delta rows collide with standard rows (${collisions.join(", ")}); keeping both (DSH_EVOLUTION_ALLOW_ROW_COLLISIONS=1)`);
2733
- return `${standardComposition.replace(/\s+$/, "")}\n\n${deltaComposition.trim()}\n`;
2741
+ return injectCatalogDescriptionCap(`${standardComposition.replace(/\s+$/, "")}\n\n${deltaComposition.trim()}\n`);
2742
+ }
2743
+ /**
2744
+ * V10-14 (P1-2), 0.3.53: inject the Hermes 60-char catalog cap onto the
2745
+ * standard-sourced `- id: tool-skill` row of a composed preset.
2746
+ *
2747
+ * The session-visible `tool-skill` instance mounts in the agent preset's own
2748
+ * standing scope; a profile-root patch (evolution-host/cordis.patch.yml)
2749
+ * cannot reach it, so without this injection the catalog's read side runs the
2750
+ * platform default (500). Text-level rewrite in the same line-scan style as
2751
+ * compositionRowIds (no YAML library):
2752
+ * - idempotent: a tool-skill item that already carries a `config:` key is
2753
+ * left byte-identical, so re-running the installer never doubles the key;
2754
+ * - the injected block carries a marker comment so a diff of the generated
2755
+ * preset can tell composer-owned text from platform text;
2756
+ * - a composition WITHOUT a tool-skill row is returned unchanged with a
2757
+ * one-time warning (a renamed platform row must not brick the install,
2758
+ * but the missed cap must be observable).
2759
+ * install-layered.mjs ships the byte-identical `injectToolSkillCap`.
2760
+ */
2761
+ function injectCatalogDescriptionCap(composition) {
2762
+ const lines = composition.split("\n");
2763
+ let found = false;
2764
+ for (let i = 0; i < lines.length; i += 1) {
2765
+ if (!/^- id:\s*tool-skill\s*$/.test(lines[i] ?? "")) continue;
2766
+ found = true;
2767
+ let end = i;
2768
+ let hasConfig = false;
2769
+ for (let j = i + 1; j < lines.length; j += 1) {
2770
+ const next = lines[j] ?? "";
2771
+ if (next.trim() === "") break;
2772
+ if (!/^\s/.test(next)) break;
2773
+ if (/^\s+config:(\s|$)/.test(next)) hasConfig = true;
2774
+ end = j;
2775
+ }
2776
+ if (hasConfig) continue;
2777
+ lines.splice(end + 1, 0, " # V10-14: Hermes 60-char catalog cap — injected by the preset composer (P1-2);", " # this preset-scope row is the session-visible instance and no profile", " # patch can reach it. Remove only to run the platform default (500).", " config:", " catalogDescriptionMaxLength: 60");
2778
+ i = end + 5;
2779
+ }
2780
+ if (!found) console.warn("evolution preset composition: warning — no `- id: tool-skill` row in the composed preset; the 60-char catalog cap was NOT injected (platform renamed the row? reconcile with the delta)");
2781
+ return lines.join("\n");
2734
2782
  }
2735
2783
  function compositionRowIds(composition) {
2736
2784
  const ids = /* @__PURE__ */ new Set();
@@ -11,6 +11,14 @@
11
11
  * standard row id fails loud by default, and `DSH_EVOLUTION_ALLOW_ROW_COLLISIONS=1`
12
12
  * downgrades it to a warning that keeps both (the row mounts twice).
13
13
  *
14
+ * V10-14 / 0.3.53 (P1-2): BOTH composers now inject the Hermes 60-char catalog
15
+ * cap onto the standard-sourced `- id: tool-skill` row of the composed preset
16
+ * (see injectCatalogDescriptionCap) — the session-visible tool-skill instance
17
+ * mounts in the preset's own standing scope, where no profile-root patch can
18
+ * reach it. 0.3.53 moved the injection INTO the composer so
19
+ * `/evolution preset install` (the npm user's only preset path) gets it too;
20
+ * install-layered applies the byte-identical rule, pinned by installer.spec.
21
+ *
14
22
  * Row ids are read from `- id:` lines; an id present in both fragments would
15
23
  * mount twice and could shadow the platform row, so it fails loud.
16
24
  * @param standardComposition - the runtime `standard` preset composition.
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.3.52",
4
+ "version": "0.3.53",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },