dsh-continual-evolve 0.11.0 → 0.12.1

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 (161) hide show
  1. package/README.md +42 -115
  2. package/README.zh.md +33 -93
  3. package/client/client.js +253 -0
  4. package/cordis.patch.yml +2 -2
  5. package/lib/card-routes.d.ts +32 -0
  6. package/lib/card-routes.js +92 -0
  7. package/lib/index.d.ts +65 -217
  8. package/lib/index.js +74 -234
  9. package/lib/known-workspaces.d.ts +22 -0
  10. package/lib/known-workspaces.js +42 -0
  11. package/lib/memory-guide.d.ts +13 -14
  12. package/lib/memory-guide.js +34 -21
  13. package/lib/memory-section.d.ts +77 -0
  14. package/lib/memory-section.js +189 -0
  15. package/lib/memory-snapshot.d.ts +54 -0
  16. package/lib/memory-snapshot.js +125 -0
  17. package/package.json +8 -17
  18. package/lib/apply.d.ts +0 -22
  19. package/lib/apply.js +0 -157
  20. package/lib/approval.d.ts +0 -73
  21. package/lib/approval.js +0 -127
  22. package/lib/audit-log.d.ts +0 -19
  23. package/lib/audit-log.js +0 -52
  24. package/lib/auto.d.ts +0 -236
  25. package/lib/auto.js +0 -773
  26. package/lib/autocase.d.ts +0 -38
  27. package/lib/autocase.js +0 -76
  28. package/lib/benchmark-command.d.ts +0 -9
  29. package/lib/benchmark-command.js +0 -357
  30. package/lib/benchmark.d.ts +0 -151
  31. package/lib/benchmark.js +0 -250
  32. package/lib/command-util.d.ts +0 -70
  33. package/lib/command-util.js +0 -123
  34. package/lib/command.d.ts +0 -13
  35. package/lib/command.js +0 -134
  36. package/lib/consolidate.d.ts +0 -90
  37. package/lib/consolidate.js +0 -180
  38. package/lib/copy.d.ts +0 -37
  39. package/lib/copy.js +0 -58
  40. package/lib/declines.d.ts +0 -103
  41. package/lib/declines.js +0 -179
  42. package/lib/evaluate.d.ts +0 -74
  43. package/lib/evaluate.js +0 -271
  44. package/lib/evolve-event.d.ts +0 -40
  45. package/lib/evolve-event.js +0 -60
  46. package/lib/extraction-phase.d.ts +0 -132
  47. package/lib/extraction-phase.js +0 -236
  48. package/lib/failures.d.ts +0 -42
  49. package/lib/failures.js +0 -171
  50. package/lib/fate.d.ts +0 -130
  51. package/lib/fate.js +0 -350
  52. package/lib/goal-command.d.ts +0 -7
  53. package/lib/goal-command.js +0 -37
  54. package/lib/goal.d.ts +0 -72
  55. package/lib/goal.js +0 -72
  56. package/lib/inject.d.ts +0 -90
  57. package/lib/inject.js +0 -164
  58. package/lib/injection-caps.d.ts +0 -4
  59. package/lib/injection-caps.js +0 -4
  60. package/lib/injection-directory.d.ts +0 -29
  61. package/lib/injection-directory.js +0 -78
  62. package/lib/injection-rank.d.ts +0 -85
  63. package/lib/injection-rank.js +0 -161
  64. package/lib/listener.d.ts +0 -45
  65. package/lib/listener.js +0 -199
  66. package/lib/llm-text.d.ts +0 -104
  67. package/lib/llm-text.js +0 -140
  68. package/lib/logfile.d.ts +0 -71
  69. package/lib/logfile.js +0 -159
  70. package/lib/maintenance-commands.d.ts +0 -23
  71. package/lib/maintenance-commands.js +0 -136
  72. package/lib/memory-agent.d.ts +0 -93
  73. package/lib/memory-agent.js +0 -300
  74. package/lib/memory-apply.d.ts +0 -44
  75. package/lib/memory-apply.js +0 -202
  76. package/lib/memory-benchmark.d.ts +0 -76
  77. package/lib/memory-benchmark.js +0 -170
  78. package/lib/memory-index.d.ts +0 -114
  79. package/lib/memory-index.js +0 -197
  80. package/lib/memory-manifest.d.ts +0 -16
  81. package/lib/memory-manifest.js +0 -70
  82. package/lib/message-source.d.ts +0 -23
  83. package/lib/message-source.js +0 -12
  84. package/lib/mount-command.d.ts +0 -10
  85. package/lib/mount-command.js +0 -48
  86. package/lib/mount.d.ts +0 -42
  87. package/lib/mount.js +0 -212
  88. package/lib/notify.d.ts +0 -48
  89. package/lib/notify.js +0 -57
  90. package/lib/plan-command.d.ts +0 -12
  91. package/lib/plan-command.js +0 -38
  92. package/lib/plan.d.ts +0 -16
  93. package/lib/plan.js +0 -126
  94. package/lib/planner.d.ts +0 -61
  95. package/lib/planner.js +0 -144
  96. package/lib/pool.d.ts +0 -7
  97. package/lib/pool.js +0 -25
  98. package/lib/prefix-cache.d.ts +0 -79
  99. package/lib/prefix-cache.js +0 -168
  100. package/lib/project.d.ts +0 -28
  101. package/lib/project.js +0 -66
  102. package/lib/projection.d.ts +0 -22
  103. package/lib/projection.js +0 -112
  104. package/lib/promotion.d.ts +0 -94
  105. package/lib/promotion.js +0 -171
  106. package/lib/recall.d.ts +0 -85
  107. package/lib/recall.js +0 -142
  108. package/lib/record-language.d.ts +0 -85
  109. package/lib/record-language.js +0 -152
  110. package/lib/render.d.ts +0 -13
  111. package/lib/render.js +0 -80
  112. package/lib/review-scheduler.d.ts +0 -38
  113. package/lib/review-scheduler.js +0 -183
  114. package/lib/review.d.ts +0 -60
  115. package/lib/review.js +0 -145
  116. package/lib/rollback.d.ts +0 -9
  117. package/lib/rollback.js +0 -68
  118. package/lib/rubric.d.ts +0 -29
  119. package/lib/rubric.js +0 -119
  120. package/lib/runtime-commands.d.ts +0 -14
  121. package/lib/runtime-commands.js +0 -115
  122. package/lib/runtime.d.ts +0 -24
  123. package/lib/runtime.js +0 -87
  124. package/lib/score.d.ts +0 -64
  125. package/lib/score.js +0 -191
  126. package/lib/search.d.ts +0 -83
  127. package/lib/search.js +0 -136
  128. package/lib/service.d.ts +0 -63
  129. package/lib/service.js +0 -253
  130. package/lib/skill-render.d.ts +0 -23
  131. package/lib/skill-render.js +0 -69
  132. package/lib/skill.d.ts +0 -15
  133. package/lib/skill.js +0 -80
  134. package/lib/skillquality.d.ts +0 -85
  135. package/lib/skillquality.js +0 -320
  136. package/lib/source.d.ts +0 -30
  137. package/lib/source.js +0 -43
  138. package/lib/state.d.ts +0 -26
  139. package/lib/state.js +0 -151
  140. package/lib/store.d.ts +0 -61
  141. package/lib/store.js +0 -164
  142. package/lib/token-usage.d.ts +0 -68
  143. package/lib/token-usage.js +0 -211
  144. package/lib/tool.d.ts +0 -34
  145. package/lib/tool.js +0 -320
  146. package/lib/turn-snapshot.d.ts +0 -78
  147. package/lib/turn-snapshot.js +0 -252
  148. package/lib/types.d.ts +0 -218
  149. package/lib/types.js +0 -133
  150. package/lib/usage.d.ts +0 -36
  151. package/lib/usage.js +0 -98
  152. package/lib/validate.d.ts +0 -28
  153. package/lib/validate.js +0 -181
  154. package/lib/wrapup-candidates.d.ts +0 -127
  155. package/lib/wrapup-candidates.js +0 -161
  156. package/lib/wrapup-command.d.ts +0 -10
  157. package/lib/wrapup-command.js +0 -243
  158. package/lib/wrapup-proposals.d.ts +0 -101
  159. package/lib/wrapup-proposals.js +0 -281
  160. package/lib/wrapup.d.ts +0 -56
  161. package/lib/wrapup.js +0 -105
