@xuanling-rs/xuanling-dsh-skills 0.2.2 → 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 umbrella22 and XuanLing contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README-ZH.md ADDED
@@ -0,0 +1,16 @@
1
+ # xuanling-dsh-skills
2
+
3
+ [English](README.md) | 简体中文
4
+
5
+ 该 DeepSeek Harness bundle 包含两个按需 XuanLing 工作流 Skill 和严格整文件覆盖 policy。
6
+ 它不注册 MCP server,也不依赖 `@xuanling-rs/xuanling-mcp`。
7
+
8
+ ```sh
9
+ dsh plugin --profile demo add @xuanling-rs/xuanling-dsh-skills@0.2.3
10
+ ```
11
+
12
+ 请与且仅与一个 XuanLing 工具 bundle 组合使用。`xuanling-file-workflow` 在 Harness 原生文件
13
+ 工具和 XuanLing 文件工具之间路由;`xuanling-memory-workflow` 将 proposal 创建和经用户授权的
14
+ review 分隔到不同轮次。Policy 会在 MCP dispatch 前拒绝缺少 `expected_sha256` 的既有文件覆盖。
15
+
16
+ 要求 Node.js 22.14 或更高版本。使用 MIT License。
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # xuanling-dsh-skills
2
+
3
+ English | [Simplified Chinese](README-ZH.md)
4
+
5
+ DeepSeek Harness bundle containing two on-demand XuanLing workflow Skills and
6
+ the strict whole-file overwrite policy. It registers no MCP server and has no
7
+ dependency on `@xuanling-rs/xuanling-mcp`.
8
+
9
+ ```sh
10
+ dsh plugin --profile demo add @xuanling-rs/xuanling-dsh-skills@0.2.3
11
+ ```
12
+
13
+ Use it with exactly one XuanLing tool bundle. `xuanling-file-workflow` routes
14
+ between Harness-native and XuanLing file tools. `xuanling-memory-workflow`
15
+ keeps proposal creation and user-authorized review in separate turns. The
16
+ policy rejects an existing-file overwrite without `expected_sha256` before
17
+ MCP dispatch.
18
+
19
+ Node.js 22.14 or newer is required. Licensed under the MIT License.
@@ -0,0 +1,28 @@
1
+ # XuanLing on-demand skills for DeepSeek Harness.
2
+ #
3
+ # One insert block mounts a dedicated @deepseek-ai/dsh-skill-filesystem
4
+ # provider that sees ONLY this bundle's skills/ directory and the strict
5
+ # XuanLing overwrite policy from this installed package:
6
+ # - providerName is unique ("xuanling-dsh-skills"), so it never clashes
7
+ # with the preset's own "filesystem" provider registration;
8
+ # - includeDefaultRoots stays false: no dependence on ~/.dsh/skills or any
9
+ # project skill root — the two skills travel with the bundle;
10
+ # - watch stays false: the shipped contents are static, so the catalog
11
+ # digest and request history stay stable.
12
+ #
13
+ # An installed profile resolves the skill directory and policy module through
14
+ # this package. XUANLING_DSH_SKILLS_ROOT remains a development override for the
15
+ # content root; the policy module itself must be profile-installed so Loader
16
+ # resolves one stable package specifier.
17
+
18
+ - insert:
19
+ - id: xuanling-skills
20
+ name: '@deepseek-ai/dsh-skill-filesystem'
21
+ config:
22
+ providerName: xuanling-dsh-skills
23
+ includeDefaultRoots: false
24
+ watch: false
25
+ customSkillDirs:
26
+ - !!js process.env.XUANLING_DSH_SKILLS_ROOT ?? process.getBuiltinModule('node:path').join(process.getBuiltinModule('node:path').dirname(process.getBuiltinModule('node:module').createRequire(baseUrl).resolve('@xuanling-rs/xuanling-dsh-skills/package.json')), 'skills')
27
+ - id: xuanling-file-policy
28
+ name: '@xuanling-rs/xuanling-dsh-skills/strict-overwrite-policy.mjs'
package/package.json CHANGED
@@ -1,9 +1,28 @@
1
1
  {
2
2
  "name": "@xuanling-rs/xuanling-dsh-skills",
3
- "version": "0.2.2",
4
- "description": "XuanLing bootstrap placeholder; replaced by the verified 0.2.3 release.",
3
+ "version": "0.2.3",
4
+ "description": "DeepSeek Harness bundle: mounts isolated XuanLing workflow skills and the strict MCP overwrite policy.",
5
5
  "license": "MIT",
6
6
  "private": false,
7
+ "dependencies": {
8
+ "@deepseek-ai/dsh-skill-filesystem": "^0.1.0-rc.5"
9
+ },
10
+ "files": [
11
+ "LICENSE",
12
+ "README.md",
13
+ "README-ZH.md",
14
+ "cordis.patch.yml",
15
+ "strict-overwrite-policy.mjs",
16
+ "skills/xuanling-file-workflow/SKILL.md",
17
+ "skills/xuanling-file-workflow/agents/openai.yaml",
18
+ "skills/xuanling-memory-workflow/SKILL.md",
19
+ "skills/xuanling-memory-workflow/agents/openai.yaml"
20
+ ],
21
+ "dsh": {
22
+ "bundle": {
23
+ "patch": "./cordis.patch.yml"
24
+ }
25
+ },
7
26
  "engines": {
8
27
  "node": ">=22.14.0"
9
28
  },
@@ -18,6 +37,10 @@
18
37
  },
