dsh-continual-evolve 0.1.0

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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +290 -0
  3. package/README.zh.md +240 -0
  4. package/cordis.patch.yml +9 -0
  5. package/lib/apply.d.ts +24 -0
  6. package/lib/apply.js +131 -0
  7. package/lib/approval.d.ts +14 -0
  8. package/lib/approval.js +27 -0
  9. package/lib/auto.d.ts +34 -0
  10. package/lib/auto.js +217 -0
  11. package/lib/benchmark.d.ts +72 -0
  12. package/lib/benchmark.js +167 -0
  13. package/lib/command.d.ts +36 -0
  14. package/lib/command.js +549 -0
  15. package/lib/evaluate.d.ts +38 -0
  16. package/lib/evaluate.js +142 -0
  17. package/lib/goal.d.ts +72 -0
  18. package/lib/goal.js +72 -0
  19. package/lib/index.d.ts +93 -0
  20. package/lib/index.js +116 -0
  21. package/lib/inject.d.ts +124 -0
  22. package/lib/inject.js +231 -0
  23. package/lib/logfile.d.ts +71 -0
  24. package/lib/logfile.js +159 -0
  25. package/lib/mount.d.ts +42 -0
  26. package/lib/mount.js +198 -0
  27. package/lib/notify.d.ts +31 -0
  28. package/lib/notify.js +42 -0
  29. package/lib/plan.d.ts +16 -0
  30. package/lib/plan.js +121 -0
  31. package/lib/planner.d.ts +30 -0
  32. package/lib/planner.js +110 -0
  33. package/lib/pool.d.ts +7 -0
  34. package/lib/pool.js +25 -0
  35. package/lib/render.d.ts +15 -0
  36. package/lib/render.js +83 -0
  37. package/lib/review.d.ts +37 -0
  38. package/lib/review.js +127 -0
  39. package/lib/rollback.d.ts +11 -0
  40. package/lib/rollback.js +69 -0
  41. package/lib/rubric.d.ts +29 -0
  42. package/lib/rubric.js +119 -0
  43. package/lib/score.d.ts +31 -0
  44. package/lib/score.js +81 -0
  45. package/lib/service.d.ts +30 -0
  46. package/lib/service.js +42 -0
  47. package/lib/skill.d.ts +10 -0
  48. package/lib/skill.js +75 -0
  49. package/lib/source.d.ts +29 -0
  50. package/lib/source.js +42 -0
  51. package/lib/state.d.ts +34 -0
  52. package/lib/state.js +154 -0
  53. package/lib/store.d.ts +20 -0
  54. package/lib/store.js +74 -0
  55. package/lib/tool.d.ts +15 -0
  56. package/lib/tool.js +163 -0
  57. package/lib/types.d.ts +137 -0
  58. package/lib/types.js +62 -0
  59. package/lib/validate.d.ts +11 -0
  60. package/lib/validate.js +55 -0
  61. package/package.json +67 -0