@@ -0,0 +1,253 @@
1
+ /**
2
+ * dsh-continual-evolve — client bundle for the official plugin manager card.
3
+ *
4
+ * Hand-written (no bundler: docs/coding-standard.md forbids a second one) in
5
+ * the host loader's factory shape, verified against dshmarket's built
6
+ * bundle: `window.__ModuleLoader__.load({ id, factory })`, where the factory
7
+ * resolves host-provided modules through the passed `require` (here: only
8
+ * react) and returns its `module.exports`. The host mounts the bundle via
9
+ * package.json `dsh.client` + the `./client` export.
10
+ *
11
+ * The card registers one slot, `plugins.bundle.config` — the seat the 0.1.7+
12
+ * plugin manager declares for a bundle's own page. Slot detection is the
13
+ * compatibility contract: a host that never declares the slot never runs the
14
+ * registration, so the card is silently absent while the memory section is
15
+ * unaffected. The render function answers the host's `view === "summary"`
16
+ * call with null (the bundle list row shows the package description; the
17
+ * card is the page).
18
+ *
19
+ * The card is a read-only projection of the workspace memory store, fetched
20
+ * at render time from this plugin's host routes (same-origin). No editor, no
21
+ * write path, no cached state — refresh refetches everything.
22
+ */
23
+ window.__ModuleLoader__.load({
24
+ id: "dsh-continual-evolve",
25
+ factory: function (require) {
26
+ var module = { exports: {} };
27
+ var exports = module.exports;
28
+ var react = undefined;
29
+ try {
30
+ react = require("react");
31
+ } catch (error) {
32
+ // Browser side: this runs before any cordis logger exporter exists,
33
+ // so console is the only outlet (same escape hatch dshmarket uses).
34
+ console.warn(
35
+ "[dsh-continual-evolve] host react module unavailable — card disabled: " +
36
+ (error instanceof Error ? error.message : String(error)),
37
+ );
38
+ return module.exports;
39
+ }
40
+ if (react === undefined || typeof react.createElement !== "function") {
41
+ // A module table that resolves react to nothing is the same downgrade:
42
+ // render would throw and blank the whole settings dialog (dshmarket #671 shape).
43
+ console.warn("[dsh-continual-evolve] host react module has no createElement — card disabled");
44
+ return module.exports;
45
+ }
46
+
47
+ var createElement = react.createElement;
48
+ var useState = react.useState;
49
+ var useEffect = react.useEffect;
50
+
51
+ var NS = "dsh-continual-evolve";
52
+ var SLOT = "plugins.bundle.config";
53
+ var API_ROOT = "/dsh-continual-evolve/api/v1";
54
+
55
+ /**
56
+ * Assemble the card's view model: the workspace allowlist, then one
57
+ * snapshot per workspace. Network or API failure per workspace degrades
58
+ * to an `error` string on that workspace's entry — one bad store never
59
+ * blanks the whole card.
60
+ *
61
+ * @param {typeof fetch} fetchImpl - injectable for tests.
62
+ * @returns {Promise<{workspaces: Array<object>}>}
63
+ */
64
+ async function loadCardModel(fetchImpl) {
65
+ var listResponse = await fetchImpl(API_ROOT + "/workspaces");
66
+ if (!listResponse.ok) {
67
+ throw new Error("workspaces API answered HTTP " + listResponse.status);
68
+ }
69
+ var listBody = await listResponse.json();
70
+ var workspaces = Array.isArray(listBody.workspaces) ? listBody.workspaces : [];
71
+ var entries = await Promise.all(
72
+ workspaces.map(async function (workspace) {
73
+ var root = typeof workspace.root === "string" ? workspace.root : "";
74
+ var lastSeen = typeof workspace.lastSeen === "string" ? workspace.lastSeen : "";
75
+ try {
76
+ var snapshotResponse = await fetchImpl(API_ROOT + "/memory?root=" + encodeURIComponent(root));
77
+ if (!snapshotResponse.ok) {
78
+ return { root: root, lastSeen: lastSeen, snapshot: null, error: "HTTP " + snapshotResponse.status };
79
+ }
80
+ return { root: root, lastSeen: lastSeen, snapshot: await snapshotResponse.json(), error: null };
81
+ } catch (error) {
82
+ return {
83
+ root: root,
84
+ lastSeen: lastSeen,
85
+ snapshot: null,
86
+ error: error instanceof Error ? error.message : String(error),
87
+ };
88
+ }
89
+ }),
90
+ );
91
+ return { workspaces: entries };
92
+ }
93
+
94
+ /** One workspace block: root, stats, drift warnings, per-file lines. */
95
+ function WorkspaceBlock(props) {
96
+ var entry = props.entry;
97
+ var snapshot = entry.snapshot;
98
+ var children = [
99
+ createElement("div", { key: "root", style: { fontFamily: "monospace", wordBreak: "break-all" } }, entry.root),
100
+ ];
101
+ if (entry.error !== null) {
102
+ children.push(createElement("div", { key: "error" }, "读取失败:" + entry.error));
103
+ return createElement("div", { style: { marginBottom: "12px" } }, children);
104
+ }
105
+ if (snapshot === null || !snapshot.exists) {
106
+ children.push(createElement("div", { key: "absent" }, "该工作区尚无记忆库(开一次会话自动创建)。"));
107
+ return createElement("div", { style: { marginBottom: "12px" } }, children);
108
+ }
109
+ if (snapshot.readError !== null) {
110
+ children.push(createElement("div", { key: "readError" }, "记忆库读取失败:" + snapshot.readError));
111
+ return createElement("div", { style: { marginBottom: "12px" } }, children);
112
+ }
113
+ children.push(
114
+ createElement(
115
+ "div",
116
+ { key: "stats" },
117
+ snapshot.fileCount + " 条记忆 · 索引 " + snapshot.indexEntryCount + " 行",
118
+ ),
119
+ );
120
+ if (snapshot.missingFiles.length > 0) {
121
+ children.push(
122
+ createElement(
123
+ "div",
124
+ { key: "missing" },
125
+ "索引失联(索引引用但文件已删):" + snapshot.missingFiles.join("、"),
126
+ ),
127
+ );
128
+ }
129
+ if (snapshot.unindexedFiles.length > 0) {
130
+ children.push(
131
+ createElement(
132
+ "div",
133
+ { key: "unindexed" },
134
+ "未入索引(文件存在但索引没有行):" + snapshot.unindexedFiles.join("、"),
135
+ ),
136
+ );
137
+ }
138
+ children.push(
139
+ createElement(
140
+ "ul",
141
+ { key: "files", style: { margin: "4px 0 0", paddingLeft: "18px" } },
142
+ snapshot.files.map(function (file) {
143
+ return createElement(
144
+ "li",
145
+ { key: file.file },
146
+ createElement("strong", null, file.file) +
147
+ (file.description !== "" ? " — " + file.description : ""),
148
+ );
149
+ }),
150
+ ),
151
+ );
152
+ return createElement("div", { style: { marginBottom: "12px" } }, children);
153
+ }
154
+
155
+ /** The card page: refresh control + one block per known workspace. */
156
+ function MemoryCard() {
157
+ var state = useState({ status: "loading", model: null, message: "" });
158
+ var model = state[0];
159
+ var setModel = state[1];
160
+ var reloadState = useState(0);
161
+ var reload = reloadState[1];
162
+ useEffect(
163
+ function () {
164
+ var alive = true;
165
+ loadCardModel(fetch).then(
166
+ function (data) {
167
+ if (alive) setModel({ status: "ready", model: data, message: "" });
168
+ },
169
+ function (error) {
170
+ if (alive) {
171
+ setModel({ status: "error", model: null, message: error instanceof Error ? error.message : String(error) });
172
+ }
173
+ },
174
+ );
175
+ return function () {
176
+ alive = false;
177
+ };
178
+ },
179
+ [reloadState[0]],
180
+ );
181
+ var children = [
182
+ createElement(
183
+ "div",
184
+ { key: "head", style: { display: "flex", alignItems: "baseline", gap: "12px" } },
185
+ createElement("strong", null, "工作区记忆(只读投影)"),
186
+ createElement(
187
+ "button",
188
+ {
189
+ type: "button",
190
+ onClick: function () {
191
+ setModel({ status: "loading", model: null, message: "" });
192
+ reload(function (n) {
193
+ return n + 1;
194
+ });
195
+ },
196
+ },
197
+ "刷新",
198
+ ),
199
+ ),
200
+ createElement(
201
+ "div",
202
+ { key: "hint" },
203
+ "事实源是各工作区 .evolve/memory/ 下的 markdown 文件——模型原生读写;本卡片只展示,编辑请直接改文件。",
204
+ ),
205
+ ];
206
+ if (model.status === "loading") {
207
+ children.push(createElement("div", { key: "body" }, "读取中…"));
208
+ } else if (model.status === "error") {
209
+ children.push(createElement("div", { key: "body" }, "卡片数据加载失败:" + model.message));
210
+ } else if (model.model.workspaces.length === 0) {
211
+ children.push(
212
+ createElement(
213
+ "div",
214
+ { key: "body" },
215
+ "本进程还没有服务过任何工作区会话——在某个工作区开一次会话后回来刷新。",
216
+ ),
217
+ );
218
+ } else {
219
+ children.push(
220
+ createElement(
221
+ "div",
222
+ { key: "body" },
223
+ model.model.workspaces.map(function (entry) {
224
+ return createElement(WorkspaceBlock, { key: entry.root, entry: entry });
225
+ }),
226
+ ),
227
+ );
228
+ }
229
+ return createElement("div", null, children);
230
+ }
231
+
232
+ exports.name = NS;
233
+ exports.inject = ["slots"];
234
+ exports.loadCardModel = loadCardModel;
235
+ exports.apply = function apply(ctx) {
236
+ ctx.slots.inject(SLOT, function () {
237
+ return ctx.slots.register(
238
+ {
239
+ name: SLOT,
240
+ key: NS,
241
+ inject: function () {
242
+ return {};
243
+ },
244
+ },
245
+ function (ownerProps) {
246
+ return ownerProps && ownerProps.view === "summary" ? null : createElement(MemoryCard);
247
+ },
248
+ );
249
+ });
250
+ };
251
+ return module.exports;
252
+ },
253
+ });
package/cordis.patch.yml CHANGED
@@ -2,8 +2,8 @@
2
2
  #