19
38
  "publishConfig": {
20
39
  "access": "public",
40
+ "provenance": true,
21
41
  "registry": "https://registry.npmjs.org"
42
+ },
43
+ "xuanlingRelease": {
44
+ "sourceCommit": "eec429d009481e193295678b9aa244d44c5d52a2"
22
45
  }
23
46
  }
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: xuanling-file-workflow
3
+ description: Guides DeepSeek Harness agents in choosing between the harness-native file tools (read, write, edit, grep, glob) and the XuanLing mcp__xuanling__fs_ tool family mounted over MCP. Use whenever a task involves searching, reading, creating, or precisely editing files, whenever an edit must be guarded by a sha256 preimage or a reversible changeset, or whenever large tool outputs need an explicit byte budget and continuation.
4
+ ---
5
+
6
+ # XuanLing File Workflow
7
+
8
+ This workspace exposes two file-tool families. Pick one deliberately for each
9
+ operation; both are first-class, and neither is a fallback for the other.
10
+
11
+ ## Families
12
+
13
+ - **Native file tools** (`read`, `write`, `edit`, `grep`, `glob`, ...): deeply
14
+ integrated with the harness. They carry the read-before-edit observation
15
+ guard, native diff/read UI cards, and the workspace sandbox policy.
16
+ - **XuanLing tools** (`mcp__xuanling__fs_*`, for example
17
+ `mcp__xuanling__fs_read_text`, `mcp__xuanling__fs_edit`,
18
+ `mcp__xuanling__fs_search`): typed cross-platform filesystem tools with
19
+ sha256 preimage guards, explicit byte budgets, strict patches, and
20
+ resumable pagination. Results are structured JSON, identical on every OS.
21
+
22
+ ## Routing rules
23
+
24
+ 1. Prefer the native file tools for routine small edits and ordinary reads:
25
+ their observation policy and editor cards are part of the harness UX, and
26
+ they avoid extra ceremony for one-line changes.
27
+ 2. Choose the XuanLing family when the operation needs what only it provides:
28
+ - **Hash/CAS-protected writes**: verify the file is unchanged since your
29
+ last read with `expected_sha256` / `expected_preimage_sha256` before
30
+ replacing or patching it.
31
+ - **Explicit output limits**: request a bounded result with an `output`
32
+ byte budget (`max_bytes`) and continue later through the returned
33
+ cursor or resume token instead of truncating silently.
34
+ - **Strict edits**: apply a verified unified diff with
35
+ `mcp__xuanling__fs_patch` (preimage-hash guarded), or a unique-match
36
+ replacement with `mcp__xuanling__fs_edit` / `mcp__xuanling__fs_replace_text`.
37
+ - **Full pagination**: list or search with a bounded window and page
38
+ through every remaining entry with the typed cursor.
39
+ - **Whole-file creation or replacement**: use `mode: "create"` for a new
40
+ file. To replace an existing file, obtain its hash with
41
+ `mcp__xuanling__fs_read_text` (`include_sha256: true`) or
42
+ `mcp__xuanling__fs_hash`, then pass both `mode: "overwrite"` and the
43
+ returned `expected_sha256`. Never omit `mode` for a whole-file write.
44
+ 3. Do not use the shell tools (bash, pwsh, terminals) for any file operation
45
+ this skill covers; the two file families are sufficient, and shell output
46
+ is not portable evidence.
47
+ 4. Read what you need, then act. Avoid re-reading a file you just verified by
48
+ sha256; avoid issuing the same search twice without consuming the cursor.
49
+
50
+ ## Schema gotchas that bite in practice
51
+
52
+ - `mcp__xuanling__fs_search` takes the search term in `pattern`; `literal` is
53
+ a boolean, not a string. There is no `query` field.
54
+ - `mcp__xuanling__fs_glob` takes `patterns` (plural array); `*.mjs` matches
55
+ one level only, use `**/*.mjs` to recurse.
56
+ - The `output` selector of any window-capable tool is a tagged object such as
57
+ `{"mode":"bounded","max_bytes":65536}` — never a number or a bare string.
58
+
59
+ ## Failure handling
60
+
61
+ - `XUANLING_FS_OVERWRITE_REQUIRES_SHA256` means the DSH policy stopped an
62
+ unsafe whole-file replacement before MCP dispatch. Read or hash the file,
63
+ reconstruct the intended content from that current version, and retry with
64
+ `expected_sha256`. Do not switch to `mode: "create"` for an existing file.
65
+ - Treat every typed tool error as information: a duplicate-match error means
66
+ supply more context or an explicit replace-all decision; a conflict means
67
+ the file changed under you, so re-read and rebuild the edit.
68
+ - You must not silently fall back to the other family when a tool fails.
69
+ Surface the error, correct the request, and retry within the same family;
70
+ switching families because of a failure needs a stated reason.
71
+ - The XuanLing server enforces a workspace root. Paths outside it are denied
72
+ by design; fix the path instead of escalating.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "XuanLing File Workflow"
3
+ short_description: "Choose between native and XuanLing file tools"
4
+ default_prompt: "Use $xuanling-file-workflow to pick the right file tools for this edit."
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: xuanling-memory-workflow
3
+ description: Guides DeepSeek Harness agents through the XuanLing shared lexical memory lifecycle. Use when the agent finds a fact, preference, procedure, solution, or summary worth keeping across sessions, when preparing a memory candidate, or when the user asks to approve, reject, replace, or recall a stored memory. Enforces the proposal and review boundary — candidates are created pending, and only an explicit user decision completes a review.
4
+ ---
5
+
6
+ # XuanLing Memory Workflow
7
+
8
+ XuanLing memory is proposal-first: nothing you write becomes a canonical
9
+ record until a human decides on the proposal. Two separate turns, always.
10
+
11
+ ## Before writing anything
12
+
13
+ 1. Search first with `memory_search` (namespaces, scopes, and tags matter —
14
+ a duplicate record is worse than no record).
15
+ 2. Read the exact current content with `memory_get` when a hit looks close.
16
+ Updating means a replace proposal against that record's current revision,
17
+ not a second create.
18
+
19
+ ## Creating a candidate
20
+
21
+ - Call `memory_candidate_create` with the full payload: kind (`fact`,
22
+ `preference`, `procedure`, `solution`, or `summary`), content, and a
23
+ one-line title/summary. Include an `idempotency_key` you derive from the
24
+ proposal's meaning.
25
+ - The call only creates a pending candidate. Report the returned proposal id
26
+ and its revision to the user, then stop: the terminal state without review
27
+ is awaiting review.
28
+ - To retry a failed candidate call, reuse the same idempotency key with the
29
+ same payload. Changing the payload under a reused key is a conflict; that
30
+ is correct behavior, not an error to work around.
31
+ - Replacing or archiving follows the same shape: `memory_candidate_replace`
32
+ or `memory_candidate_archive` targets a specific record revision, and the
33
+ server refuses to apply it if that revision went stale.
34
+
35
+ ## The review gate
36
+
37
+ - Call `memory_review` only after an explicit user instruction — an approval
38
+ or rejection decision that names the concrete proposal. A conversational
39
+ "looks good" during other work is not that decision; ask the user to
40
+ confirm the specific proposal id if in doubt.
41
+ - Never describe yourself or this agent as the human reviewer. You propose;
42
+ the user disposes. When you report a review outcome, attribute the decision
43
+ to the user who made it.
44
+ - Never approve a proposal to finish a task, save tokens, or unblock a
45
+ workflow; an unreviewed candidate is a correct end state.
46
+
47
+ ## When not to write
48
+
49
+ - Parse failures, model hiccups, tool errors, or an unavailable store mean
50
+ you skip the write entirely. Do not create partial or best-effort
51
+ candidates to compensate; just continue the user's task and mention the
52
+ skipped save if it matters.
53
+ - Nothing here authorizes writing secrets, raw credentials, or user-private
54
+ content into the shared store.
55
+ - Feedback after recall uses `memory_feedback` on a specific record revision
56
+ and is safe anytime.
57
+
58
+ ## Scope and namespace quick reference
59
+
60
+ - `scope` is a tagged object: `{"type":"global"}`,
61
+ `{"type":"project","project_id":...}`, or
62
+ `{"type":"workspace","project_id":...,"workspace_id":...}`.
63
+ - Search walks ancestor scopes only when asked; sibling projects never leak.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "XuanLing Memory Workflow"
3
+ short_description: "Proposal-first XuanLing memory lifecycle"
4
+ default_prompt: "Use $xuanling-memory-workflow to save this insight as a pending proposal."
@@ -0,0 +1,45 @@
1
+ const GUARDED_TOOL = "mcp__xuanling__fs_write_text";
2
+
3
+ export const STRICT_OVERWRITE_DENIAL =
4
+ "[XUANLING_FS_OVERWRITE_REQUIRES_SHA256] " +
5
+ "mcp__xuanling__fs_write_text mode=overwrite requires a non-empty " +
6
+ "expected_sha256; read with include_sha256=true or call " +
7
+ "mcp__xuanling__fs_hash, then retry";
8
+
9
+ export const name = "xuanling-strict-overwrite-policy";
10
+
11
+ /**
12
+ * Decide only the DSH-specific precondition. XuanLing remains responsible for
13
+ * canonical schema validation, hash format, current-file CAS, and filesystem
14
+ * effects.
15
+ */
16
+ export function decideStrictOverwrite(toolName, argumentsValue) {
17
+ if (toolName !== GUARDED_TOOL) return { kind: "delegate" };
18
+ if (
19
+ typeof argumentsValue !== "object" ||
20
+ argumentsValue === null ||
21
+ Array.isArray(argumentsValue)
22
+ ) {
23
+ return { kind: "delegate" };
24
+ }
25
+
26
+ const mode = argumentsValue.mode;
27
+ if (mode === "create") return { kind: "delegate" };
28
+ if (mode !== undefined && mode !== "overwrite") {
29
+ return { kind: "delegate" };
30
+ }
31
+
32
+ const expectedSha256 = argumentsValue.expected_sha256;
33
+ if (typeof expectedSha256 === "string" && expectedSha256.length > 0) {
34
+ return { kind: "delegate" };
35
+ }
36
+ return { kind: "deny", reason: STRICT_OVERWRITE_DENIAL };
37
+ }
38
+
39
+ export function apply(ctx) {
40
+ ctx.on("tools/pre-execute", (exec, next) => {
41
+ const decision = decideStrictOverwrite(exec.name, exec.arguments);
42
+ if (decision.kind === "deny") return Promise.resolve(decision);
43
+ return next();
44
+ });
45
+ }