@lmzhen/dsh-evolution-core 0.3.13 → 0.3.15
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 +106 -57
- package/lib/types/index.d.ts +1 -0
- package/lib/types/preset-composition.d.ts +18 -0
- package/lib/types/skill-store.d.ts +28 -9
- package/package.json +5 -1
package/lib/index.js
CHANGED
|
@@ -2,6 +2,7 @@ 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 { load } from "js-yaml";
|
|
5
6
|
//#region lib/types/io.js
|
|
6
7
|
/**
|
|
7
8
|
* Structural IO seam for the evolution plugin family.
|
|
@@ -2116,6 +2117,38 @@ async function recordMutation(root, io, record, cap = 500) {
|
|
|
2116
2117
|
});
|
|
2117
2118
|
}
|
|
2118
2119
|
//#endregion
|
|
2120
|
+
//#region lib/types/preset-composition.js
|
|
2121
|
+
/**
|
|
2122
|
+
* Build the user-root Evolution preset composition from the RUNTIME platform's
|
|
2123
|
+
* `standard` preset rows plus the evolution delta rows (P1-1 follow-up,
|
|
2124
|
+
* 0.3.15): the agent-preset registry mounts ONE composition file verbatim, so
|
|
2125
|
+
* a delta-only `agent.cordis.yml` would produce an agent carrying only the
|
|
2126
|
+
* delta rows.
|
|
2127
|
+
*
|
|
2128
|
+
* Same contract as `install-layered.mjs` `generateAgentPreset` (the source
|
|
2129
|
+
* install path) — installer.spec pins byte parity between the two.
|
|
2130
|
+
*
|
|
2131
|
+
* Row ids are read from `- id:` lines; an id present in both fragments would
|
|
2132
|
+
* mount twice and could shadow the platform row, so it fails loud.
|
|
2133
|
+
* @param standardComposition - the runtime `standard` preset composition.
|
|
2134
|
+
* @param deltaComposition - the evolution delta fragment.
|
|
2135
|
+
* @returns the composed preset composition (standard rows first, then delta).
|
|
2136
|
+
*/
|
|
2137
|
+
function composePresetComposition(standardComposition, deltaComposition) {
|
|
2138
|
+
const standardIds = compositionRowIds(standardComposition);
|
|
2139
|
+
const collisions = [...compositionRowIds(deltaComposition)].filter((id) => standardIds.has(id)).sort();
|
|
2140
|
+
if (collisions.length > 0) throw new Error(`evolution preset composition: delta rows collide with runtime standard rows: ${collisions.join(", ")}`);
|
|
2141
|
+
return `${standardComposition.replace(/\s+$/, "")}\n\n${deltaComposition.trim()}\n`;
|
|
2142
|
+
}
|
|
2143
|
+
function compositionRowIds(composition) {
|
|
2144
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2145
|
+
for (const line of composition.split("\n")) {
|
|
2146
|
+
const match = /^- id:\s*(\S+)/.exec(line);
|
|
2147
|
+
if (match) ids.add(match[1] ?? "");
|
|
2148
|
+
}
|
|
2149
|
+
return ids;
|
|
2150
|
+
}
|
|
2151
|
+
//#endregion
|
|
2119
2152
|
//#region lib/types/quality.js
|
|
2120
2153
|
/**
|
|
2121
2154
|
* Quality scoring and near-duplicate detection for the curated skill library.
|
|
@@ -2501,15 +2534,42 @@ function markerEntryName(marker) {
|
|
|
2501
2534
|
function markerPath(dir, marker) {
|
|
2502
2535
|
return join(dir, markerEntryName(marker));
|
|
2503
2536
|
}
|
|
2504
|
-
|
|
2537
|
+
/**
|
|
2538
|
+
* Shared frontmatter block detection (P3-3 single owner): opening line `---`
|
|
2539
|
+
* and closing line exactly `---` (both trimmed). Used by `parseFrontmatter`,
|
|
2540
|
+
* `frontmatterYamlUnsafeValues` and `normalizeFrontmatter` so the three can
|
|
2541
|
+
* never disagree about where the block ends (the loose `indexOf('\n---')`
|
|
2542
|
+
* form matched `\n----` and was replaced by this strict line rule).
|
|
2543
|
+
*/
|
|
2544
|
+
function frontmatterBlock(content) {
|
|
2505
2545
|
if (!content.trimStart().startsWith("---")) return null;
|
|
2506
|
-
const
|
|
2546
|
+
const nl = content.includes("\r\n") ? "\r\n" : "\n";
|
|
2547
|
+
const lines = content.split(nl);
|
|
2548
|
+
if ((lines[0] ?? "").trim() !== "---") return null;
|
|
2549
|
+
let end = -1;
|
|
2550
|
+
for (let i = 1; i < lines.length; i++) {
|
|
2551
|
+
const line = lines[i];
|
|
2552
|
+
if (line === void 0) continue;
|
|
2553
|
+
if (line.trim() === "---") {
|
|
2554
|
+
end = i;
|
|
2555
|
+
break;
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2507
2558
|
if (end < 0) return null;
|
|
2508
|
-
|
|
2509
|
-
|
|
2559
|
+
return {
|
|
2560
|
+
block: lines.slice(1, end).join(nl),
|
|
2561
|
+
lines,
|
|
2562
|
+
end,
|
|
2563
|
+
nl
|
|
2564
|
+
};
|
|
2565
|
+
}
|
|
2566
|
+
function parseFrontmatter(content) {
|
|
2567
|
+
const found = frontmatterBlock(content);
|
|
2568
|
+
if (!found) return null;
|
|
2569
|
+
const body = found.lines.slice(found.end + 1).join(found.nl).trim();
|
|
2510
2570
|
if (!body) return null;
|
|
2511
2571
|
const frontmatter = {};
|
|
2512
|
-
for (const line of block.split(
|
|
2572
|
+
for (const line of found.block.split(found.nl)) {
|
|
2513
2573
|
const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line);
|
|
2514
2574
|
if (match) {
|
|
2515
2575
|
const [, key, value] = match;
|
|
@@ -2528,7 +2588,10 @@ function parseFrontmatter(content) {
|
|
|
2528
2588
|
* silently split family-visibility from platform-visibility (0.3.11
|
|
2529
2589
|
* inkos-harness case: the description carried "…: " and the catalog dropped
|
|
2530
2590
|
* the whole skill). Already-quoted values and well-formed flow collections
|
|
2531
|
-
* (`[a, b]` / `{a: b}`) are considered safe.
|
|
2591
|
+
* (`[a, b]` / `{a: b}`) are considered safe. This rule is only the FAST
|
|
2592
|
+
* PATH — the write path re-verifies every rewrite with the real YAML parser
|
|
2593
|
+
* (see normalizeFrontmatter), so an incomplete approximation can never
|
|
2594
|
+
* corrupt a multiline flow value (P3-4). */
|
|
2532
2595
|
function yamlPlainScalarNeedsQuotes(value) {
|
|
2533
2596
|
if (value.length === 0) return false;
|
|
2534
2597
|
if (value.length >= 2 && (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'"))) return false;
|
|
@@ -2545,23 +2608,9 @@ function yamlPlainScalarNeedsQuotes(value) {
|
|
|
2545
2608
|
* path. Single-line entries only; lines with embedded line breaks skip. */
|
|
2546
2609
|
function frontmatterYamlUnsafeValues(content) {
|
|
2547
2610
|
const found = [];
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
const
|
|
2551
|
-
if ((lines[0] ?? "").trim() !== "---") return found;
|
|
2552
|
-
let end = -1;
|
|
2553
|
-
for (let i = 1; i < lines.length; i++) {
|
|
2554
|
-
const line = lines[i];
|
|
2555
|
-
if (line === void 0) continue;
|
|
2556
|
-
if (line.trim() === "---") {
|
|
2557
|
-
end = i;
|
|
2558
|
-
break;
|
|
2559
|
-
}
|
|
2560
|
-
}
|
|
2561
|
-
if (end < 0) return found;
|
|
2562
|
-
for (let i = 1; i < end; i++) {
|
|
2563
|
-
const line = lines[i];
|
|
2564
|
-
if (line === void 0) continue;
|
|
2611
|
+
const block = frontmatterBlock(content);
|
|
2612
|
+
if (!block) return found;
|
|
2613
|
+
for (const line of block.block.split(block.nl)) {
|
|
2565
2614
|
if (line.includes("\n") || line.includes("\r")) continue;
|
|
2566
2615
|
const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line);
|
|
2567
2616
|
if (!match) continue;
|
|
@@ -2579,43 +2628,25 @@ function frontmatterYamlUnsafeValues(content) {
|
|
|
2579
2628
|
* Normalize a SKILL.md frontmatter block into catalog-loadable YAML: values
|
|
2580
2629
|
* that YAML forbids unquoted get quotes — double quotes normally, single
|
|
2581
2630
|
* quotes (with `''` doubling) when the value contains `"` or `\` (both legal
|
|
2582
|
-
* unescaped inside single-quoted YAML). Idempotent
|
|
2583
|
-
*
|
|
2584
|
-
*
|
|
2585
|
-
*
|
|
2586
|
-
*
|
|
2631
|
+
* unescaped inside single-quoted YAML). Idempotent; only single-line
|
|
2632
|
+
* `key: value` entries are touched; body text is never modified; line-ending
|
|
2633
|
+
* style is preserved. **Every rewrite is re-verified with the real YAML
|
|
2634
|
+
* parser** (js-yaml — the same parser the platform catalog uses): if the
|
|
2635
|
+
* rewritten block no longer parses, or a rewritten value's parsed content
|
|
2636
|
+
* differs from the original, the rewrite is rolled back and reported in
|
|
2637
|
+
* `issues` (fail-loud, never a silent value corruption — P3-4).
|
|
2587
2638
|
*/
|
|
2588
2639
|
function normalizeFrontmatter(content) {
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
changed: false,
|
|
2592
|
-
fields: [],
|
|
2593
|
-
issues: []
|
|
2594
|
-
};
|
|
2595
|
-
const nl = content.includes("\r\n") ? "\r\n" : "\n";
|
|
2596
|
-
const lines = content.split(nl);
|
|
2597
|
-
if ((lines[0] ?? "").trim() !== "---") return {
|
|
2598
|
-
content,
|
|
2599
|
-
changed: false,
|
|
2600
|
-
fields: [],
|
|
2601
|
-
issues: []
|
|
2602
|
-
};
|
|
2603
|
-
let end = -1;
|
|
2604
|
-
for (let i = 1; i < lines.length; i++) {
|
|
2605
|
-
const line = lines[i];
|
|
2606
|
-
if (line === void 0) continue;
|
|
2607
|
-
if (line.trim() === "---") {
|
|
2608
|
-
end = i;
|
|
2609
|
-
break;
|
|
2610
|
-
}
|
|
2611
|
-
}
|
|
2612
|
-
if (end < 0) return {
|
|
2640
|
+
const block = frontmatterBlock(content);
|
|
2641
|
+
if (!block) return {
|
|
2613
2642
|
content,
|
|
2614
2643
|
changed: false,
|
|
2615
2644
|
fields: [],
|
|
2616
2645
|
issues: []
|
|
2617
2646
|
};
|
|
2647
|
+
const { lines, end, nl } = block;
|
|
2618
2648
|
const unsafe = new Map(frontmatterYamlUnsafeValues(content).map((entry) => [entry.key, entry.value]));
|
|
2649
|
+
const originalValues = new Map(unsafe);
|
|
2619
2650
|
const fields = [];
|
|
2620
2651
|
const issues = [];
|
|
2621
2652
|
let changed = false;
|
|
@@ -2635,12 +2666,30 @@ function normalizeFrontmatter(content) {
|
|
|
2635
2666
|
fields.push(key);
|
|
2636
2667
|
changed = true;
|
|
2637
2668
|
}
|
|
2638
|
-
return {
|
|
2639
|
-
content
|
|
2640
|
-
changed,
|
|
2641
|
-
fields,
|
|
2669
|
+
if (!changed) return {
|
|
2670
|
+
content,
|
|
2671
|
+
changed: false,
|
|
2672
|
+
fields: [],
|
|
2642
2673
|
issues
|
|
2643
2674
|
};
|
|
2675
|
+
const rewrittenBlock = lines.slice(1, end).join(nl);
|
|
2676
|
+
try {
|
|
2677
|
+
const parsed = load(rewrittenBlock);
|
|
2678
|
+
for (const key of fields) if (String(parsed[key]) !== originalValues.get(key)) throw new Error(`rewritten value for ${key} differs from the original`);
|
|
2679
|
+
return {
|
|
2680
|
+
content: lines.join(nl),
|
|
2681
|
+
changed: true,
|
|
2682
|
+
fields,
|
|
2683
|
+
issues
|
|
2684
|
+
};
|
|
2685
|
+
} catch (error) {
|
|
2686
|
+
return {
|
|
2687
|
+
content,
|
|
2688
|
+
changed: false,
|
|
2689
|
+
fields: [],
|
|
2690
|
+
issues: [`frontmatter rewrite verification failed (${error instanceof Error ? error.message : String(error)}) — quoting skipped; wrap this value manually`]
|
|
2691
|
+
};
|
|
2692
|
+
}
|
|
2644
2693
|
}
|
|
2645
2694
|
/**
|
|
2646
2695
|
* Skill names referenced by a SKILL.md's `related_skills` frontmatter
|
|
@@ -4154,4 +4203,4 @@ function evolutionHome(env = process.env) {
|
|
|
4154
4203
|
return join(env.DSH_HOME ?? join(homedir(), ".dsh"), "evolution");
|
|
4155
4204
|
}
|
|
4156
4205
|
//#endregion
|
|
4157
|
-
export { AUTHORING_DESCRIPTION_BAR, COMBINED_REVIEW_PLAN_PROMPT, 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_HEALTH_THRESHOLDS, 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, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EvolutionGateSet, HEALTH_STAMP_RE, LOW_QUALITY_THRESHOLD, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_RESTRUCTURE_MOVES, 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, RESTRUCTURE_TARGET_RE, SKILLS_GUIDANCE, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, advanceReview, appendEvolutionEvent, applyCuratorFields, applyCuratorLifecycleFields, applyCuratorMetaFields, assessStructureHealth, authoringFeedback, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpUse, bumpView, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, createGateSet, duplicateHeadings, emptyRecord, evaluateThreat, eventsFile, evolutionHome, evolutionIoAdapter, findDriftSignal, foldCuratorFields, foldTurn, frontmatterYamlUnsafeValues, getRecord, latestActivityAt, lifecycleCandidate, listEventArchives, loadMutations, loadSuppressedNames, loadUsage, markAgentCreated, memoryRoot, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, observeEvent, overlongLines, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, readEvolutionEvents, readEvolutionTimeline, recordMutation, redactSecrets, relatedSkillNames, renderCuratorReportMarkdown, resolveOrigins, retainEventArchives, reviewPrompt, saveSuppressedNames, saveUsage, scanContentThreats, scanMemoryThreats, scanThreats, skillsRoot, suppressedFile, transactIo, updateSuppressedNames, usageFile, usageObserved, validateFrontmatter, verifyPromptBundle, yamlPlainScalarNeedsQuotes };
|
|
4206
|
+
export { AUTHORING_DESCRIPTION_BAR, COMBINED_REVIEW_PLAN_PROMPT, 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_HEALTH_THRESHOLDS, 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, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EvolutionGateSet, HEALTH_STAMP_RE, LOW_QUALITY_THRESHOLD, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_RESTRUCTURE_MOVES, 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, RESTRUCTURE_TARGET_RE, SKILLS_GUIDANCE, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, advanceReview, appendEvolutionEvent, applyCuratorFields, applyCuratorLifecycleFields, applyCuratorMetaFields, assessStructureHealth, authoringFeedback, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpUse, bumpView, composePresetComposition, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, createGateSet, duplicateHeadings, emptyRecord, evaluateThreat, eventsFile, evolutionHome, evolutionIoAdapter, findDriftSignal, foldCuratorFields, foldTurn, frontmatterBlock, frontmatterYamlUnsafeValues, getRecord, latestActivityAt, lifecycleCandidate, listEventArchives, loadMutations, loadSuppressedNames, loadUsage, markAgentCreated, memoryRoot, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, observeEvent, overlongLines, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, readEvolutionEvents, readEvolutionTimeline, recordMutation, redactSecrets, relatedSkillNames, renderCuratorReportMarkdown, resolveOrigins, retainEventArchives, reviewPrompt, saveSuppressedNames, saveUsage, scanContentThreats, scanMemoryThreats, scanThreats, skillsRoot, suppressedFile, transactIo, updateSuppressedNames, usageFile, usageObserved, validateFrontmatter, verifyPromptBundle, yamlPlainScalarNeedsQuotes };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export * from './io.ts';
|
|
|
15
15
|
export * from './learn-prompt.ts';
|
|
16
16
|
export * from './memory-store.ts';
|
|
17
17
|
export * from './mutations.ts';
|
|
18
|
+
export * from './preset-composition.ts';
|
|
18
19
|
export * from './prompts.ts';
|
|
19
20
|
export * from './quality.ts';
|
|
20
21
|
export * from './redact.ts';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the user-root Evolution preset composition from the RUNTIME platform's
|
|
3
|
+
* `standard` preset rows plus the evolution delta rows (P1-1 follow-up,
|
|
4
|
+
* 0.3.15): the agent-preset registry mounts ONE composition file verbatim, so
|
|
5
|
+
* a delta-only `agent.cordis.yml` would produce an agent carrying only the
|
|
6
|
+
* delta rows.
|
|
7
|
+
*
|
|
8
|
+
* Same contract as `install-layered.mjs` `generateAgentPreset` (the source
|
|
9
|
+
* install path) — installer.spec pins byte parity between the two.
|
|
10
|
+
*
|
|
11
|
+
* Row ids are read from `- id:` lines; an id present in both fragments would
|
|
12
|
+
* mount twice and could shadow the platform row, so it fails loud.
|
|
13
|
+
* @param standardComposition - the runtime `standard` preset composition.
|
|
14
|
+
* @param deltaComposition - the evolution delta fragment.
|
|
15
|
+
* @returns the composed preset composition (standard rows first, then delta).
|
|
16
|
+
*/
|
|
17
|
+
export declare function composePresetComposition(standardComposition: string, deltaComposition: string): string;
|
|
18
|
+
//# sourceMappingURL=preset-composition.d.ts.map
|
|
@@ -100,6 +100,19 @@ export interface Frontmatter {
|
|
|
100
100
|
description?: string;
|
|
101
101
|
[key: string]: unknown;
|
|
102
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Shared frontmatter block detection (P3-3 single owner): opening line `---`
|
|
105
|
+
* and closing line exactly `---` (both trimmed). Used by `parseFrontmatter`,
|
|
106
|
+
* `frontmatterYamlUnsafeValues` and `normalizeFrontmatter` so the three can
|
|
107
|
+
* never disagree about where the block ends (the loose `indexOf('\n---')`
|
|
108
|
+
* form matched `\n----` and was replaced by this strict line rule).
|
|
109
|
+
*/
|
|
110
|
+
export declare function frontmatterBlock(content: string): {
|
|
111
|
+
block: string;
|
|
112
|
+
lines: string[];
|
|
113
|
+
end: number;
|
|
114
|
+
nl: string;
|
|
115
|
+
} | null;
|
|
103
116
|
export declare function parseFrontmatter(content: string): {
|
|
104
117
|
frontmatter: Frontmatter;
|
|
105
118
|
body: string;
|
|
@@ -111,7 +124,10 @@ export declare function parseFrontmatter(content: string): {
|
|
|
111
124
|
* silently split family-visibility from platform-visibility (0.3.11
|
|
112
125
|
* inkos-harness case: the description carried "…: " and the catalog dropped
|
|
113
126
|
* the whole skill). Already-quoted values and well-formed flow collections
|
|
114
|
-
* (`[a, b]` / `{a: b}`) are considered safe.
|
|
127
|
+
* (`[a, b]` / `{a: b}`) are considered safe. This rule is only the FAST
|
|
128
|
+
* PATH — the write path re-verifies every rewrite with the real YAML parser
|
|
129
|
+
* (see normalizeFrontmatter), so an incomplete approximation can never
|
|
130
|
+
* corrupt a multiline flow value (P3-4). */
|
|
115
131
|
export declare function yamlPlainScalarNeedsQuotes(value: string): boolean;
|
|
116
132
|
/** Raw-line scan of the frontmatter block: entries whose UNQUOTED value is
|
|
117
133
|
* YAML-unsafe for the strict platform catalog. Operates on the ORIGINAL line
|
|
@@ -127,20 +143,23 @@ export interface FrontmatterNormalizeResult {
|
|
|
127
143
|
changed: boolean;
|
|
128
144
|
/** Frontmatter keys whose values were auto-quoted. */
|
|
129
145
|
fields: string[];
|
|
130
|
-
/** Values that cannot be auto-quoted safely (control characters
|
|
131
|
-
*
|
|
132
|
-
*
|
|
146
|
+
/** Values that cannot be auto-quoted safely (control characters, or a
|
|
147
|
+
* rewrite that failed the real-parser verification — a multiline flow
|
|
148
|
+
* collection line etc. is left untouched and reported here, so the write
|
|
149
|
+
* path rejects instead of silently damaging a value; 0.3.14). */
|
|
133
150
|
issues: string[];
|
|
134
151
|
}
|
|
135
152
|
/**
|
|
136
153
|
* Normalize a SKILL.md frontmatter block into catalog-loadable YAML: values
|
|
137
154
|
* that YAML forbids unquoted get quotes — double quotes normally, single
|
|
138
155
|
* quotes (with `''` doubling) when the value contains `"` or `\` (both legal
|
|
139
|
-
* unescaped inside single-quoted YAML). Idempotent
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
156
|
+
* unescaped inside single-quoted YAML). Idempotent; only single-line
|
|
157
|
+
* `key: value` entries are touched; body text is never modified; line-ending
|
|
158
|
+
* style is preserved. **Every rewrite is re-verified with the real YAML
|
|
159
|
+
* parser** (js-yaml — the same parser the platform catalog uses): if the
|
|
160
|
+
* rewritten block no longer parses, or a rewritten value's parsed content
|
|
161
|
+
* differs from the original, the rewrite is rolled back and reported in
|
|
162
|
+
* `issues` (fail-loud, never a silent value corruption — P3-4).
|
|
144
163
|
*/
|
|
145
164
|
export declare function normalizeFrontmatter(content: string): FrontmatterNormalizeResult;
|
|
146
165
|
/**
|
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.
|
|
4
|
+
"version": "0.3.15",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,12 +31,16 @@
|
|
|
31
31
|
"lib/types/invariant.d.ts"
|
|
32
32
|
],
|
|
33
33
|
"license": "MIT",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"js-yaml": "^4.2.0"
|
|
36
|
+
},
|
|
34
37
|
"peerDependencies": {
|
|
35
38
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
36
39
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
37
40
|
"@deepseek-ai/dsh-session": "^0.1.1-rc.2"
|
|
38
41
|
},
|
|
39
42
|
"devDependencies": {
|
|
43
|
+
"@types/js-yaml": "^4.0.9",
|
|
40
44
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
41
45
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
42
46
|
"@deepseek-ai/dsh-session": "^0.1.1-rc.2"
|