3
3
  # Installed via `dsh plugin --profile <name> add dsh-continual-evolve`, this
4
4
  # patch inserts the plugin row so it activates without manual profile editing.
5
- # Conservative defaults: the auto-review gate is OFF (opt in via your profile
6
- # cordis.patch.yml config) and cross-session edits require human approval.
5
+ # The plugin only registers a session-start memory section (workspace
6
+ # .evolve/memory, native file read/write); no gate is ever ON by default.
7
7
  - insert:
8
8
  - id: continual-evolve
9
9
  name: 'dsh-continual-evolve'
@@ -0,0 +1,32 @@
1
+ import type { KnownWorkspaces } from "./known-workspaces.js";
2
+ /** URL prefix of the card API (kind-exact routes registered under it). */
3
+ export declare const CARD_API_WORKSPACES_PATH = "/dsh-continual-evolve/api/v1/workspaces";
4
+ export declare const CARD_API_MEMORY_PATH = "/dsh-continual-evolve/api/v1/memory";
5
+ /** Minimal request shape the handlers touch (Node IncomingMessage subset). */
6
+ export interface CardRequest {
7
+ method?: string;
8
+ url?: string;
9
+ }
10
+ /** Minimal response shape the handlers touch (Node ServerResponse subset). */
11
+ export interface CardResponse {
12
+ writeHead(status: number, headers?: Record<string, string>): unknown;
13
+ end(body?: string): unknown;
14
+ }
15
+ /** One `kind: "exact"` route registration on the host web server. */
16
+ export interface CardRoute {
17
+ kind: "exact";
18
+ path: string;
19
+ handler(request: CardRequest, response: CardResponse): void;
20
+ }
21
+ /** Minimal webServer surface the card mounts on. */
22
+ export interface CardWebServer {
23
+ register(route: CardRoute): unknown;
24
+ }
25
+ /**
26
+ * Register the two card routes and return a disposer that removes them.
27
+ * Registration return values are passed through untouched: whatever disposer
28
+ * shape the host hands back (or none, as on some host versions), the
29
+ * disposer calls only the functions among them.
30
+ */
31
+ export declare function mountCardRoutes(webServer: CardWebServer, workspaces: KnownWorkspaces): () => void;
32
+ //# sourceMappingURL=card-routes.d.ts.map
@@ -0,0 +1,92 @@
1
+ /**
2
+ * The read-only HTTP surface the plugin management card fetches from.
3
+ *
4
+ * Mounted through the host's `webServer` service (same registration shape
5
+ * dshmarket uses: `kind: "exact"` routes on the profile's web server), the
6
+ * two endpoints are GET-only projections: the workspace allowlist and, for a
7
+ * known root, the memory snapshot. The allowlist IS the security fence — the
8
+ * memory endpoint resolves its `root` parameter only against roots the
9
+ * running process has actually served, so the API cannot read arbitrary
10
+ * paths. Handlers are synchronous and never throw past the response.
11
+ */
12
+ import { resolve } from "node:path";
13
+ import { memorySnapshot } from "./memory-snapshot.js";
14
+ /** URL prefix of the card API (kind-exact routes registered under it). */
15
+ export const CARD_API_WORKSPACES_PATH = "/dsh-continual-evolve/api/v1/workspaces";
16
+ export const CARD_API_MEMORY_PATH = "/dsh-continual-evolve/api/v1/memory";
17
+ function sendJson(response, status, body) {
18
+ response.writeHead(status, { "content-type": "application/json; charset=utf-8" });
19
+ response.end(JSON.stringify(body));
20
+ }
21
+ function isGet(request) {
22
+ return (request.method ?? "GET") === "GET";
23
+ }
24
+ /**
25
+ * Register the two card routes and return a disposer that removes them.
26
+ * Registration return values are passed through untouched: whatever disposer
27
+ * shape the host hands back (or none, as on some host versions), the
28
+ * disposer calls only the functions among them.
29
+ */
30
+ export function mountCardRoutes(webServer, workspaces) {
31
+ const disposers = [];
32
+ disposers.push(webServer.register({
33
+ kind: "exact",
34
+ path: CARD_API_WORKSPACES_PATH,
35
+ handler(request, response) {
36
+ if (!isGet(request)) {
37
+ response.writeHead(405, { allow: "GET" });
38
+ response.end();
39
+ return;
40
+ }
41
+ sendJson(response, 200, { workspaces: workspaces.list() });
42
+ },
43
+ }));
44
+ disposers.push(webServer.register({
45
+ kind: "exact",
46
+ path: CARD_API_MEMORY_PATH,
47
+ handler(request, response) {
48
+ if (!isGet(request)) {
49
+ response.writeHead(405, { allow: "GET" });
50
+ response.end();
51
+ return;
52
+ }
53
+ const root = rootParamOf(request);
54
+ if (root === null) {
55
+ sendJson(response, 400, { error: "root query parameter is required and must be an absolute path" });
56
+ return;
57
+ }
58
+ const known = workspaces.list().find((workspace) => workspace.root === resolve(root));
59
+ if (known === undefined) {
60
+ // The allowlist answers 404 without distinguishing "never
61
+ // served" from "wrong path": no filesystem oracle here.
62
+ sendJson(response, 404, { error: "unknown workspace root" });
63
+ return;
64
+ }
65
+ sendJson(response, 200, memorySnapshot(known.root));
66
+ },
67
+ }));
68
+ return () => {
69
+ for (const disposer of disposers) {
70
+ if (typeof disposer === "function") {
71
+ disposer();
72
+ }
73
+ }
74
+ };
75
+ }
76
+ /** The decoded `root` query parameter, or null when absent/relative. */
77
+ function rootParamOf(request) {
78
+ try {
79
+ const url = new URL(request.url ?? "/", "http://dsh-card.invalid");
80
+ const root = url.searchParams.get("root");
81
+ if (root === null || root.trim().length === 0) {
82
+ return null;
83
+ }
84
+ return root;
85
+ }
86
+ catch (error) {
87
+ // A malformed URL is a bad request, not a crash: null maps to 400.
88
+ void error;
89
+ return null;
90
+ }
91
+ }
92
+ //# sourceMappingURL=card-routes.js.map