@lmzhen/dsh-evolution-core 0.1.0-rc.26 → 0.1.0-rc.28
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 +128 -9
- package/lib/types/curator.d.ts +23 -1
- package/lib/types/skill-store.d.ts +11 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -308,6 +308,50 @@ function parseCuratorNominations(text) {
|
|
|
308
308
|
consolidations: consolidations.filter((item) => valid(item.from) && valid(item.into))
|
|
309
309
|
};
|
|
310
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* The lifecycle-candidate gate, shared by the transition engine and the scope
|
|
313
|
+
* view so the two can never disagree: records failing ANY of these gates are
|
|
314
|
+
* outside the managed scope.
|
|
315
|
+
*/
|
|
316
|
+
function lifecycleCandidate(name, record, config, bundled) {
|
|
317
|
+
if (record.pinned) return false;
|
|
318
|
+
if (config.excludeSkillNames?.has(name)) return false;
|
|
319
|
+
if (config.suppressedNames?.has(name)) return false;
|
|
320
|
+
if (config.referencedSkillNames?.has(name)) return false;
|
|
321
|
+
if (!(record.created_by === "agent" || config.manageUnmanaged === true) && !(config.pruneBuiltins === true && bundled)) return false;
|
|
322
|
+
if (PROTECTED_BUILTIN_SKILLS.has(name)) return false;
|
|
323
|
+
if (record.state === "archived") return false;
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Read-only scope classification, derived from the SAME gate the transition
|
|
328
|
+
* engine uses (`lifecycleCandidate`), so the view always predicts what a
|
|
329
|
+
* curator pass may touch.
|
|
330
|
+
*/
|
|
331
|
+
function computeScopeView(usage, config) {
|
|
332
|
+
const managed = [];
|
|
333
|
+
const watched = [];
|
|
334
|
+
const exempted = [];
|
|
335
|
+
const protectedNames = [];
|
|
336
|
+
for (const [name, record] of usage) {
|
|
337
|
+
if (config.excludeSkillNames?.has(name) || config.referencedSkillNames?.has(name)) {
|
|
338
|
+
exempted.push(name);
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
const bundled = config.bundledNames?.has(name) === true;
|
|
342
|
+
if (record.pinned || bundled || config.suppressedNames?.has(name) === true) protectedNames.push(name);
|
|
343
|
+
if (lifecycleCandidate(name, record, config, bundled)) {
|
|
344
|
+
managed.push(name);
|
|
345
|
+
if (record.state === "stale" || record.quality_warn === true) watched.push(name);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return {
|
|
349
|
+
managed: managed.sort(),
|
|
350
|
+
watched: watched.sort(),
|
|
351
|
+
exempted: exempted.sort(),
|
|
352
|
+
protected: protectedNames.sort()
|
|
353
|
+
};
|
|
354
|
+
}
|
|
311
355
|
function daysSince(iso, created, now) {
|
|
312
356
|
return (now - new Date(iso ?? created).getTime()) / 864e5;
|
|
313
357
|
}
|
|
@@ -319,14 +363,7 @@ function computeLifecycleTransitions(usage, config, now = /* @__PURE__ */ new Da
|
|
|
319
363
|
markStale: []
|
|
320
364
|
};
|
|
321
365
|
for (const [name, record] of usage) {
|
|
322
|
-
if (record.
|
|
323
|
-
if (config.excludeSkillNames?.has(name)) continue;
|
|
324
|
-
if (config.suppressedNames?.has(name)) continue;
|
|
325
|
-
if (config.referencedSkillNames?.has(name)) continue;
|
|
326
|
-
const bundled = config.bundledNames?.has(name) === true;
|
|
327
|
-
if (!(record.created_by === "agent" || config.manageUnmanaged === true) && !(config.pruneBuiltins === true && bundled)) continue;
|
|
328
|
-
if (PROTECTED_BUILTIN_SKILLS.has(name)) continue;
|
|
329
|
-
if (record.state === "archived") continue;
|
|
366
|
+
if (!lifecycleCandidate(name, record, config, config.bundledNames?.has(name) === true)) continue;
|
|
330
367
|
const age = daysSince(null, record.created_at, now.getTime());
|
|
331
368
|
if (record.use_count === 0 && age < config.staleAfterDays) continue;
|
|
332
369
|
const idle = daysSince(latestActivityAt(record), record.created_at, now.getTime());
|
|
@@ -1659,8 +1696,15 @@ var SkillLibrary = class {
|
|
|
1659
1696
|
return summaries;
|
|
1660
1697
|
}
|
|
1661
1698
|
async read(name) {
|
|
1699
|
+
if (this.badName(name) !== null) return null;
|
|
1662
1700
|
return this.io.readText(join(skillDir(this.root, name), "SKILL.md"));
|
|
1663
1701
|
}
|
|
1702
|
+
/** Name-format guard shared by every path-building mutator/reader. */
|
|
1703
|
+
badName(name) {
|
|
1704
|
+
const normalized = name.trim();
|
|
1705
|
+
if (!SKILL_NAME_RE.test(normalized) || normalized.length > this.limits.maxNameLength) return `Invalid skill name "${normalized}". Use lowercase letters, digits, and hyphens (<= ${this.limits.maxNameLength}).`;
|
|
1706
|
+
return null;
|
|
1707
|
+
}
|
|
1664
1708
|
async writeProtection(name, origin = "foreground") {
|
|
1665
1709
|
const dir = skillDir(this.root, name);
|
|
1666
1710
|
for (const marker of ["bundled", "hub-installed"]) if (await this.io.exists(markerPath(dir, marker))) return marker;
|
|
@@ -1683,11 +1727,19 @@ var SkillLibrary = class {
|
|
|
1683
1727
|
}
|
|
1684
1728
|
/** Whether the skill carries the bundled marker (curator prune-builtins eligibility). */
|
|
1685
1729
|
async isBundled(name) {
|
|
1730
|
+
if (this.badName(name) !== null) return false;
|
|
1686
1731
|
const dir = skillDir(this.root, name);
|
|
1687
1732
|
return await this.io.exists(markerPath(dir, "bundled"));
|
|
1688
1733
|
}
|
|
1734
|
+
/** Whether the skill carries the pinned marker (the marker is the factual source; usage.pinned mirrors it). */
|
|
1735
|
+
async isPinned(name) {
|
|
1736
|
+
if (this.badName(name) !== null) return false;
|
|
1737
|
+
const dir = skillDir(this.root, name);
|
|
1738
|
+
return await this.io.exists(markerPath(dir, "pinned"));
|
|
1739
|
+
}
|
|
1689
1740
|
/** Count non-empty support subdirectories (richness input for quality scoring). */
|
|
1690
1741
|
async countSupportDirs(name) {
|
|
1742
|
+
if (this.badName(name) !== null) return 0;
|
|
1691
1743
|
const dir = skillDir(this.root, name);
|
|
1692
1744
|
let entries;
|
|
1693
1745
|
try {
|
|
@@ -1721,6 +1773,48 @@ var SkillLibrary = class {
|
|
|
1721
1773
|
async listMutations() {
|
|
1722
1774
|
return await loadMutations(this.root, this.io);
|
|
1723
1775
|
}
|
|
1776
|
+
/**
|
|
1777
|
+
* Pin or unpin a skill (`.pinned` marker). Pinned skills are protected from
|
|
1778
|
+
* deletion, from background-review writes, and from the lifecycle — a
|
|
1779
|
+
* protective mutation, so the autonomous pipeline may never call it. The
|
|
1780
|
+
* marker write is the only state change; content is untouched.
|
|
1781
|
+
*/
|
|
1782
|
+
async setPinned(name, pinned, origin = "foreground") {
|
|
1783
|
+
const normalized = name.trim();
|
|
1784
|
+
if (!SKILL_NAME_RE.test(normalized) || normalized.length > this.limits.maxNameLength) return {
|
|
1785
|
+
ok: false,
|
|
1786
|
+
message: `Invalid skill name "${normalized}". Use lowercase letters, digits, and hyphens (<= ${this.limits.maxNameLength}).`
|
|
1787
|
+
};
|
|
1788
|
+
if (origin === "background_review") return {
|
|
1789
|
+
ok: false,
|
|
1790
|
+
message: "Only the foreground (user or the main agent) may pin or unpin skills."
|
|
1791
|
+
};
|
|
1792
|
+
const dir = skillDir(this.root, normalized);
|
|
1793
|
+
const marker = markerPath(dir, "pinned");
|
|
1794
|
+
const existing = await this.io.exists(marker);
|
|
1795
|
+
if (pinned && existing) return {
|
|
1796
|
+
ok: true,
|
|
1797
|
+
message: `Skill "${normalized}" is already pinned.`,
|
|
1798
|
+
path: dir
|
|
1799
|
+
};
|
|
1800
|
+
if (!pinned && !existing) return {
|
|
1801
|
+
ok: true,
|
|
1802
|
+
message: `Skill "${normalized}" is not pinned; nothing to do.`,
|
|
1803
|
+
path: dir
|
|
1804
|
+
};
|
|
1805
|
+
if (!await this.io.exists(join(dir, "SKILL.md"))) return {
|
|
1806
|
+
ok: false,
|
|
1807
|
+
message: `Skill "${normalized}" not found.`
|
|
1808
|
+
};
|
|
1809
|
+
if (pinned) await this.io.writeText(marker, "");
|
|
1810
|
+
else await this.io.remove(marker);
|
|
1811
|
+
await this.audit(normalized, pinned ? "pin" : "unpin", null, null, pinned ? "pinned" : "unpinned");
|
|
1812
|
+
return {
|
|
1813
|
+
ok: true,
|
|
1814
|
+
message: pinned ? `Skill "${normalized}" pinned: protected from deletion, background review, and the lifecycle.` : `Skill "${normalized}" unpinned.`,
|
|
1815
|
+
path: dir
|
|
1816
|
+
};
|
|
1817
|
+
}
|
|
1724
1818
|
async create(name, content, origin) {
|
|
1725
1819
|
const normalized = name.trim();
|
|
1726
1820
|
if (!SKILL_NAME_RE.test(normalized) || normalized.length > this.limits.maxNameLength) return {
|
|
@@ -1752,6 +1846,11 @@ var SkillLibrary = class {
|
|
|
1752
1846
|
};
|
|
1753
1847
|
}
|
|
1754
1848
|
async update(name, content, origin = "foreground") {
|
|
1849
|
+
const badName = this.badName(name);
|
|
1850
|
+
if (badName) return {
|
|
1851
|
+
ok: false,
|
|
1852
|
+
message: badName
|
|
1853
|
+
};
|
|
1755
1854
|
const dir = skillDir(this.root, name);
|
|
1756
1855
|
const md = await this.io.readText(join(dir, "SKILL.md"));
|
|
1757
1856
|
if (!md) return {
|
|
@@ -1782,6 +1881,11 @@ var SkillLibrary = class {
|
|
|
1782
1881
|
};
|
|
1783
1882
|
}
|
|
1784
1883
|
async patch(name, oldString, newString, filePath = "", replaceAll = false, origin = "foreground") {
|
|
1884
|
+
const badName = this.badName(name);
|
|
1885
|
+
if (badName) return {
|
|
1886
|
+
ok: false,
|
|
1887
|
+
message: badName
|
|
1888
|
+
};
|
|
1785
1889
|
const dir = skillDir(this.root, name);
|
|
1786
1890
|
const skillMd = join(dir, "SKILL.md");
|
|
1787
1891
|
if (!await this.io.exists(skillMd)) return {
|
|
@@ -1843,6 +1947,11 @@ var SkillLibrary = class {
|
|
|
1843
1947
|
};
|
|
1844
1948
|
}
|
|
1845
1949
|
async archive(name, options = {}) {
|
|
1950
|
+
const badName = this.badName(name);
|
|
1951
|
+
if (badName) return {
|
|
1952
|
+
ok: false,
|
|
1953
|
+
message: badName
|
|
1954
|
+
};
|
|
1846
1955
|
const dir = skillDir(this.root, name);
|
|
1847
1956
|
const md = await this.io.readText(join(dir, "SKILL.md"));
|
|
1848
1957
|
if (!md) return {
|
|
@@ -2001,6 +2110,11 @@ var SkillLibrary = class {
|
|
|
2001
2110
|
};
|
|
2002
2111
|
}
|
|
2003
2112
|
async writeSupportFile(name, filePath, content, origin = "foreground") {
|
|
2113
|
+
const badName = this.badName(name);
|
|
2114
|
+
if (badName) return {
|
|
2115
|
+
ok: false,
|
|
2116
|
+
message: badName
|
|
2117
|
+
};
|
|
2004
2118
|
const dir = skillDir(this.root, name);
|
|
2005
2119
|
if (!await this.io.exists(join(dir, "SKILL.md"))) return {
|
|
2006
2120
|
ok: false,
|
|
@@ -2036,6 +2150,11 @@ var SkillLibrary = class {
|
|
|
2036
2150
|
};
|
|
2037
2151
|
}
|
|
2038
2152
|
async removeSupportFile(name, filePath, origin = "foreground") {
|
|
2153
|
+
const badName = this.badName(name);
|
|
2154
|
+
if (badName) return {
|
|
2155
|
+
ok: false,
|
|
2156
|
+
message: badName
|
|
2157
|
+
};
|
|
2039
2158
|
const dir = skillDir(this.root, name);
|
|
2040
2159
|
if (!await this.io.exists(join(dir, "SKILL.md"))) return {
|
|
2041
2160
|
ok: false,
|
|
@@ -2186,4 +2305,4 @@ var JsonState = class JsonState {
|
|
|
2186
2305
|
}
|
|
2187
2306
|
};
|
|
2188
2307
|
//#endregion
|
|
2189
|
-
export { COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, 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, 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, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, advanceReview, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpUse, bumpView, computeDedupGroups, computeLifecycleTransitions, computeQualityScores, contentHash, emptyRecord, evaluateThreat, evolutionHome, evolutionIoAdapter, foldTurn, getRecord, latestActivityAt, loadMutations, loadSuppressedNames, loadUsage, markAgentCreated, memoryRoot, mutationsFile, nodeEvolutionIo, observeEvent, parseCuratorNominations, parseFrontmatter, recordMutation, reviewPrompt, saveSuppressedNames, saveUsage, scanContentThreats, scanMemoryThreats, scanThreats, skillsRoot, suppressedFile, usageFile, validateFrontmatter, verifyPromptBundle };
|
|
2308
|
+
export { COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, 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, 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, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, advanceReview, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpUse, bumpView, computeDedupGroups, computeLifecycleTransitions, computeQualityScores, computeScopeView, contentHash, emptyRecord, evaluateThreat, evolutionHome, evolutionIoAdapter, foldTurn, getRecord, latestActivityAt, lifecycleCandidate, loadMutations, loadSuppressedNames, loadUsage, markAgentCreated, memoryRoot, mutationsFile, nodeEvolutionIo, observeEvent, parseCuratorNominations, parseFrontmatter, recordMutation, reviewPrompt, saveSuppressedNames, saveUsage, scanContentThreats, scanMemoryThreats, scanThreats, skillsRoot, suppressedFile, usageFile, validateFrontmatter, verifyPromptBundle };
|
package/lib/types/curator.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Deterministic skill curator: active → stale → archived transitions.
|
|
3
3
|
* Pure function; file moves are performed by SkillLibrary.
|
|
4
4
|
*/
|
|
5
|
-
import type { UsageMap } from './usage.ts';
|
|
5
|
+
import type { UsageMap, UsageRecord } from './usage.ts';
|
|
6
6
|
export { PROTECTED_BUILTIN_SKILLS } from './constants.ts';
|
|
7
7
|
export interface CuratorConfig {
|
|
8
8
|
staleAfterDays: number;
|
|
@@ -87,5 +87,27 @@ export interface CuratorNominations {
|
|
|
87
87
|
* is re-validated against the tree before any file move happens downstream.
|
|
88
88
|
*/
|
|
89
89
|
export declare function parseCuratorNominations(text: string): CuratorNominations;
|
|
90
|
+
/**
|
|
91
|
+
* The lifecycle-candidate gate, shared by the transition engine and the scope
|
|
92
|
+
* view so the two can never disagree: records failing ANY of these gates are
|
|
93
|
+
* outside the managed scope.
|
|
94
|
+
*/
|
|
95
|
+
export declare function lifecycleCandidate(name: string, record: UsageRecord, config: CuratorConfig, bundled: boolean): boolean;
|
|
96
|
+
export interface ScopeView {
|
|
97
|
+
/** Skills inside the lifecycle scope right now (candidate gate + active state). */
|
|
98
|
+
managed: string[];
|
|
99
|
+
/** Managed skills already flagged stale or quality-warned — the ones to watch. */
|
|
100
|
+
watched: string[];
|
|
101
|
+
/** Explicitly exempted by excludeSkillNames / referencedSkillNames. */
|
|
102
|
+
exempted: string[];
|
|
103
|
+
/** Carrying a protection marker (pinned / bundled / hub-installed). */
|
|
104
|
+
protected: string[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Read-only scope classification, derived from the SAME gate the transition
|
|
108
|
+
* engine uses (`lifecycleCandidate`), so the view always predicts what a
|
|
109
|
+
* curator pass may touch.
|
|
110
|
+
*/
|
|
111
|
+
export declare function computeScopeView(usage: UsageMap, config: CuratorConfig): ScopeView;
|
|
90
112
|
export declare function computeLifecycleTransitions(usage: UsageMap, config: CuratorConfig, now?: Date): CuratorResult;
|
|
91
113
|
//# sourceMappingURL=curator.d.ts.map
|
|
@@ -57,6 +57,8 @@ export declare class SkillLibrary {
|
|
|
57
57
|
constructor(root?: string, io?: EvolutionIoLike, limits?: SkillLimits);
|
|
58
58
|
list(): Promise<SkillSummary[]>;
|
|
59
59
|
read(name: string): Promise<string | null>;
|
|
60
|
+
/** Name-format guard shared by every path-building mutator/reader. */
|
|
61
|
+
private badName;
|
|
60
62
|
writeProtection(name: string, origin?: WriteOrigin): Promise<string | null>;
|
|
61
63
|
deleteProtection(name: string, options?: {
|
|
62
64
|
allowBundled?: boolean;
|
|
@@ -64,12 +66,21 @@ export declare class SkillLibrary {
|
|
|
64
66
|
isManaged(name: string): Promise<boolean>;
|
|
65
67
|
/** Whether the skill carries the bundled marker (curator prune-builtins eligibility). */
|
|
66
68
|
isBundled(name: string): Promise<boolean>;
|
|
69
|
+
/** Whether the skill carries the pinned marker (the marker is the factual source; usage.pinned mirrors it). */
|
|
70
|
+
isPinned(name: string): Promise<boolean>;
|
|
67
71
|
/** Count non-empty support subdirectories (richness input for quality scoring). */
|
|
68
72
|
countSupportDirs(name: string): Promise<number>;
|
|
69
73
|
/** Best-effort audit trail entry; never blocks the mutation. */
|
|
70
74
|
private audit;
|
|
71
75
|
/** Recent mutation audit records (read-only inspection surface). */
|
|
72
76
|
listMutations(): Promise<MutationRecord[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Pin or unpin a skill (`.pinned` marker). Pinned skills are protected from
|
|
79
|
+
* deletion, from background-review writes, and from the lifecycle — a
|
|
80
|
+
* protective mutation, so the autonomous pipeline may never call it. The
|
|
81
|
+
* marker write is the only state change; content is untouched.
|
|
82
|
+
*/
|
|
83
|
+
setPinned(name: string, pinned: boolean, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
73
84
|
create(name: string, content: string, origin: 'foreground' | 'background_review'): Promise<SkillActionResult>;
|
|
74
85
|
update(name: string, content: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
75
86
|
patch(name: string, oldString: string, newString: string, filePath?: string, replaceAll?: boolean, origin?: WriteOrigin): Promise<SkillActionResult>;
|
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.
|
|
4
|
+
"version": "0.1.0-rc.28",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|