package/lib/types.d.ts ADDED
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Type model for the continual-evolution harness state.
3
+ *
4
+ * Design provenance: the state model follows the continual-harness design
5
+ * validated in prime-agent's `/refine` subsystem (MIT): versioned entries
6
+ * keyed by kind, an append-only refinement history carrying an evidence
7
+ * trail, atomic persistence, and deterministic inverse-op rollback. The
8
+ * code here is an original implementation, written for the DeepSeek Harness
9
+ * plugin surface.
10
+ */
11
+ /** What a harness entry can be. */
12
+ export type RefinementKind = "prompt" | "memory" | "skill" | "subagent";
13
+ /** How an entry changes. */
14
+ export type RefinementAction = "create" | "update" | "delete" | "archive";
15
+ /** Where an entry lives: session-scoped or cross-session. */
16
+ export type HarnessScope = "local" | "global";
17
+ /**
18
+ * Metadata key recording which session an entry's content was distilled from
19
+ * (trajectory citation; see {@link EntrySource}).
20
+ */
21
+ export declare const SOURCE_SESSION_KEY = "sourceSession";
22
+ /**
23
+ * Metadata key recording the session-log event seqs (of the direct user
24
+ * messages) the entry cites as its source (trajectory citation).
25
+ */
26
+ export declare const SOURCE_SEQS_KEY = "sourceSeqs";
27
+ /**
28
+ * Metadata key recording when an entry was archived. Archived entries are
29
+ * hidden from injection but never deleted — the data stays in the store and
30
+ * the entry can be restored (unarchive) or rolled back like any other edit.
31
+ */
32
+ export declare const ARCHIVED_AT_KEY = "archivedAt";
33
+ /**
34
+ * True when the entry is archived (hidden from injection, restorable).
35
+ * Absent or empty archivedAt means the entry is active.
36
+ */
37
+ export declare function isArchived(entry: HarnessEntry): boolean;
38
+ /**
39
+ * Trajectory citation attached to newly created entries: the session the
40
+ * content came from and the seqs of the direct user messages it was
41
+ * distilled from. Both fields are optional — when they cannot be determined
42
+ * the citation is simply omitted (never an error).
43
+ */
44
+ export interface EntrySource {
45
+ sessionId?: string;
46
+ /** Event seqs of the source user messages, in log order. */
47
+ seqs?: number[];
48
+ }
49
+ /** A single persisted harness entry. */
50
+ export interface HarnessEntry {
51
+ id: string;
52
+ kind: RefinementKind;
53
+ title: string;
54
+ content: string;
55
+ path: string;
56
+ scope: HarnessScope;
57
+ /** Skill entries carry an executable contract; see {@link PythonReference}. */
58
+ reference: Record<string, unknown>;
59
+ /** Skill entries declare their accepted inputs here. */
60
+ arguments: Record<string, unknown>;
61
+ metadata: Record<string, unknown>;
62
+ source: "evolve";
63
+ created_at: string;
64
+ updated_at: string;
65
+ version: number;
66
+ }
67
+ /** One entry of the append-only refinement history (the evidence trail). */
68
+ export interface HarnessRefinementEvent {
69
+ id: string;
70
+ trigger: string;
71
+ changes: string[];
72
+ /** Where the trajectory evidence for this refinement lives (e.g. seq ranges). */
73
+ evidence: string;
74
+ /** The falsifiable expectation recorded with the edit. */
75
+ outcome: string;
76
+ created_at: string;
77
+ }
78
+ /** The whole harness state file. */
79
+ export interface HarnessState {
80
+ schema: number;
81
+ entries: Record<RefinementKind, Record<string, HarnessEntry>>;
82
+ refinements: HarnessRefinementEvent[];
83
+ }
84
+ /** A model-proposed edit, before validation and application. */
85
+ export interface RefinementEdit {
86
+ action: RefinementAction;
87
+ kind: RefinementKind;
88
+ id?: string;
89
+ title?: string;
90
+ content?: string;
91
+ path?: string;
92
+ reference?: Record<string, unknown>;
93
+ arguments?: Record<string, unknown>;
94
+ metadata?: Record<string, unknown>;
95
+ reason?: string;
96
+ }
97
+ /** The structured output of a planning pass. */
98
+ export interface RefinementProposal {
99
+ summary: string;
100
+ rationale: string;
101
+ edits: RefinementEdit[];
102
+ expectedOutcome: string;
103
+ }
104
+ /** An edit after the apply pass: before/after snapshots and outcome per edit. */
105
+ export interface AppliedRefinementEdit extends RefinementEdit {
106
+ id: string;
107
+ before?: HarnessEntry;
108
+ after?: HarnessEntry;
109
+ applied: boolean;
110
+ error?: string;
111
+ }
112
+ /** The result of applying one refinement. */
113
+ export interface RefinementResult {
114
+ id: string;
115
+ summary: string;
116
+ rationale: string;
117
+ expectedOutcome: string;
118
+ appliedEdits: AppliedRefinementEdit[];
119
+ harnessStatePath: string;
120
+ rollbackOf?: string;
121
+ scope?: HarnessScope;
122
+ }
123
+ /** The executable contract a skill entry must carry (python REPL skills). */
124
+ export interface PythonReference {
125
+ type: "python";
126
+ import?: string;
127
+ python_import?: string;
128
+ callable?: string;
129
+ call_pattern?: string;
130
+ }
131
+ /** A stable id derived from a title. */
132
+ export declare function slug(raw: string, fallback: string): string;
133
+ /** Fresh empty state with the current schema version. */
134
+ export declare function emptyHarnessState(): HarnessState;
135
+ /** Deep clone helper (state is plain JSON data). */
136
+ export declare function cloneEntry(entry: HarnessEntry | undefined): HarnessEntry | undefined;
137
+ //# sourceMappingURL=types.d.ts.map
package/lib/types.js ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Type model for the continual-evolution harness state.
3
+ *
4
+ * Design provenance: the state model follows the continual-harness design
5
+ * validated in prime-agent's `/refine` subsystem (MIT): versioned entries
6
+ * keyed by kind, an append-only refinement history carrying an evidence
7
+ * trail, atomic persistence, and deterministic inverse-op rollback. The
8
+ * code here is an original implementation, written for the DeepSeek Harness
9
+ * plugin surface.
10
+ */
11
+ /**
12
+ * Metadata key recording which session an entry's content was distilled from
13
+ * (trajectory citation; see {@link EntrySource}).
14
+ */
15
+ export const SOURCE_SESSION_KEY = "sourceSession";
16
+ /**
17
+ * Metadata key recording the session-log event seqs (of the direct user
18
+ * messages) the entry cites as its source (trajectory citation).
19
+ */
20
+ export const SOURCE_SEQS_KEY = "sourceSeqs";
21
+ /**
22
+ * Metadata key recording when an entry was archived. Archived entries are
23
+ * hidden from injection but never deleted — the data stays in the store and
24
+ * the entry can be restored (unarchive) or rolled back like any other edit.
25
+ */
26
+ export const ARCHIVED_AT_KEY = "archivedAt";
27
+ /**
28
+ * True when the entry is archived (hidden from injection, restorable).
29
+ * Absent or empty archivedAt means the entry is active.
30
+ */
31
+ export function isArchived(entry) {
32
+ const value = entry.metadata[ARCHIVED_AT_KEY];
33
+ return typeof value === "string" && value.length > 0;
34
+ }
35
+ /** A stable id derived from a title. */
36
+ export function slug(raw, fallback) {
37
+ const normalized = raw
38
+ .trim()
39
+ .toLowerCase()
40
+ .replace(/[^a-z0-9]+/g, "_")
41
+ .replace(/^_+|_+$/g, "")
42
+ .slice(0, 80);
43
+ return normalized || fallback;
44
+ }
45
+ /** Fresh empty state with the current schema version. */
46
+ export function emptyHarnessState() {
47
+ return {
48
+ schema: 1,
49
+ entries: {
50
+ prompt: {},
51
+ memory: {},
52
+ skill: {},
53
+ subagent: {},
54
+ },
55
+ refinements: [],
56
+ };
57
+ }
58
+ /** Deep clone helper (state is plain JSON data). */
59
+ export function cloneEntry(entry) {
60
+ return entry ? JSON.parse(JSON.stringify(entry)) : undefined;
61
+ }
62
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Code-enforced validation of model-proposed edits. Every rule here exists
3
+ * because the proposal is untrusted input: enum membership, immutability of
4
+ * the base system prompt, required fields per action, and the executable
5
+ * contract skill entries must carry.
6
+ */
7
+ import type { RefinementEdit } from "./types.js";
8
+ export declare const BASE_SYSTEM_PROMPT_ID = "base_system_prompt";
9
+ /** Returns a human-readable failure reason, or undefined when the edit passes. */
10
+ export declare function validateEdit(edit: RefinementEdit, computedId: string | undefined): string | undefined;
11
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1,55 @@
1
+ const ACTIONS = new Set(["create", "update", "delete", "archive"]);
2
+ const KINDS = new Set(["prompt", "memory", "skill", "subagent"]);
3
+ export const BASE_SYSTEM_PROMPT_ID = "base_system_prompt";
4
+ /** Returns a human-readable failure reason, or undefined when the edit passes. */
5
+ export function validateEdit(edit, computedId) {
6
+ if (!ACTIONS.has(edit.action)) {
7
+ return `unsupported action ${String(edit.action)}`;
8
+ }
9
+ if (!KINDS.has(edit.kind)) {
10
+ return `unsupported kind ${String(edit.kind)}`;
11
+ }
12
+ if (edit.kind === "prompt" && (edit.id === BASE_SYSTEM_PROMPT_ID || computedId === BASE_SYSTEM_PROMPT_ID)) {
13
+ return "base system prompt is not editable";
14
+ }
15
+ if (edit.action !== "create" && !edit.id) {
16
+ return `${edit.action} requires id`;
17
+ }
18
+ // Archive only names an existing entry: no title/content payload, and the
19
+ // base system prompt stays immutable under every action.
20
+ if (edit.action === "archive") {
21
+ return undefined;
22
+ }
23
+ if (edit.action !== "delete" && (!edit.title || !edit.content)) {
24
+ return `${edit.action} requires title and content`;
25
+ }
26
+ if (edit.action !== "delete" && edit.kind === "skill") {
27
+ return validateSkillContract(edit);
28
+ }
29
+ return undefined;
30
+ }
31
+ function validateSkillContract(edit) {
32
+ if (edit.arguments === undefined) {
33
+ return "create/update skill requires arguments";
34
+ }
35
+ const reference = edit.reference;
36
+ if (!reference || typeof reference !== "object") {
37
+ return "create/update skill requires python reference";
38
+ }
39
+ const ref = reference;
40
+ if (ref.type !== "python") {
41
+ return "create/update skill reference.type must be python";
42
+ }
43
+ const hasImport = (typeof ref.import === "string" && ref.import.length > 0) ||
44
+ (typeof ref.python_import === "string" && ref.python_import.length > 0);
45
+ const hasCallable = (typeof ref.callable === "string" && ref.callable.length > 0) ||
46
+ (typeof ref.call_pattern === "string" && ref.call_pattern.length > 0);
47
+ if (!hasImport) {
48
+ return "create/update skill requires python import";
49
+ }
50
+ if (!hasCallable) {
51
+ return "create/update skill requires callable or call_pattern";
52
+ }
53
+ return undefined;
54
+ }
55
+ //# sourceMappingURL=validate.js.map
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "dsh-continual-evolve",
3
+ "version": "0.1.0",
4
+ "description": "Continual self-evolution plugin for DeepSeek Harness: versioned, auditable, rollback-safe harness state (prompt notes, memories, skills, subagent specs) refined from session trajectories.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "lib/index.js",
8
+ "types": "lib/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./lib/index.d.ts",
12
+ "default": "./lib/index.js"
13
+ },
14
+ "./types": {
15
+ "types": "./lib/types.d.ts",
16
+ "default": "./lib/types.js"
17
+ },
18
+ "./package.json": "./package.json"
19
+ },
20
+ "files": [
21
+ "lib/**/*.js",
22
+ "lib/**/*.d.ts",
23
+ "cordis.patch.yml",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
27
+ "dsh": {
28
+ "bundle": {
29
+ "patch": "./cordis.patch.yml"
30
+ }
31
+ },
32
+ "engines": {
33
+ "node": "^22.19.0 || >=24.0.0"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "peerDependencies": {
39
+ "@deepseek-ai/cordis": "^4.0.1",
40
+ "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6",
41
+ "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
42
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.6"
43
+ },
44
+ "devDependencies": {
45
+ "@deepseek-ai/cordis": "^4.0.1",
46
+ "@deepseek-ai/dsh-home-paths": "0.1.0-rc.6",
47
+ "@deepseek-ai/dsh-llm": "0.1.0-rc.6",
48
+ "@deepseek-ai/dsh-tools": "0.1.0-rc.6",
49
+ "@deepseek-ai/dsh-agent": "0.1.0-rc.6",
50
+ "@deepseek-ai/dsh-commands": "0.1.0-rc.6",
51
+ "@deepseek-ai/dsh-system-prompt": "0.1.0-rc.6",
52
+ "@deepseek-ai/schemastery": "^3.18.1",
53
+ "@types/node": "^22.10.0",
54
+ "oxlint": "^0.16.0",
55
+ "typescript": "^5.9.0",
56
+ "vitest": "^3.2.0"
57
+ },
58
+ "scripts": {
59
+ "build": "tsc -p tsconfig.json",
60
+ "dev": "tsc -p tsconfig.json --watch",
61
+ "typecheck": "tsc -p tsconfig.json --noEmit",
62
+ "test": "vitest run",
63
+ "test:watch": "vitest",
64
+ "lint": "oxlint src test",
65
+ "clean": "rm -rf lib"
66
+ }
67
+ }