@lmzhen/dsh-evolution-core 0.1.0-rc.4 → 0.1.0-rc.41
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 +1273 -265
- package/lib/types/constants.d.ts +51 -0
- package/lib/types/curator.d.ts +60 -3
- package/lib/types/index.d.ts +4 -0
- package/lib/types/io.d.ts +7 -2
- package/lib/types/learn-prompt.d.ts +19 -0
- package/lib/types/memory-store.d.ts +38 -9
- package/lib/types/mutations.d.ts +24 -0
- package/lib/types/prompts.d.ts +11 -3
- package/lib/types/quality.d.ts +57 -0
- package/lib/types/skill-store.d.ts +99 -16
- package/lib/types/state-store.d.ts +7 -0
- package/lib/types/threats.d.ts +16 -4
- package/lib/types/usage.d.ts +10 -0
- package/package.json +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared constants for the dsh-evolution plugin family.
|
|
3
|
+
*
|
|
4
|
+
* Two classes of value live here, deliberately separated by section so future
|
|
5
|
+
* edits do not blur the semantic boundary:
|
|
6
|
+
*
|
|
7
|
+
* 1. **Fixed protocol/format/security invariants** — changing these breaks an
|
|
8
|
+
* on-disk format, a naming/format contract, a path-security boundary, or a
|
|
9
|
+
* cross-component invariant. They are NOT exposed as deployment config.
|
|
10
|
+
*
|
|
11
|
+
* 2. **Cross-package shared tunable defaults** — the same semantic default is
|
|
12
|
+
* read (with a config override path) by more than one package (e.g.
|
|
13
|
+
* `evolution-policy` and `evolution-curator` both default `staleAfterDays`
|
|
14
|
+
* to 30). Centralizing them here means one authoritative default: a config
|
|
15
|
+
* override still applies per package, but the fallback is single-sourced.
|
|
16
|
+
*
|
|
17
|
+
* Package-private tunables (used by exactly one package) stay in that package,
|
|
18
|
+
* not here — see evolution-replay's `DEFAULT_WEIGHTS` and evolution-feedback's
|
|
19
|
+
* threshold, which are intentionally left where they are used.
|
|
20
|
+
* @module @deepseek-ai/dsh-evolution-core
|
|
21
|
+
*/
|
|
22
|
+
/** Skill frontmatter `name` validated for the file name (lowercase + hyphen). */
|
|
23
|
+
export declare const SKILL_NAME_RE: RegExp;
|
|
24
|
+
/** Allowed skill support-file subdirectories (path-traversal boundary). */
|
|
25
|
+
export declare const SUPPORT_DIRS: readonly ["references", "templates", "scripts", "assets"];
|
|
26
|
+
/** Delimiter between durable memory entries (on-disk storage format). */
|
|
27
|
+
export declare const ENTRY_DELIMITER = "\n\u00A7\n";
|
|
28
|
+
/** Built-in skill names the curator must never lifecycle-manage. */
|
|
29
|
+
export declare const PROTECTED_BUILTIN_SKILLS: ReadonlySet<string>;
|
|
30
|
+
export declare const MAX_SKILL_NAME_LENGTH = 64;
|
|
31
|
+
export declare const MAX_DESCRIPTION_LENGTH = 1024;
|
|
32
|
+
export declare const MAX_SKILL_CONTENT_CHARS = 100000;
|
|
33
|
+
export declare const MAX_SKILL_FILE_BYTES = 1048576;
|
|
34
|
+
export declare const DEFAULT_REVIEW_MEMORY_INTERVAL = 10;
|
|
35
|
+
export declare const DEFAULT_REVIEW_SKILL_INTERVAL = 10;
|
|
36
|
+
/** Skill-review completion channel trigger mode: 'cadence' | 'completion' | 'both'. */
|
|
37
|
+
export declare const DEFAULT_SKILL_REVIEW_TRIGGER: "both";
|
|
38
|
+
/** Cumulative session tool calls before a session counts as "proven long" for the completion channel. */
|
|
39
|
+
export declare const DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS = 20;
|
|
40
|
+
export declare const DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS = 3;
|
|
41
|
+
export declare const DEFAULT_SUBSTANTIVE_MIN_USER_CHARS = 200;
|
|
42
|
+
export declare const DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS = 500;
|
|
43
|
+
export declare const DEFAULT_MAX_OPS_PER_PLAN = 32;
|
|
44
|
+
export declare const DEFAULT_CURATOR_INTERVAL_HOURS = 168;
|
|
45
|
+
export declare const DEFAULT_MIN_IDLE_HOURS = 2;
|
|
46
|
+
export declare const DEFAULT_STALE_AFTER_DAYS = 30;
|
|
47
|
+
export declare const DEFAULT_ARCHIVE_AFTER_DAYS = 90;
|
|
48
|
+
export declare const DEFAULT_MEMORY_CHAR_LIMIT = 2200;
|
|
49
|
+
export declare const DEFAULT_USER_CHAR_LIMIT = 1375;
|
|
50
|
+
export declare const DEFAULT_SKILL_CONTENT_CHARS = 100000;
|
|
51
|
+
//# sourceMappingURL=constants.d.ts.map
|
package/lib/types/curator.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Deterministic skill curator: active → stale → archived transitions.
|
|
3
|
-
* Pure function
|
|
3
|
+
* Pure function with one deliberate side effect: records in the passed
|
|
4
|
+
* `usage` map are MUTATED (state/archived_at) to carry the transition — the
|
|
5
|
+
* caller owns the map and decides whether to clone first (dry-run) or persist
|
|
6
|
+
* after. File moves are performed by SkillLibrary.
|
|
4
7
|
*/
|
|
5
|
-
import type { UsageMap } from './usage.ts';
|
|
8
|
+
import type { UsageMap, UsageRecord } from './usage.ts';
|
|
9
|
+
export { PROTECTED_BUILTIN_SKILLS } from './constants.ts';
|
|
6
10
|
export interface CuratorConfig {
|
|
7
11
|
staleAfterDays: number;
|
|
8
12
|
archiveAfterDays: number;
|
|
@@ -12,6 +16,14 @@ export interface CuratorConfig {
|
|
|
12
16
|
excludeSkillNames?: ReadonlySet<string>;
|
|
13
17
|
/** When true, usage records without created_by='agent' also enter the lifecycle. */
|
|
14
18
|
manageUnmanaged?: boolean;
|
|
19
|
+
/** When true, bundled skills (in `bundledNames`) are curation candidates like agent-created ones. */
|
|
20
|
+
pruneBuiltins?: boolean;
|
|
21
|
+
/** Skill names carrying the bundled marker; only read when `pruneBuiltins` is true. */
|
|
22
|
+
bundledNames?: ReadonlySet<string>;
|
|
23
|
+
/** Skill names the curator archived once and must not fight across re-seeds. */
|
|
24
|
+
suppressedNames?: ReadonlySet<string>;
|
|
25
|
+
/** Skills referenced by scheduled/automated jobs: never auto-transitioned (idle clocks mislead for rarely-firing tasks). */
|
|
26
|
+
referencedSkillNames?: ReadonlySet<string>;
|
|
15
27
|
}
|
|
16
28
|
export interface CuratorTransition {
|
|
17
29
|
name: string;
|
|
@@ -25,7 +37,6 @@ export interface CuratorResult {
|
|
|
25
37
|
reactivate: string[];
|
|
26
38
|
markStale: string[];
|
|
27
39
|
}
|
|
28
|
-
export declare const PROTECTED_BUILTIN_SKILLS: ReadonlySet<string>;
|
|
29
40
|
export interface CuratorArchivedSkill {
|
|
30
41
|
name: string;
|
|
31
42
|
path: string;
|
|
@@ -36,6 +47,8 @@ export interface CuratorFailedSkill {
|
|
|
36
47
|
reason: string;
|
|
37
48
|
}
|
|
38
49
|
export interface CuratorRunReport {
|
|
50
|
+
/** Report shape version; readers may ignore unknown fields on later versions. */
|
|
51
|
+
schemaVersion: 1;
|
|
39
52
|
runId: string;
|
|
40
53
|
startedAt: string;
|
|
41
54
|
finishedAt: string;
|
|
@@ -45,6 +58,8 @@ export interface CuratorRunReport {
|
|
|
45
58
|
archived: CuratorArchivedSkill[];
|
|
46
59
|
failed: CuratorFailedSkill[];
|
|
47
60
|
snapshotPath?: string;
|
|
61
|
+
/** Whether the LLM nomination pass was enabled for this run (decision visibility). */
|
|
62
|
+
llmReviewEnabled?: boolean;
|
|
48
63
|
}
|
|
49
64
|
export interface CuratorReportInput {
|
|
50
65
|
runId: string;
|
|
@@ -56,7 +71,49 @@ export interface CuratorReportInput {
|
|
|
56
71
|
archived: readonly CuratorArchivedSkill[];
|
|
57
72
|
failed: readonly CuratorFailedSkill[];
|
|
58
73
|
snapshotPath?: string;
|
|
74
|
+
llmReviewEnabled?: boolean;
|
|
59
75
|
}
|
|
60
76
|
export declare function buildCuratorRunReport(input: CuratorReportInput): CuratorRunReport;
|
|
77
|
+
/** One LLM-nominated consolidation: `from` merges into the umbrella `into`. */
|
|
78
|
+
export interface CuratorConsolidation {
|
|
79
|
+
from: string;
|
|
80
|
+
into: string;
|
|
81
|
+
}
|
|
82
|
+
/** Structured result of the optional curator LLM nomination pass. */
|
|
83
|
+
export interface CuratorNominations {
|
|
84
|
+
prunings: string[];
|
|
85
|
+
consolidations: CuratorConsolidation[];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Parse the curator LLM's YAML nomination block (consolidations + prunings).
|
|
89
|
+
* Line-oriented and lenient by design: the LLM output is advisory, every name
|
|
90
|
+
* is re-validated against the tree before any file move happens downstream.
|
|
91
|
+
*/
|
|
92
|
+
export declare function parseCuratorNominations(text: string): CuratorNominations;
|
|
93
|
+
/**
|
|
94
|
+
* The lifecycle-candidate gate, shared by the transition engine and the scope
|
|
95
|
+
* view so the two can never disagree: records failing ANY of these gates are
|
|
96
|
+
* outside the managed scope.
|
|
97
|
+
*/
|
|
98
|
+
export declare function lifecycleCandidate(name: string, record: UsageRecord, config: CuratorConfig, bundled: boolean): boolean;
|
|
99
|
+
export interface ScopeView {
|
|
100
|
+
/** Skills inside the lifecycle scope right now (candidate gate + active state). */
|
|
101
|
+
managed: string[];
|
|
102
|
+
/** Managed skills already flagged stale or quality-warned — the ones to watch. */
|
|
103
|
+
watched: string[];
|
|
104
|
+
/** Managed skills flagged low quality (subset of `watched`) — consolidation candidates. */
|
|
105
|
+
qualityWarned: string[];
|
|
106
|
+
/** Explicitly exempted by excludeSkillNames / referencedSkillNames. */
|
|
107
|
+
exempted: string[];
|
|
108
|
+
/** Carrying a protection marker (pinned / bundled / hub-installed). */
|
|
109
|
+
protected: string[];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Read-only scope classification, derived from the SAME gate the transition
|
|
113
|
+
* engine uses (`lifecycleCandidate`), so the view always predicts what a
|
|
114
|
+
* curator pass may touch. `protectedNames` carries the marker info the usage
|
|
115
|
+
* records lack (bundled / hub-installed / pinned from `SkillLibrary.list()`).
|
|
116
|
+
*/
|
|
117
|
+
export declare function computeScopeView(usage: UsageMap, config: CuratorConfig, protectedNames?: ReadonlyMap<string, string>): ScopeView;
|
|
61
118
|
export declare function computeLifecycleTransitions(usage: UsageMap, config: CuratorConfig, now?: Date): CuratorResult;
|
|
62
119
|
//# sourceMappingURL=curator.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -10,11 +10,15 @@
|
|
|
10
10
|
export * from './curator.ts';
|
|
11
11
|
export * from './events.ts';
|
|
12
12
|
export * from './io.ts';
|
|
13
|
+
export * from './learn-prompt.ts';
|
|
13
14
|
export * from './memory-store.ts';
|
|
15
|
+
export * from './mutations.ts';
|
|
14
16
|
export * from './prompts.ts';
|
|
17
|
+
export * from './quality.ts';
|
|
15
18
|
export * from './signals.ts';
|
|
16
19
|
export * from './skill-store.ts';
|
|
17
20
|
export * from './state-store.ts';
|
|
18
21
|
export * from './threats.ts';
|
|
19
22
|
export * from './usage.ts';
|
|
23
|
+
export * from './constants.ts';
|
|
20
24
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/types/io.d.ts
CHANGED
|
@@ -13,10 +13,15 @@ export interface EvolutionIoLike {
|
|
|
13
13
|
exists(path: string): Promise<boolean>;
|
|
14
14
|
rename(path: string, destination: string): Promise<void>;
|
|
15
15
|
copy(path: string, destination: string): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Optional byte-size probe for the read guard. Return the file's size in
|
|
18
|
+
* bytes, or `null`/`undefined` when unknown (unsupported backend, missing
|
|
19
|
+
* file, stat failure). An implementation without this probe gets no guard:
|
|
20
|
+
* consumers treat an unknown size as "guard not applicable".
|
|
21
|
+
*/
|
|
22
|
+
size?(path: string): Promise<number | null>;
|
|
16
23
|
}
|
|
17
24
|
/** Lazy adapter over an IO provider registry, shared by every evolution consumer. */
|
|
18
25
|
export declare function evolutionIoAdapter(provider: () => EvolutionIoLike): EvolutionIoLike;
|
|
19
26
|
export declare function nodeEvolutionIo(): EvolutionIoLike;
|
|
20
|
-
/** Absolute path helper kept separate so stores stay platform-correct. */
|
|
21
|
-
export declare function childPath(parent: string, ...parts: string[]): string;
|
|
22
27
|
//# sourceMappingURL=io.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open-ended `/evolution learn` prompt builder.
|
|
3
|
+
*
|
|
4
|
+
* `learn` is open-ended: the user can name anything they can describe — a
|
|
5
|
+
* directory of code, an API doc URL, a workflow they just walked the agent
|
|
6
|
+
* through, or pasted notes. The prompt instructs the live agent to gather the
|
|
7
|
+
* named sources with its existing tools, then author a single SKILL.md via
|
|
8
|
+
* `skill_manage` following `DSH_AUTHORING_STANDARDS`. There is no separate
|
|
9
|
+
* distillation engine and no model-tool footprint.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Build the agent prompt for an open-ended `/evolution learn` request.
|
|
13
|
+
*
|
|
14
|
+
* @param userRequest free-text the user gave after `/evolution learn`; an
|
|
15
|
+
* empty string falls back to "the workflow we just went through".
|
|
16
|
+
* @returns a complete instruction the agent runs as a normal turn.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildLearnPrompt(userRequest: string): string;
|
|
19
|
+
//# sourceMappingURL=learn-prompt.d.ts.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Stores are MEMORY.md and USER.md under $DSH_HOME/memories (~/.dsh/memories).
|
|
4
4
|
*/
|
|
5
5
|
import { type EvolutionIoLike } from './io.ts';
|
|
6
|
-
export
|
|
6
|
+
export { ENTRY_DELIMITER } from './constants.ts';
|
|
7
7
|
export type MemoryTarget = 'memory' | 'user';
|
|
8
8
|
export interface MemoryOperation {
|
|
9
9
|
action: 'add' | 'replace' | 'remove';
|
|
@@ -37,24 +37,53 @@ export declare class MemoryStore {
|
|
|
37
37
|
private failureCount;
|
|
38
38
|
constructor(options?: MemoryStoreOptions);
|
|
39
39
|
limitFor(target: MemoryTarget): number;
|
|
40
|
+
/**
|
|
41
|
+
* Read-guard probe: `{ size, limit }` when the on-disk file exceeds
|
|
42
|
+
* `limit * READ_GUARD_FACTOR` bytes, `null` when it is absent, unknown
|
|
43
|
+
* (backend without a size probe), under the bound, or the target has no
|
|
44
|
+
* limit configured.
|
|
45
|
+
*/
|
|
46
|
+
private oversizedFile;
|
|
40
47
|
read(target: MemoryTarget): Promise<string[]>;
|
|
41
48
|
write(target: MemoryTarget, entries: string[]): Promise<void>;
|
|
42
49
|
resetFailures(): void;
|
|
43
50
|
private failure;
|
|
51
|
+
/**
|
|
52
|
+
* StorageHint percentage must clamp at 100 like the render header: a drifted
|
|
53
|
+
* entry can push chars past the limit, and "Storage at 125%" contradicts the
|
|
54
|
+
* clamped usage indicator.
|
|
55
|
+
*/
|
|
56
|
+
private storageHint;
|
|
57
|
+
/**
|
|
58
|
+
* Best-effort raw-copy backup of the on-disk file to `<file>.bak.<stamp>`
|
|
59
|
+
* before a refusal, so an externally modified (or oversized) file stays
|
|
60
|
+
* recoverable. Copies bytes instead of reading them so a pathologically
|
|
61
|
+
* large file is never loaded just to back it up. Failure to back up does
|
|
62
|
+
* not change the refusal semantics.
|
|
63
|
+
*/
|
|
64
|
+
private backupFile;
|
|
65
|
+
/**
|
|
66
|
+
* Read-guard refusal for write paths. Returns the refusal result when the
|
|
67
|
+
* target file is oversized, `null` otherwise. The file is skipped for
|
|
68
|
+
* reading (never loaded), backed up by raw copy, and the model is told to
|
|
69
|
+
* fix it manually — mirroring the drift refusal so corrupted state is never
|
|
70
|
+
* silently overwritten.
|
|
71
|
+
*/
|
|
72
|
+
private oversizedRefusal;
|
|
44
73
|
add(target: MemoryTarget, facts: string): Promise<MemoryApplyResult>;
|
|
45
74
|
replace(target: MemoryTarget, oldText: string, facts: string): Promise<MemoryApplyResult>;
|
|
46
75
|
remove(target: MemoryTarget, oldText: string): Promise<MemoryApplyResult>;
|
|
47
76
|
private mutate;
|
|
48
77
|
applyBatch(target: MemoryTarget, operations: MemoryOperation[]): Promise<MemoryApplyResult>;
|
|
49
78
|
renderContext(): Promise<string>;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Detect on-disk drift: true when the file is not in the canonical
|
|
81
|
+
* `render(normalizeEntries(raw))` form. This catches structural anomalies
|
|
82
|
+
* the writer would quietly normalize away (empty/`§`-only entries, stray
|
|
83
|
+
* blank lines, leading/trailing delimiters) that indicate the file was
|
|
84
|
+
* edited outside MemoryStore. Purely single-canonical content reaches the
|
|
85
|
+
* same serialization and returns false, so a normal write is never flagged.
|
|
86
|
+
*/
|
|
58
87
|
detectDrift(target: MemoryTarget): Promise<boolean>;
|
|
59
88
|
}
|
|
60
89
|
//# sourceMappingURL=memory-store.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curator/author audit trail: `.mutations.json` records every skill mutation
|
|
3
|
+
* with before/after content hashes so any automated edit is reviewable and
|
|
4
|
+
* replayable. Best-effort persistence, mirroring the usage sidecar posture.
|
|
5
|
+
* @module @deepseek-ai/dsh-evolution-core
|
|
6
|
+
*/
|
|
7
|
+
import { type EvolutionIoLike } from './io.ts';
|
|
8
|
+
export interface MutationRecord {
|
|
9
|
+
skillName: string;
|
|
10
|
+
action: string;
|
|
11
|
+
beforeHash?: string;
|
|
12
|
+
afterHash?: string;
|
|
13
|
+
summary: string;
|
|
14
|
+
at: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const DEFAULT_MUTATION_CAP = 500;
|
|
17
|
+
/** Version of the `.mutations.json` file shape; writers always emit the current one. */
|
|
18
|
+
export declare const MUTATIONS_FILE_VERSION = 1;
|
|
19
|
+
export declare function mutationsFile(root: string): string;
|
|
20
|
+
export declare function contentHash(content: string): string;
|
|
21
|
+
export declare function loadMutations(root: string, io?: EvolutionIoLike): Promise<MutationRecord[]>;
|
|
22
|
+
/** Append one record, trim to `cap`, and write atomically (versioned shape). */
|
|
23
|
+
export declare function recordMutation(root: string, io: EvolutionIoLike, record: MutationRecord, cap?: number): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=mutations.d.ts.map
|
package/lib/types/prompts.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Prompt bundle identity. Bump both id and version whenever a prompt's text
|
|
3
|
+
* changes semantically: the bundle digest is the fail-closed signal for
|
|
4
|
+
* review workers, so a stale id across deployments must be distinguishable.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PROMPT_BUNDLE_ID = "dsh-evolution@2";
|
|
7
|
+
export declare const PROMPT_BUNDLE_VERSION = 2;
|
|
2
8
|
export declare const MEMORY_REVIEW_PROMPT = "[Auto-review \u2014 Memory]\nReview the conversation above and consider saving to memory if appropriate.\n\nFocus on:\n1. Has the user revealed things about themselves \u2014 persona, desires, preferences, or personal details worth remembering?\n2. Has the user expressed expectations about how you should behave, their work style, or ways they want you to operate?\n\nIf something stands out, save it using the memory tool.\nIf nothing is worth saving, just say \"Nothing to save.\" and stop.";
|
|
3
9
|
export declare const SKILL_REVIEW_PROMPT = "[Auto-review \u2014 Skills]\nReview the conversation above and update the skill library. Be ACTIVE \u2014 most sessions produce at least one skill update, even if small.\n\nTarget shape: CLASS-LEVEL skills with a rich SKILL.md and a references/ directory for session-specific detail. Not a flat list of narrow one-session skills.\n\nSignals that warrant action:\n- The user corrected your style, tone, format, verbosity, workflow, or approach.\n- A non-trivial technique, fix, workaround, or debugging path emerged.\n- A loaded skill turned out wrong, missing, or outdated \u2014 patch it now.\n\nPreference order:\n1. Patch a skill that was loaded or read this session.\n2. Patch an existing umbrella skill.\n3. Add references/, templates/, or scripts/ support under an existing skill.\n4. Create a new class-level umbrella skill only when nothing fits.\n\nProtected skills (bundled/hub-installed) must not be edited. Pinned skills may be patched but not archived.\n\nDo NOT capture:\n- Environment-dependent failures (missing binaries, unconfigured credentials).\n- Negative claims about tools (\"browser tools do not work\").\n- Transient errors that resolved during the session.\n- One-off task narratives.\n\nIf a tool failed because of setup state, capture the FIX under an existing setup skill \u2014 never \"this tool does not work\" as a standalone constraint.\n\n\"Nothing to save.\" is a real option but should NOT be the default.";
|
|
4
10
|
export declare const COMBINED_REVIEW_PROMPT = "[Auto-review]\nReview the conversation above and update two things.\n\n**Memory**: who the user is. Save durable user preferences, personal details, and expectations with the memory tool.\n\n**Skills**: how to do this class of task. Be ACTIVE. Follow the same class-level umbrella policy, preference order, protected-skill rules, and do-not-capture list as a skill review.\n\nAct on whichever dimension has real signal. If genuinely nothing stands out on either, say \"Nothing to save.\" and stop \u2014 but don't reach for that conclusion as a default.";
|
|
5
|
-
export declare const CURATOR_PROMPT = "You are the skill curator. Maintain a healthy, class-level skill library.\n\
|
|
11
|
+
export declare const CURATOR_PROMPT = "You are the skill curator. Maintain a healthy, class-level skill library, not a flat pile of narrow one-session skills.\n\nThe goal is a LIBRARY OF CLASS-LEVEL INSTRUCTIONS. A skill collection of many narrow skills where each captures one session's specific bug is a FAILURE of the library. An agent searching skills matches on descriptions, not exact names; one broad umbrella with labeled subsections beats five narrow siblings for discoverability.\n\nRight target shape: class-level skills with rich SKILL.md + references/, templates/, scripts/ support files for session-specific detail.\n\nHard rules:\n1. NEVER hard-delete a skill. Archive (moving to .archive/) is the maximum destructive action; archives are recoverable, deletion is not.\n2. Do not touch bundled, hub-installed, pinned, or scheduled-task-referenced (`referenced`) skills. Referenced skills MAY be consolidated into an umbrella, but never simply pruned.\n3. Do not archive recently-created or never-used skills without strong evidence. \"use=0\" is NOT evidence either way \u2014 it only means the trigger has not come up yet.\n4. Do NOT reject consolidation on the grounds that \"each skill has a distinct trigger\". The right bar is: would a human maintainer write this as N separate skills, or one skill with N labeled subsections? When the answer is the latter, merge.\n5. Judge overlap on CONTENT, not on usage counters.\n6. Before archiving a merged skill, ensure its unique content was preserved in the umbrella.\n\nHow to work:\n1. Scan the candidate list. Identify PREFIX CLUSTERS \u2014 skills sharing a first word or domain keyword (expect 10-25 clusters).\n2. For each cluster with 2+ members, ask \"what is the UMBRELLA CLASS these skills serve?\" and consolidate:\n a. MERGE INTO AN EXISTING UMBRELLA (patch a labeled section for each sibling's unique insight, then archive the siblings).\n b. CREATE A NEW UMBRELLA SKILL.md covering the shared workflow with short labeled subsections, then archive the absorbed siblings.\n c. DEMOTE session-specific detail to references/, templates/, or scripts/ under the umbrella.\n3. Keep the umbrella body tight and scannable: exact commands, verbatim paths, ~100-200 lines; never invent flags or APIs.\n\nProduce a YAML summary with exactly this shape:\nconsolidations:\n - from: <old-skill-name>\n into: <umbrella-skill-name>\n reason: <one short sentence>\nprunings:\n - name: <skill-name>\n reason: <one short sentence>\nNominate a pruning only when archival is clearly safe (stale AND genuinely obsolete or fully absorbed elsewhere).";
|
|
12
|
+
export declare const CURATOR_DRY_RUN_BANNER = "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nDRY-RUN \u2014 REPORT ONLY. DO NOT MUTATE THE SKILL LIBRARY.\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nThis is a PREVIEW pass. Follow every instruction above EXCEPT:\n \u2022 Do NOT call skill_manage with action=create, update, patch, delete, write_file, or remove_file.\n \u2022 Do NOT move, copy, or rewrite any file under the skills tree.\n\nYour output IS the deliverable: produce the exact same human-readable summary and YAML block you would on a live run, describing the actions you WOULD take. A reviewer will decide whether to approve a live run.\n\nIf you accidentally take a mutating action, say so explicitly in the summary.";
|
|
13
|
+
export declare const COMPLETION_SKILL_REVIEW_PROMPT = "[Auto-review \u2014 Skills \u00B7 task complete]\nYour current task now appears complete. Before wrapping up, review the approach and update the skill library via skill_manage.\n\nFollow the skills review policy: be ACTIVE, prefer class-level umbrellas, patch skills loaded this session, and capture non-trivial techniques and user corrections. Do NOT capture environment-dependent failures, negative claims about tools, or one-off task narratives.\n\nDo NOT modify output files or re-run the task. If you are still mid-task, ignore this.";
|
|
6
14
|
export declare function reviewPrompt(kind: 'memory' | 'skill' | 'combined'): string;
|
|
7
15
|
export interface PromptBundle {
|
|
8
16
|
id: string;
|
|
@@ -12,5 +20,5 @@ export interface PromptBundle {
|
|
|
12
20
|
}
|
|
13
21
|
export declare const PROMPT_BUNDLE: PromptBundle;
|
|
14
22
|
export declare function verifyPromptBundle(bundle?: PromptBundle): boolean;
|
|
15
|
-
export declare const DSH_AUTHORING_STANDARDS = "Follow the Hermes skill-authoring standards, translated to DSH tools.\n\nFrontmatter:\n- name: lowercase-hyphenated, <=64 chars, no spaces.\n- description: ONE sentence, <=60 characters, ends with a period. State the capability, not the implementation. No marketing words. Do NOT repeat the skill name. Count the characters before saving.\n- version: 0.1.0\n- author: always the literal value \"Hermes\". NEVER fill it from the environment, git config, or any identity you can probe.\n- platforms: declare [macos], [linux], and/or [windows] only when the skill is genuinely OS-bound; omit for portable skills.\n- metadata.hermes.tags: a few Capitalized, Relevant, Tags.\n\nBody section order (omit only when empty):\n1. \"# <Human Title>\" then a 2-3 sentence intro: what it does, what it does NOT do, key dependency stance.\n2. \"## When to Use\" \u2014 concrete trigger phrases.\n3. \"## Prerequisites\" \u2014 exact env vars, install steps, credentials.\n4. \"## How to Run\" \u2014 canonical invocation framed through DSH tools.\n5. \"## Quick Reference\" \u2014 flat command/endpoint list.\n6. \"## Procedure\" \u2014 numbered steps with copy-paste-exact commands.\n7. \"## Pitfalls\" \u2014 known limits and rate limits.\n8. \"## Verification\" \u2014 one check proving the skill worked.\n\nDSH-tool framing:\n- Reference DSH tools by name in backticks: `bash`, `str_replace_editor`, `write`, `skill`, `skill_manage`, `memory`.\n- Do not name wrapped shell utilities when a DSH tool already covers them.\n- Larger scripts belong under `scripts/` (written with `skill_manage write_file`) and are referenced from SKILL.md by relative path.\n\nQuality bar:\n- Prefer verbatim flags, paths, and APIs from the source. Never invent them.\n- Keep it tight: ~100 lines simple, ~200 complex.\n- No router/index/hub skills that only point at other skills.\n- References go in `references/`, templates in `templates/`.";
|
|
23
|
+
export declare const DSH_AUTHORING_STANDARDS = "Follow the Hermes skill-authoring standards, translated to DSH tools.\n\nFrontmatter:\n- name: lowercase-hyphenated, <=64 chars, no spaces.\n- description: ONE sentence, <=60 characters, ends with a period. State the capability, not the implementation. No marketing words. Do NOT repeat the skill name. Count the characters before saving.\n- version: 0.1.0\n- author: always the literal value \"Hermes\". NEVER fill it from the environment, git config, or any identity you can probe.\n- platforms: declare [macos], [linux], and/or [windows] only when the skill is genuinely OS-bound; omit for portable skills.\n- metadata.hermes.tags: a few Capitalized, Relevant, Tags.\n- metadata.hermes.related_skills: [a, b] \u2014 name sibling skills this one builds on or is referenced by (optional; feeds the quality references factor).\n\nBody section order (omit only when empty):\n1. \"# <Human Title>\" then a 2-3 sentence intro: what it does, what it does NOT do, key dependency stance.\n2. \"## When to Use\" \u2014 concrete trigger phrases.\n3. \"## Prerequisites\" \u2014 exact env vars, install steps, credentials.\n4. \"## How to Run\" \u2014 canonical invocation framed through DSH tools.\n5. \"## Quick Reference\" \u2014 flat command/endpoint list.\n6. \"## Procedure\" \u2014 numbered steps with copy-paste-exact commands.\n7. \"## Pitfalls\" \u2014 known limits and rate limits.\n8. \"## Verification\" \u2014 one check proving the skill worked.\n\nDSH-tool framing:\n- Reference DSH tools by name in backticks: `bash`, `str_replace_editor`, `write`, `skill`, `skill_manage`, `memory`.\n- Do not name wrapped shell utilities when a DSH tool already covers them.\n- Larger scripts belong under `scripts/` (written with `skill_manage write_file`) and are referenced from SKILL.md by relative path.\n\nQuality bar:\n- Prefer verbatim flags, paths, and APIs from the source. Never invent them.\n- Keep it tight: ~100 lines simple, ~200 complex.\n- No router/index/hub skills that only point at other skills.\n- References go in `references/`, templates in `templates/`.";
|
|
16
24
|
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality scoring and near-duplicate detection for the curated skill library.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions over data inputs so the scoring policy is unit-testable and
|
|
5
|
+
* the same math feeds the usage sidecar, the `skill_manage review` surface and
|
|
6
|
+
* the learning graph. Weights follow the Hermes/hermes-claw six-factor model;
|
|
7
|
+
* mutation maturity is a documented DSH approximation (single per-month patch
|
|
8
|
+
* trend ratio replaces the claw timestamp-trend formula, since DSH usage
|
|
9
|
+
* records only carry the last patched timestamp).
|
|
10
|
+
* @module @deepseek-ai/dsh-evolution-core
|
|
11
|
+
*/
|
|
12
|
+
import type { UsageMap } from './usage.ts';
|
|
13
|
+
export interface QualityFactors {
|
|
14
|
+
/** 0.25 — use_count per day of age, capped at 1. */
|
|
15
|
+
usageFrequency: number;
|
|
16
|
+
/** 0.20 — 1 − patch/use (zero use = stable). */
|
|
17
|
+
stability: number;
|
|
18
|
+
/** 0.20 — 1 under 30 idle days, linear decay to 0 at 180. */
|
|
19
|
+
recency: number;
|
|
20
|
+
/** 0.10 — in-degree / 3 (graph references), capped at 1. */
|
|
21
|
+
references: number;
|
|
22
|
+
/** 0.20 — patch cadence maturity (DSH approximation of the trend formula). */
|
|
23
|
+
mutationMaturity: number;
|
|
24
|
+
/** 0.05 — non-empty support subdirectories × 0.175, capped at 1. */
|
|
25
|
+
richness: number;
|
|
26
|
+
}
|
|
27
|
+
export interface QualityScore {
|
|
28
|
+
score: number;
|
|
29
|
+
factors: QualityFactors;
|
|
30
|
+
warn: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare const QUALITY_WEIGHTS: {
|
|
33
|
+
readonly usageFrequency: 0.25;
|
|
34
|
+
readonly stability: 0.2;
|
|
35
|
+
readonly recency: 0.2;
|
|
36
|
+
readonly references: 0.1;
|
|
37
|
+
readonly mutationMaturity: 0.2;
|
|
38
|
+
readonly richness: 0.05;
|
|
39
|
+
};
|
|
40
|
+
/** Score below which a skill is flagged for review. */
|
|
41
|
+
export declare const LOW_QUALITY_THRESHOLD = 0.3;
|
|
42
|
+
export declare function computeQualityScores(input: {
|
|
43
|
+
usage: UsageMap;
|
|
44
|
+
referenceCounts?: ReadonlyMap<string, number>;
|
|
45
|
+
supportDirs?: ReadonlyMap<string, number>;
|
|
46
|
+
now?: Date;
|
|
47
|
+
}): Map<string, QualityScore>;
|
|
48
|
+
/**
|
|
49
|
+
* Two-phase near-duplicate clustering: exact normalized-hash groups first,
|
|
50
|
+
* then token-Jaccard edges at {@link DEDUP_SIMILARITY_THRESHOLD} with a token
|
|
51
|
+
* ratio guard, union-find across the whole set.
|
|
52
|
+
*/
|
|
53
|
+
export declare function computeDedupGroups(input: {
|
|
54
|
+
contents: ReadonlyMap<string, string>;
|
|
55
|
+
threshold?: number;
|
|
56
|
+
}): string[][];
|
|
57
|
+
//# sourceMappingURL=quality.d.ts.map
|
|
@@ -7,11 +7,7 @@
|
|
|
7
7
|
* move to `.archive/` — never a hard delete.
|
|
8
8
|
*/
|
|
9
9
|
import { type EvolutionIoLike } from './io.ts';
|
|
10
|
-
|
|
11
|
-
export declare const MAX_SKILL_NAME_LENGTH = 64;
|
|
12
|
-
export declare const MAX_DESCRIPTION_LENGTH = 1024;
|
|
13
|
-
export declare const MAX_SKILL_CONTENT_CHARS = 100000;
|
|
14
|
-
export declare const MAX_SKILL_FILE_BYTES = 1048576;
|
|
10
|
+
import { type MutationRecord } from './mutations.ts';
|
|
15
11
|
export interface SkillLimits {
|
|
16
12
|
maxNameLength: number;
|
|
17
13
|
maxDescriptionLength: number;
|
|
@@ -19,7 +15,6 @@ export interface SkillLimits {
|
|
|
19
15
|
maxSkillFileBytes: number;
|
|
20
16
|
}
|
|
21
17
|
export declare const DEFAULT_SKILL_LIMITS: SkillLimits;
|
|
22
|
-
export declare const SUPPORT_DIRS: readonly ["references", "templates", "scripts", "assets"];
|
|
23
18
|
export interface SkillSummary {
|
|
24
19
|
name: string;
|
|
25
20
|
description: string;
|
|
@@ -33,6 +28,37 @@ export interface SkillActionResult {
|
|
|
33
28
|
message: string;
|
|
34
29
|
path?: string;
|
|
35
30
|
}
|
|
31
|
+
/** Extra file name carried inside a snapshot's `extras/` directory. */
|
|
32
|
+
export declare const SNAPSHOT_EXTRA_NAME_RE: RegExp;
|
|
33
|
+
/** An opaque side file stored under a snapshot's `extras/` (curator state etc.). */
|
|
34
|
+
export interface SnapshotExtra {
|
|
35
|
+
name: string;
|
|
36
|
+
content: string;
|
|
37
|
+
}
|
|
38
|
+
/** Normalized manifest of a skills snapshot. */
|
|
39
|
+
export interface SnapshotManifest {
|
|
40
|
+
reason: string;
|
|
41
|
+
createdAt: string;
|
|
42
|
+
/** Active skill names at snapshot time. */
|
|
43
|
+
skills: string[];
|
|
44
|
+
/** Co-copied sidecar file names (usage/suppression). */
|
|
45
|
+
sidecars: string[];
|
|
46
|
+
/** Whether `.archive/` was co-copied; absent on legacy manifests (do not touch archive on restore). */
|
|
47
|
+
hasArchive?: boolean;
|
|
48
|
+
/** Extras declared under `extras/`; only these names are ever read back. */
|
|
49
|
+
extras: string[];
|
|
50
|
+
}
|
|
51
|
+
/** Who is writing: a foreground user-directed tool call, or the autonomous review/curator pipeline. */
|
|
52
|
+
export type WriteOrigin = 'foreground' | 'subagent' | 'background_review';
|
|
53
|
+
/** Options for `SkillLibrary.archive`. The absorbed-into name and the archival reason are distinct fields. */
|
|
54
|
+
export interface ArchiveOptions {
|
|
55
|
+
/** Umbrella skill this one was consolidated into; when set it must exist (consolidate semantics). */
|
|
56
|
+
absorbedInto?: string;
|
|
57
|
+
/** Human-readable reason written to `.archive-reason`; default derives from `absorbedInto`. */
|
|
58
|
+
reason?: string;
|
|
59
|
+
/** Permit archiving a bundled skill (curator prune-builtins only; hub-installed and pinned stay protected). */
|
|
60
|
+
allowBundled?: boolean;
|
|
61
|
+
}
|
|
36
62
|
export declare function skillsRoot(env?: NodeJS.ProcessEnv): string;
|
|
37
63
|
export interface Frontmatter {
|
|
38
64
|
name?: string;
|
|
@@ -51,21 +77,78 @@ export declare class SkillLibrary {
|
|
|
51
77
|
constructor(root?: string, io?: EvolutionIoLike, limits?: SkillLimits);
|
|
52
78
|
list(): Promise<SkillSummary[]>;
|
|
53
79
|
read(name: string): Promise<string | null>;
|
|
54
|
-
|
|
55
|
-
|
|
80
|
+
/** Name-format guard shared by every path-building mutator/reader. */
|
|
81
|
+
private badName;
|
|
82
|
+
writeProtection(name: string, origin?: WriteOrigin): Promise<string | null>;
|
|
83
|
+
deleteProtection(name: string, options?: {
|
|
84
|
+
allowBundled?: boolean;
|
|
85
|
+
}): Promise<string | null>;
|
|
56
86
|
isManaged(name: string): Promise<boolean>;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
87
|
+
/** Whether the skill carries the bundled marker (curator prune-builtins eligibility). */
|
|
88
|
+
isBundled(name: string): Promise<boolean>;
|
|
89
|
+
/** Whether the skill carries the pinned marker (the marker is the factual source; usage.pinned mirrors it). */
|
|
90
|
+
isPinned(name: string): Promise<boolean>;
|
|
91
|
+
/** Count non-empty support subdirectories (richness input for quality scoring). */
|
|
92
|
+
countSupportDirs(name: string): Promise<number>;
|
|
93
|
+
/** Best-effort audit trail entry; never blocks the mutation. */
|
|
94
|
+
private audit;
|
|
95
|
+
/** Recent mutation audit records (read-only inspection surface). */
|
|
96
|
+
listMutations(): Promise<MutationRecord[]>;
|
|
97
|
+
/**
|
|
98
|
+
* Pin or unpin a skill (`.pinned` marker). Pinned skills are protected from
|
|
99
|
+
* deletion, from background-review writes, and from the lifecycle — a
|
|
100
|
+
* protective mutation, so the autonomous pipeline may never call it. The
|
|
101
|
+
* marker write is the only state change; content is untouched.
|
|
102
|
+
*/
|
|
103
|
+
setPinned(name: string, pinned: boolean, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
104
|
+
create(name: string, content: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
105
|
+
update(name: string, content: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
106
|
+
patch(name: string, oldString: string, newString: string, filePath?: string, replaceAll?: boolean, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
107
|
+
archive(name: string, options?: ArchiveOptions): Promise<SkillActionResult>;
|
|
108
|
+
/**
|
|
109
|
+
* Merge the bodies of `sources` into `target` and archive the sources with
|
|
110
|
+
* an absorbed-into marker. Hermes-style consolidation: overlapping skills
|
|
111
|
+
* collapse into one, and the originals stay recoverable under `.archive/`.
|
|
112
|
+
*/
|
|
113
|
+
consolidate(target: string, sources: string[], origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
114
|
+
/**
|
|
115
|
+
* Restore one skill from `.archive/` back to the active root. Hermes-style
|
|
116
|
+
* recoverability: archival never deletes, and this is the control-plane
|
|
117
|
+
* path back. The `.archive-reason` marker is dropped on restore.
|
|
118
|
+
*/
|
|
119
|
+
restoreFromArchive(name: string): Promise<SkillActionResult>;
|
|
120
|
+
writeSupportFile(name: string, filePath: string, content: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
121
|
+
removeSupportFile(name: string, filePath: string, origin?: WriteOrigin): Promise<SkillActionResult>;
|
|
122
|
+
/**
|
|
123
|
+
* Snapshot the recoverable skills state: active tree, usage/suppression
|
|
124
|
+
* sidecars, `.archive/` and caller-supplied extras. `extras` are opaque
|
|
125
|
+
* side files the Snapshot owner cares about (curator state); they are
|
|
126
|
+
* listed in the manifest and only those names are ever read back.
|
|
127
|
+
*/
|
|
128
|
+
snapshotAll(reason?: string, extras?: SnapshotExtra[]): Promise<string>;
|
|
129
|
+
/** Read and normalize a snapshot manifest; null when the file is missing or unparsable. */
|
|
130
|
+
readSnapshotManifest(path: string): Promise<SnapshotManifest | null>;
|
|
131
|
+
/** Keep only the newest N snapshots (Hermes keep=5 parity); oldest folded into .backups history. */
|
|
132
|
+
private retainSnapshots;
|
|
64
133
|
listSnapshots(): Promise<Array<{
|
|
65
134
|
path: string;
|
|
66
135
|
createdAt: string;
|
|
67
136
|
reason: string;
|
|
68
137
|
}>>;
|
|
69
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Read the extras of a snapshot, restricted to the names declared in the
|
|
140
|
+
* manifest — an `extras/` directory is never listed directly, so unknown
|
|
141
|
+
* files cannot leak back as state on the next restore.
|
|
142
|
+
*/
|
|
143
|
+
readSnapshotExtras(path: string): Promise<SnapshotExtra[]>;
|
|
144
|
+
/**
|
|
145
|
+
* Manifest-driven restore of the latest snapshot: active tree, sidecars,
|
|
146
|
+
* `.archive/` and (for full-state snapshots) the extras read back by the
|
|
147
|
+
* caller. `extras` are additionally written into the pre-rollback safety
|
|
148
|
+
* snapshot so the rollback itself is undoable with the same state.
|
|
149
|
+
*/
|
|
150
|
+
restoreLatestSnapshot(extras?: SnapshotExtra[]): Promise<SkillActionResult & {
|
|
151
|
+
extras?: SnapshotExtra[];
|
|
152
|
+
}>;
|
|
70
153
|
}
|
|
71
154
|
//# sourceMappingURL=skill-store.d.ts.map
|
|
@@ -8,6 +8,13 @@ export declare class JsonState<T> {
|
|
|
8
8
|
readonly path: string;
|
|
9
9
|
private value;
|
|
10
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;
|
|
11
18
|
private loadSync;
|
|
12
19
|
get(): T;
|
|
13
20
|
set(value: T): void;
|
package/lib/types/threats.d.ts
CHANGED
|
@@ -12,17 +12,29 @@ export interface ThreatFinding {
|
|
|
12
12
|
category: string;
|
|
13
13
|
scope: ThreatScope;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Optional scan controls. Default behavior (`options` omitted) is unchanged:
|
|
17
|
+
* every in-scope pattern blocks. Adapters that need to tolerate a specific
|
|
18
|
+
* benign phrasing (e.g. a skill that legitimately opens with "You are now a ...")
|
|
19
|
+
* can exclude that label by name here. This is opt-in and never widens strict
|
|
20
|
+
* scope; it only permits callers to drop a known-innocent match.
|
|
21
|
+
*/
|
|
22
|
+
export interface ScanOptions {
|
|
23
|
+
/** Pattern labels to skip during this scan. */
|
|
24
|
+
excludeLabels?: readonly string[];
|
|
25
|
+
}
|
|
15
26
|
/**
|
|
16
27
|
* Scan text at `scope`. Patterns are cumulative: `strict` includes all scopes.
|
|
28
|
+
* `options.excludeLabels` removes matching patterns without changing `scope`.
|
|
17
29
|
*/
|
|
18
|
-
export declare function scanThreats(text: string, scope?: ThreatScope, maxScanChars?: number): ThreatFinding[];
|
|
30
|
+
export declare function scanThreats(text: string, scope?: ThreatScope, maxScanChars?: number, options?: ScanOptions): ThreatFinding[];
|
|
19
31
|
/** Blocking policy: any hit blocks. `severity` is deliberately not a gate. */
|
|
20
|
-
export declare function evaluateThreat(text: string, scope?: ThreatScope, maxScanChars?: number): {
|
|
32
|
+
export declare function evaluateThreat(text: string, scope?: ThreatScope, maxScanChars?: number, options?: ScanOptions): {
|
|
21
33
|
blocked: boolean;
|
|
22
34
|
findings: ThreatFinding[];
|
|
23
35
|
};
|
|
24
36
|
/** User-facing block message for memory writes. */
|
|
25
|
-
export declare function scanMemoryThreats(text: string, maxScanChars?: number): string | null;
|
|
37
|
+
export declare function scanMemoryThreats(text: string, maxScanChars?: number, options?: ScanOptions): string | null;
|
|
26
38
|
/** User-facing block message for skill content writes. */
|
|
27
|
-
export declare function scanContentThreats(text: string, maxScanChars?: number): string | null;
|
|
39
|
+
export declare function scanContentThreats(text: string, maxScanChars?: number, options?: ScanOptions): string | null;
|
|
28
40
|
//# sourceMappingURL=threats.d.ts.map
|
package/lib/types/usage.d.ts
CHANGED
|
@@ -30,4 +30,14 @@ export declare function bumpUse(map: UsageMap, name: string, when?: Date): void;
|
|
|
30
30
|
export declare function bumpPatch(map: UsageMap, name: string, when?: Date): void;
|
|
31
31
|
export declare function markAgentCreated(map: UsageMap, name: string): void;
|
|
32
32
|
export declare function latestActivityAt(record: UsageRecord): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Curator suppression sidecar: built-in skills the curator has archived stay
|
|
35
|
+
* suppressed across re-seeds, so the lifecycle never fights a re-created
|
|
36
|
+
* bundled skill. Best-effort load/save, mirroring the usage sidecar posture.
|
|
37
|
+
* Versioned shape ({ version, names }) with legacy plain-array compat.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SUPPRESSED_FILE_VERSION = 1;
|
|
40
|
+
export declare function suppressedFile(root: string): string;
|
|
41
|
+
export declare function loadSuppressedNames(root: string, io?: EvolutionIoLike): Promise<ReadonlySet<string>>;
|
|
42
|
+
export declare function saveSuppressedNames(root: string, names: ReadonlySet<string>, io?: EvolutionIoLike): Promise<void>;
|
|
33
43
|
//# sourceMappingURL=usage.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.
|
|
4
|
+
"version": "0.1.0-rc.41",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|