dsh-rules 0.1.1 → 0.1.3
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/README.md +1 -1
- package/README.zh.md +1 -1
- package/lib/index.js +28 -7
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Glob-activated rule prompts for [DeepSeek Harness](https://github.com/deepseek-a
|
|
|
25
25
|
|
|
26
26
|
- **Glob activation** — rules activate per file the agent touches: `**`, `*`, `?`, `{a,b}`, `[abc]`, and `!` negation (picomatch).
|
|
27
27
|
- **Claude Code compatible** — plain rule files (`.dsh/rules/*.md`) *and* `# Path:` sections inside `CLAUDE.md` / `AGENTS.md`.
|
|
28
|
-
- **Visible & durable** — active rules are injected as a user message the UI shows and the session log persists; each snapshot supersedes earlier ones, so the model always sees the current set.
|
|
28
|
+
- **Visible & durable** — active rules are injected as a user message the UI shows and the session log persists; each injection appears in the chat as a collapsible row (same chrome as tool-call rows) with a one-line notice — e.g. `dsh-rules · Active rules: typescript, docs` — expanding to the full rules text. Each snapshot supersedes earlier ones, so the model always sees the current set.
|
|
29
29
|
- **Budget-bounded** — byte-budget rendering (32 KB default): low-priority rules are dropped first, then the last rule is truncated; content is escaped so it can never break out of the framing tags.
|
|
30
30
|
- **Resume-friendly** — on session resume the last snapshot and its matched files are restored from the log, preventing duplicate injection.
|
|
31
31
|
- **Per-session tracking** — every agent/session tracks its own touched files (subagents included); global rules (no `path:`) are always active.
|
package/README.zh.md
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
- **glob 激活** —— 按 agent 触碰的文件逐个激活规则:`**`、`*`、`?`、`{a,b}`、`[abc]`、`!` 取反(picomatch)。
|
|
27
27
|
- **Claude Code 兼容** —— 既支持规则文件(`.dsh/rules/*.md`),也支持 `CLAUDE.md` / `AGENTS.md` 内的 `# Path:` 段落。
|
|
28
|
-
- **可见且持久** —— 激活的规则以用户消息注入,UI
|
|
28
|
+
- **可见且持久** —— 激活的规则以用户消息注入,UI 可见、会话日志持久化;每次注入在对话里显示为一行可折叠的通知(与工具调用行同款外观,如 `dsh-rules · Active rules: typescript, docs`),展开可见完整规则文本;每个快照取代更早快照,模型始终看到最新集合。
|
|
29
29
|
- **预算可控** —— 字节预算渲染(默认 32 KB):先丢弃低优先级规则,再截断最后一条;正文转义,无法逃逸框架标签。
|
|
30
30
|
- **恢复友好** —— 恢复会话时从日志恢复最近一次快照与已匹配文件列表,避免重复注入。
|
|
31
31
|
- **按会话跟踪** —— 每个 agent/会话独立跟踪触碰文件(含子代理);无 `path:` 的全局规则恒激活。
|
package/lib/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @module dsh-rules
|
|
12
12
|
*/
|
|
13
|
-
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
13
|
+
import { boundContextSummary, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
14
14
|
import { dshHomeDisplay, resolveDshHome } from "@deepseek-ai/dsh-home-paths";
|
|
15
15
|
import z from "@deepseek-ai/schemastery";
|
|
16
16
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -264,11 +264,11 @@ var RulesState = class {
|
|
|
264
264
|
if (desiredText === null) {
|
|
265
265
|
if (previous === void 0 || previous === null || previous === EMPTY_RULES_TEXT) return void 0;
|
|
266
266
|
this.lastInjected.set(sessionId, EMPTY_RULES_TEXT);
|
|
267
|
-
return rulesMessage(EMPTY_RULES_TEXT);
|
|
267
|
+
return rulesMessage(EMPTY_RULES_TEXT, "No active rules");
|
|
268
268
|
}
|
|
269
269
|
if (previous === desiredText) return void 0;
|
|
270
270
|
this.lastInjected.set(sessionId, desiredText);
|
|
271
|
-
return rulesMessage(desiredText);
|
|
271
|
+
return rulesMessage(desiredText, rulesSummary(active));
|
|
272
272
|
}
|
|
273
273
|
/** Restore the last injected snapshot (and matched files) from a resumed session log. */
|
|
274
274
|
seedFromSession(session) {
|
|
@@ -277,7 +277,8 @@ var RulesState = class {
|
|
|
277
277
|
const event = events[index];
|
|
278
278
|
if (event?.type !== "user/message") continue;
|
|
279
279
|
const source = event.data?.source;
|
|
280
|
-
if (source?.kind !== "plugin" || source.plugin !== name
|
|
280
|
+
if (source?.kind !== "plugin" || source.plugin !== name) continue;
|
|
281
|
+
if (source.form !== "rules" && source.form !== "notice") continue;
|
|
281
282
|
const [block] = event.data.content;
|
|
282
283
|
const text = event.data.content.length === 1 && block?.type === "text" ? block.text : void 0;
|
|
283
284
|
if (text === void 0) break;
|
|
@@ -427,14 +428,34 @@ var RulesState = class {
|
|
|
427
428
|
}
|
|
428
429
|
};
|
|
429
430
|
|
|
430
|
-
/** Build the user-role message carrying one rules snapshot.
|
|
431
|
-
|
|
431
|
+
/** Build the user-role message carrying one rules snapshot.
|
|
432
|
+
*
|
|
433
|
+
* The message source uses the host's `notice` context form (`form` +
|
|
434
|
+
* one-line `summary`): the DSH web UI renders every plugin-sourced user
|
|
435
|
+
* message as a collapsible context row (same chrome as tool-call rows), and a
|
|
436
|
+
* `notice` form makes the summary visible on the collapsed row — e.g.
|
|
437
|
+
* `dsh-rules · Active rules: typescript, docs` — with the full snapshot
|
|
438
|
+
* behind the disclosure. */
|
|
439
|
+
function rulesMessage(text, summary) {
|
|
432
440
|
return createUserMessage({
|
|
433
441
|
content: [{ type: "text", text }],
|
|
434
|
-
source: {
|
|
442
|
+
source: {
|
|
443
|
+
kind: "plugin",
|
|
444
|
+
plugin: name,
|
|
445
|
+
form: "notice",
|
|
446
|
+
summary: boundContextSummary(summary)
|
|
447
|
+
}
|
|
435
448
|
});
|
|
436
449
|
}
|
|
437
450
|
|
|
451
|
+
/** One-line account of the active rule set, in rendering order (rank, name). */
|
|
452
|
+
function rulesSummary(active) {
|
|
453
|
+
const names = [...active]
|
|
454
|
+
.sort((left, right) => left.rank - right.rank || (left.name < right.name ? -1 : left.name > right.name ? 1 : 0))
|
|
455
|
+
.map((rule) => rule.name);
|
|
456
|
+
return `Active rules: ${names.join(", ")}`;
|
|
457
|
+
}
|
|
458
|
+
|
|
438
459
|
/** Whether one message is our rules snapshot with the same text as another. */
|
|
439
460
|
function sameRulesMessage(message, desired) {
|
|
440
461
|
if (message.source?.kind !== "plugin" || message.source?.plugin !== name) return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-rules",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "DSH rules plugin: activate rule prompts / markdown documents by glob-matching the files an agent reads or edits (Claude Code rules.md style).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
"prompt"
|
|
13
13
|
],
|
|
14
14
|
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/rj-jiangyichen/dsh-rules.git"
|
|
18
|
+
},
|
|
15
19
|
"type": "module",
|
|
16
20
|
"main": "lib/index.js",
|
|
17
21
|
"exports": {
|