dsh-minimal-ptc 0.4.7 → 0.5.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.
package/README.en.md CHANGED
@@ -1,103 +1,71 @@
1
- # dsh-minimal-ptc
2
-
3
- ![npm](https://img.shields.io/npm/v/dsh-minimal-ptc) ![downloads](https://img.shields.io/npm/dm/dsh-minimal-ptc) ![license](https://img.shields.io/github/license/STARDUSTLC666/dsh-minimal-ptc) ![stars](https://img.shields.io/github/stars/STARDUSTLC666/dsh-minimal-ptc?style=social)
4
-
5
- > Minimal prompt x full PTC capabilities — a cleaner coding agent.
6
- > Installing gives you a new agent mode: **Minimal PTC**, with Git Bash and persistent PowerShell on Windows, compatible with Harness 0.1.5-rc.2 and 0.1.6-alpha.1.
7
-
8
- ## Highlights
9
-
10
- - **RL-aligned**: the whole system prompt is one sentence — `You are a helpful software engineer assistant.` — close to the compact instruction distribution used during RL fine-tuning, without long-prompt format bias or context noise.
11
- - **Complete PTC surface**: provides `run_code` SDK orchestration, files and search, Shell, Skills, plan mode, goals, subagents, Ralph, and web search/fetch; the general-purpose workflow tool stays hidden as in alpha.4.
12
- - **We / Let's reasoning**: the PTC SDK packs thinking and doing into one TypeScript program, orchestrating multi-step operations before executing them once. This matches the high-scoring Minimal trajectory in DeepSeek's official Project2 V4.1b runs (99/96), where reasoning is dominated by `we` / `let's` instead of the standard-like `let me` / `I` blocks seen at 91/92.
13
- - **Git Bash on Windows**: ships a preset-local Git Bash executor (GIT_BASH -> Program Files\Git -> LOCALAPPDATA\Git -> PATH). The bash tool is no longer disabled on Windows.
14
- - **Persistent PowerShell on Windows**: mirrors the `dsh-v0.1.5-rc.1` minimal preset; `pwsh` runs as a persistent PTY session, so cwd, variables, and functions survive across calls.
15
-
16
- ## Compatibility
17
-
18
- Verified with official source builds of Harness `0.1.5-rc.2` and `0.1.6-alpha.1` on 2026-09-16: all 18 components load alongside ModLens, with passing tool schemas, skill registration, offline read-only calls, real Agent preset mounting, and plugin calls through `run_code`. Uses the `cordis.patch.yml` + `dsh.bundle.patch` bundle model. Node requirements are 22.19 or later within 22.x, or 24 or later. Live external-service workflows require separate configuration and validation.
19
-
20
- Since 0.4.6, the plugin selects the workflow provider after host startup: `workflow-ptc` on 0.1.6 and `workflow-worker-thread` on 0.1.5. Managed presets refresh when the plugin version or host runtime family changes. Local edits on the same version and runtime, and user-created presets without a marker, remain untouched. Since 0.4.7, the preset restores the official 0.1.6 `ptc` rows `present` / `command-goal` / `tool-plugin-manager` (disabled) plus `modelSelectionSettings` on subagent spawn, and a startup health check guards the `reading 'prepare'` failure modes (see Troubleshooting).
21
-
22
- The Minimal PTC preset also mounts in a real agent and assembles `run_code` as the model-facing tool while retaining installed plugin tools and Windows Git Bash. Uses the persona `prefix` field introduced in Harness 0.1.3; use plugin 0.4.3 with older Harness versions. Since 0.4.5, the preset update marker reads the package version automatically so upgrades cannot leave an older preset because of a stale hard-coded version.
23
-
24
- ## Installation
25
-
26
- 1. Add this package to a web profile (`package.json`):
27
-
28
- ```json
29
- "dependencies": { "dsh-minimal-ptc": "^0.4.0" },
30
- "dsh": { "profile": { "bundles": [..., "dsh-minimal-ptc"] } }
31
- ```
32
-
33
- Local development can use a link: `"dsh-minimal-ptc": "link:E://deepseek//dsh-minimal-ptc"`.
34
-
35
- 2. Run `pnpm install` in the profile directory.
36
-
37
- 3. Restart the web profile process. The host row materializes the bundled preset into `$DSH_HOME/.agent-presets/ptc-minimal`.
38
-
39
- 4. Select **Minimal PTC** when starting a new session.
40
-
41
- ## Troubleshooting: `Cannot read properties of undefined (reading 'prepare')`
42
-
43
- When every tool call (including `run_code`) fails with this error while sessions mount fine, the root cause is **two identities of the dsh-tools scheduler key (a Symbol) inside one process**. Two confirmed triggers:
44
-
45
- 1. **A duplicate core package inside a profile**: a third-party plugin lists `@deepseek-ai/*` under `dependencies` (it belongs in `peerDependencies`), a tarball install drags in transitive copies, or stale `node_modules` linger. Check:
46
-
47
- ```bash
48
- # Any output means trouble (should be empty)
49
- ls ~/.dsh/profiles/*/node_modules/@deepseek-ai 2>/dev/null
50
- ```
51
-
52
- Fix: move the `@deepseek-ai` directory out of that profile's `node_modules` (or fix the offending plugin's dependencies and reinstall), then restart dsh.
53
-
54
- 2. **The 0.1.6-alpha host's own dual build outputs**: the `@deepseek-ai/dsh-tools` exports map routes `./types` and `./presentation` to a second compiled tree (`lib/types/*.js`) next to the bundle (`lib/index.js`) — the key splits even with zero extra copies. The root fix, in `packages/core/tools/src/index.ts`:
55
-
56
- ```ts
57
- Symbol('@deepseek-ai/dsh-tools.scheduler') → Symbol.for('@deepseek-ai/dsh-tools.scheduler')
58
- ```
59
-
60
- `Symbol.for` uses the global symbol registry, so the key stays identical across module instances and both triggers are disarmed.
61
-
62
- **Since 0.4.7 this plugin self-checks at startup**: if a profile holds core-package copies, or the host still uses a module-local Symbol key (unpatched), it logs a warning with the matching remediation. Warnings never block startup.
63
-
64
- ## Uninstall
65
-
66
- ```bash
67
- dsh plugin --profile web remove dsh-minimal-ptc
68
- ```
69
-
70
- Then restart the web service. To clean up fully, also remove the plugin entry from your profile `cordis.patch.yml` if you overrode it.
71
-
72
-
73
- ## Capabilities
74
-
75
- - Web search and page fetch are enabled via `tool-web` (`fetch: true`).
76
- - Subagents and Ralph are enabled; the general-purpose workflow tool remains hidden in PTC mode.
77
- - `subagent_codex` and `subagent_claude_code` providers are disabled by default; remove their `disabled: true` lines to expose them.
78
-
79
- ## Windows Git Bash configuration
80
-
81
- The preset-local Git Bash executor can be overridden in `agent.cordis.yml` under `gitbash-executor`:
82
-
83
- | Option | Default | Meaning |
84
- | :-- | :-- | :-- |
85
- | `shellPath` | auto-detected | Fixed Git Bash path (e.g. `C:\\Program Files\\Git\\bin\\bash.exe`) |
86
- | `timeoutMs` | 120000 | Per-command timeout (ms) |
87
- | `maxTimeoutMs` | 600000 | Maximum timeout a request may ask for |
88
- | `maxOutputBytes` | 64000 | Per-call output cap |
89
- | `maxSpillBytes` | 67108864 | Output spill-to-disk cap |
90
- | `graceMs` | 3000 | Grace period after timeout |
91
-
92
- Detection order: `GIT_BASH` -> `Program Files\\Git` -> `Program Files (x86)\\Git` -> `LOCALAPPDATA\\Programs\\Git` -> PATH.
93
-
94
- ## Materialization policy
95
-
96
- - No target directory -> write all preset files and a version marker.
97
- - Plugin version or host runtime family changes -> refresh managed files.
98
- - Directory exists without a marker (treated as user-created) -> leave it untouched.
99
- - Upgrading: bump `version` in `package.json`; the marker reads it automatically.
100
-
101
- ## License
102
-
103
- MIT
1
+ [中文](README.md)
2
+
3
+ # dsh-minimal-ptc
4
+
5
+ ## 0.5.1 update (2026-09-27)
6
+
7
+ Declares the tools service dependency so the startup health check can inspect the tool scheduler on the current Cordis host.
8
+
9
+ Validation host: Harness 0.1.7-rc.2 built from official sources, retaining the local tool-scheduler fix. Build and automated checks pass; interactive coverage and external-service limits are recorded in this release round.
10
+
11
+ Adds **Minimal PTC** to DeepSeek Harness: a concise system prompt with files, terminals, search, skills and installed plugin tools, orchestrated through `run_code`. Windows includes Git Bash and persistent PowerShell.
12
+
13
+ ## Install and use
14
+
15
+ Version 0.5.0 requires **Harness 0.1.7 or later**. Use `dsh-minimal-ptc@0.4.7` on Harness 0.1.5/0.1.6.
16
+
17
+ ```bash
18
+ dsh plugin --profile web add dsh-minimal-ptc
19
+ ```
20
+
21
+ Restart `dsh web`, start a new session and choose **极简 PTC 模式** (Minimal PTC) from the mode picker above the message box. Describe your task normally; no preset directory or YAML editing is required.
22
+
23
+ For example: “Run this project’s tests, find the failures and fix them.” Existing email, calendar and other plugin tools remain available.
24
+
25
+ ## Changes in 0.5.0
26
+
27
+ - Registers through the official Harness 0.1.7 declarative Agent preset service, fixing the missing mode after a host upgrade.
28
+ - Installs and updates the preset with the plugin. Existing user content in `.agent-presets/ptc-minimal` is preserved.
29
+ - Checks for conflicting runtime packages without flagging supported helpers such as `schemastery` and `cosmokit`.
30
+ - Uses `workflow-ptc` and retains plugin tools, Git Bash, persistent PowerShell, search, plans, goals and subagents.
31
+
32
+ ## Compatibility and validation
33
+
34
+ Tested on 2026-09-23 with official-source **Harness 0.1.7-alpha.2**, including a local `Symbol.for` tool-scheduler fix. All 18 plugins load together with passing tool contracts and skill registration. The real Web mode picker lists and selects the preset; a real agent mounts it with `run_code` as its model entry point while retaining plugin tools and the shell.
35
+
36
+ A real `run_code` call to the RSS plugin passed in a sandboxed Windows workspace and again after restart. The fixture owner has full control of the disposable directory so the host can apply sandbox permissions. External mail, databases and other services still require their own valid configuration.
37
+
38
+ Requires Node 22.19 or later within 22.x, or 24 or later.
39
+
40
+ ## Windows terminals
41
+
42
+ A standard Git for Windows installation is detected automatically. For a custom location, set `GIT_BASH` to the full path of `bash.exe` before starting DSH. PowerShell sessions preserve their current directory, variables and functions.
43
+
44
+ Developers creating their own preset can use the bundled `ptc-minimal.patch.yml` as a reference; the executor module is `dsh-minimal-ptc/gitbash-executor`.
45
+
46
+ | Executor option | Default | Purpose |
47
+ | :-- | :-- | :-- |
48
+ | `shellPath` | auto-detected | Git Bash path |
49
+ | `timeoutMs` | 120000 | Per-command timeout in ms |
50
+ | `maxTimeoutMs` | 600000 | Maximum requested timeout |
51
+ | `maxOutputBytes` | 64000 | Output cap per call |
52
+ | `maxSpillBytes` | 67108864 | Output spill-to-disk cap |
53
+ | `graceMs` | 3000 | Grace period after timeout |
54
+
55
+ ## Troubleshooting
56
+
57
+ If the mode is missing, confirm Harness is 0.1.7 or later and restart after installation. Recreating a retired preset directory will not help: the new host does not discover presets there.
58
+
59
+ If every tool fails with `Cannot read properties of undefined (reading 'prepare')`, check startup logs for duplicate runtime packages. Update the plugin bringing in extra `dsh-tools` / `cordis` copies and reinstall dependencies. Do not remove the entire `@deepseek-ai` directory: public helpers are supported dependencies. Another confirmed cause is the host loading two tool build outputs with a module-local scheduler `Symbol`; source builds can use `Symbol.for('@deepseek-ai/dsh-tools.scheduler')` and rebuild.
60
+
61
+ ## Uninstall
62
+
63
+ ```bash
64
+ dsh plugin --profile web remove dsh-minimal-ptc
65
+ ```
66
+
67
+ Restart the Web service afterward.
68
+
69
+ ## License
70
+
71
+ MIT
package/README.md CHANGED
@@ -1,114 +1,71 @@
1
- # dsh-minimal-ptc
2
-
3
- ![npm](https://img.shields.io/npm/v/dsh-minimal-ptc) ![downloads](https://img.shields.io/npm/dm/dsh-minimal-ptc) ![license](https://img.shields.io/github/license/STARDUSTLC666/dsh-minimal-ptc) ![stars](https://img.shields.io/github/stars/STARDUSTLC666/dsh-minimal-ptc?style=social)
4
-
5
- > 极简提示词 × PTC 全能力 —— 一个更"干净"的编码 Agent。
6
- > 安装即获得新的 Agent 模式:**极简 PTC 模式**;Windows 自动启用 Git Bash 与持久 PowerShell,兼容 Harness 0.1.5-rc.2 和 0.1.6-alpha.1。
7
-
8
- ## 卖点
9
-
10
- - **对齐 RL 训练**:系统提示词只有一句 `You are a helpful software engineer assistant.`,
11
- 贴近 RL 微调时的简洁指令分布,没有长提示词带来的格式偏置与上下文噪音,
12
- 让模型按训练时的节奏干活。
13
- - **PTC 工具面完整**:提供 `run_code` SDK 多步编排、文件读写与检索、Shell、
14
- Skills、计划、目标、子代理、Ralph 与网页搜索/抓取;按 alpha.4 默认隐藏通用 workflow 工具。
15
- - **We / Let's 思维链**:PTC SDK 把"想"和"做"装进一个 TypeScript 程序,
16
- 多步操作先编排、再一次执行。这与 DeepSeek 官方跑分环境(Project2 V4.1b)中
17
- Minimal 高分轨迹一致:99/96 的两跑以 `we` / `let's` 为主,而不是
18
- Standard/PTC 常见的 `let me` / `I` 长块。
19
- - **Windows 保持 bash**:预设内置 Git Bash executor(自动探测 GIT_BASH → Program Files\Git → LOCALAPPDATA\Git → PATH),`bash` 工具不再在 Windows 上被禁用。
20
- - **Windows 持久 PowerShell**:对齐 `dsh-v0.1.5-rc.1` 的 minimal 预设,`pwsh` 使用持久 PTY 会话,cwd、变量、函数跨调用保留。
21
-
22
- ## 兼容性
23
-
24
- 已在官方源码构建的 Harness `0.1.5-rc.2` 和 `0.1.6-alpha.1` 上验证(2026-09-16):18 个组件与 ModLens 同载,工具 schema、技能注册、离线只读调用、真实 Agent 预设挂载及 `run_code` 调用插件工具通过。采用 `cordis.patch.yml` + `dsh.bundle.patch` 组合包模型。Node 要求为 22.19 及以上的 22.x,或 24 及以上。外部服务的实际业务操作需按各组件配置单独验证。
25
-
26
- 0.4.6 起,插件等待宿主启动完成后选择工作流运行时:0.1.6 使用 `workflow-ptc`,0.1.5 保留 `workflow-worker-thread`。受管理的预设会在插件版本或运行时种类变化时刷新;同版本、同运行时的本地修改以及无版本标记的自建预设保持不变。0.4.7 起预设补齐官方 0.1.6 `ptc` 的 `present` / `command-goal` / `tool-plugin-manager`(默认关闭)行与 subagent 的 `modelSelectionSettings`,并新增启动健康检查(见下文故障排查)。
27
-
28
- 另已在真实 agent 中挂载极简 PTC 预设并组装模型工具:模型入口为 `run_code`,安装的插件工具和 Windows Git Bash 均可用。沿用 0.1.3 起的 persona `prefix` 字段;更旧的 Harness 请使用插件 0.4.3。0.4.5 起,预设更新标记自动读取包版本,避免升级后仍保留旧预设。
29
-
30
- ## 安装
31
-
32
- 1. 把本包加入 web profile(`package.json`):
33
-
34
- ```json
35
- "dependencies": { "dsh-minimal-ptc": "^0.4.0" },
36
- "dsh": { "profile": { "bundles": [..., "dsh-minimal-ptc"] } }
37
- ```
38
-
39
- 本地开发也可以用 link:`"dsh-minimal-ptc": "link:E://deepseek//dsh-minimal-ptc"`。
40
-
41
- 2. 在 profile 目录执行 `pnpm install`。
42
-
43
- 3. 重启 web profile 进程:宿主行会把内置预设物化到
44
- `$DSH_HOME/.agent-presets/ptc-minimal`。
45
-
46
- 4. 新建会话时选择 **极简 PTC 模式**。
47
-
48
- ## 故障排查:`Cannot read properties of undefined (reading 'prepare')`
49
-
50
- 每次工具调用(含 `run_code`)都以这个错误失败、且会话在挂载期一切正常时,根因是 **dsh-tools 的调度器键(一个 Symbol)在进程内出现了两个身份**。两个已确认的触发路径:
51
-
52
- 1. **profile 里多装了一份核心包**:某个第三方插件把 `@deepseek-ai/*` 写进了 `dependencies`(应为 `peerDependencies`)、tarball 安装拖入传递副本,或旧 `node_modules` 残留。检查:
53
-
54
- ```bash
55
- # 任一命令有输出即为中招(应为空)
56
- ls ~/.dsh/profiles/*/node_modules/@deepseek-ai 2>/dev/null
57
- ```
58
-
59
- 修复:把该 profile `node_modules` 下的 `@deepseek-ai` 目录移走(或整改插件依赖后重装),重启 dsh。
60
-
61
- 2. **0.1.6-alpha 宿主自身的双构建产物**:`@deepseek-ai/dsh-tools` 的 exports 把 `./types`、`./presentation` 子路径指向第二套编译输出(`lib/types/*.js`),与打包产物 `lib/index.js` 并存时调度器键同样分裂——即使没有装任何多余副本也会中招。根治办法是把 `packages/core/tools/src/index.ts` 里的
62
-
63
- ```ts
64
- Symbol('@deepseek-ai/dsh-tools.scheduler') → Symbol.for('@deepseek-ai/dsh-tools.scheduler')
65
- ```
66
-
67
- `Symbol.for` 走全局符号注册表,跨模块实例恒等,两类触发路径同时免疫。
68
-
69
- **本插件自 0.4.7 起在启动时自动体检**:发现 profile 内核心包副本、或宿主仍使用模块本地 Symbol 键(未打上述补丁)时,会在日志里给出对应警告与修复指引(只警告,不阻断启动)。
70
-
71
- ## 卸载
72
-
73
- ```bash
74
- dsh plugin --profile web remove dsh-minimal-ptc
75
- ```
76
-
77
- 卸载后重启 Web 服务。如需彻底清理,可再手动删除自己 profile `cordis.patch.yml` 中覆盖的插件行。
78
-
79
-
80
- ## Windows Git Bash 配置
81
-
82
- 预设内置的 Git Bash executor 可在 `agent.cordis.yml` 的 `gitbash-executor` 行覆盖:
83
-
84
- | 配置 | 默认 | 说明 |
85
- | :-- | :-- | :-- |
86
- | `shellPath` | 自动探测 | 固定 Git Bash 路径(如 `C:\\Program Files\\Git\\bin\\bash.exe`) |
87
- | `timeoutMs` | 120000 | 单次命令超时(毫秒) |
88
- | `maxTimeoutMs` | 600000 | 请求可要求的最大超时 |
89
- | `maxOutputBytes` | 64000 | 单次输出上限 |
90
- | `maxSpillBytes` | 67108864 | 输出溢出落盘上限 |
91
- | `graceMs` | 3000 | 超时后的宽限时间 |
92
-
93
- 自动探测顺序:`GIT_BASH` → `Program Files\\Git` → `Program Files (x86)\\Git` → `LOCALAPPDATA\\Programs\\Git` → PATH。
94
-
95
- ## 目录结构
96
-
97
- ```
98
- dsh-minimal-ptc/
99
- ├── cordis.patch.yml # 插入宿主行(物化预设)
100
- ├── lib/index.js # 宿主插件:物化 ptc-minimal 预设到用户预设根目录
101
- └── presets/ptc-minimal/ # 内置 Agent 模式(极简提示词 + PTC 全能力)
102
- ├── agent.cordis.yml
103
- ├── gitbash-executor.mjs # Windows Git Bash 探测与执行器(零依赖)
104
- └── preset.yml
105
- ```
106
-
107
- ## 说明
108
-
109
- - 物化策略:目标目录不存在时写入全部文件;插件版本或宿主运行时种类变化时刷新受管理文件;无标记的自建预设不覆盖。
110
- - 升级插件只需更新 `package.json` 的版本;预设标记自动读取该版本。
111
-
112
- ## 许可证
113
-
114
- MIT
1
+ [English](README.en.md)
2
+
3
+ # dsh-minimal-ptc
4
+
5
+ ## 0.5.1 更新(2026-09-27)
6
+
7
+ 补齐 tools 服务依赖声明,让启动健康检查可以在新版 Cordis 宿主中读取工具调度器。
8
+
9
+ 验证宿主:官方源码构建的 Harness 0.1.7-rc.2(保留本地工具调度器修复)。构建与自动测试通过;实际操作和外部服务限制见本轮验收记录。
10
+
11
+ 给 DeepSeek Harness 添加「极简 PTC 模式」:使用简短的系统提示词,保留文件、终端、搜索、技能与已安装插件,通过 `run_code` 编排多步操作。Windows 支持 Git Bash 和持久 PowerShell。
12
+
13
+ ## 安装和使用
14
+
15
+ 0.5.0 需要 **Harness 0.1.7 及以上**。仍使用 Harness 0.1.5/0.1.6 时,请安装 `dsh-minimal-ptc@0.4.7`。
16
+
17
+ ```bash
18
+ dsh plugin --profile web add dsh-minimal-ptc
19
+ ```
20
+
21
+ 重启 `dsh web`,新建会话,在输入框上方的模式列表中选择 **极简 PTC 模式**,然后像平时一样描述任务。无需创建预设目录或修改 YAML。
22
+
23
+ 例如:「检查这个项目的测试,找出失败原因并修复。」已有的邮件、日历等插件也可按原来的方式使用。
24
+
25
+ ## 0.5.0 的变化
26
+
27
+ - 使用 Harness 0.1.7 官方的声明式 Agent 预设注册方式,修复升级后模式消失的问题。
28
+ - 预设随插件安装和更新;保留用户旧的 `.agent-presets/ptc-minimal` 目录,不覆盖其中的自定义内容。
29
+ - 启动检查只提示会影响工具运行的核心包副本,不再把 `schemastery`、`cosmokit` 等正常依赖误报为冲突。
30
+ - 使用新版 `workflow-ptc`,保留插件工具、Git Bash、持久 PowerShell、搜索、计划、目标与子代理能力。
31
+
32
+ ## 兼容性与验证
33
+
34
+ 2026-09-23 在官方源码构建的 **Harness 0.1.7-alpha.2** 上验证(含本地工具调度器 `Symbol.for` 修复):18 个插件同载,工具契约与技能注册通过;极简 PTC 出现在实际网页模式列表中并可选择,真实 Agent 挂载后以 `run_code` 为模型入口,保留插件工具与 Shell。
35
+
36
+ 已在沙箱开启的 Windows 隔离工作区通过 `run_code` 实际调用 RSS 插件,重启后再次通过。测试工作区由当前用户拥有完整管理权限,以便宿主设置沙箱权限;外部邮箱、数据库等业务仍需各插件的有效配置。
37
+
38
+ Node 要求为 22.19 及以上的 22.x,或 24 及以上。
39
+
40
+ ## Windows 终端
41
+
42
+ 安装常规版 Git for Windows 后会自动找到 Git Bash。若安装在自定义位置,可设置 `GIT_BASH` 为 `bash.exe` 的完整路径,再启动 DSH。PowerShell 会话会保留当前目录、变量和函数。
43
+
44
+ 开发者如需自建预设,可参考包内的 `ptc-minimal.patch.yml`,执行器模块为 `dsh-minimal-ptc/gitbash-executor`。
45
+
46
+ | 执行器选项 | 默认值 | 作用 |
47
+ | :-- | :-- | :-- |
48
+ | `shellPath` | 自动探测 | 指定 Git Bash 路径 |
49
+ | `timeoutMs` | 120000 | 单次命令超时,毫秒 |
50
+ | `maxTimeoutMs` | 600000 | 允许请求的最长超时 |
51
+ | `maxOutputBytes` | 64000 | 单次输出上限 |
52
+ | `maxSpillBytes` | 67108864 | 输出落盘上限 |
53
+ | `graceMs` | 3000 | 超时后的退出宽限时间 |
54
+
55
+ ## 排错
56
+
57
+ 模式未出现时,先确认 DSH 为 0.1.7 及以上且安装后已重启。不要通过重建旧预设目录解决,新宿主不再从该目录发现预设。
58
+
59
+ 若每个工具都报 `Cannot read properties of undefined (reading 'prepare')`,查看启动日志中的核心包冲突提示。应升级带入额外 `dsh-tools` / `cordis` 副本的插件并重新安装依赖;不要删除整个 `@deepseek-ai` 目录,官方的公共辅助包属于正常依赖。另一个已确认原因是宿主同时加载两份工具构建产物且调度器键使用模块局部 `Symbol`;源码构建可将其改为 `Symbol.for('@deepseek-ai/dsh-tools.scheduler')` 后重新构建。
60
+
61
+ ## 卸载
62
+
63
+ ```bash
64
+ dsh plugin --profile web remove dsh-minimal-ptc
65
+ ```
66
+
67
+ 重启 Web 服务后生效。
68
+
69
+ ## License
70
+
71
+ MIT
package/lib/index.js CHANGED
@@ -1,167 +1,172 @@
1
- // dsh-minimal-ptc 宿主行:把内置的 ptc-minimal 预设物化到用户预设根目录。
2
- //
3
- // 预设发现是实时重读的,因此安装完成后重启一次 web profile 进程,
4
- // 选择器里就会出现「极简 PTC 模式」。
5
- //
6
- // 物化策略:目标目录不存在 → 写入全部文件并留版本标记;
7
- // 版本标记低于当前版本 → 用插件自带文件刷新;
8
- // 目录存在但无标记(视为用户自建)→ 不覆盖。
9
- //
10
- // 零运行时依赖:harness home 的解析逻辑内置(DSH_HOME 环境变量优先,
11
- // 否则 ~/.dsh),与 dsh 官方规则一致。
12
- import { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync } from 'node:fs'
13
- import { homedir } from 'node:os'
14
- import { join, resolve } from 'node:path'
15
- import { fileURLToPath } from 'node:url'
16
- import pkg from '../package.json' with { type: 'json' }
17
-
18
- export const name = 'ptc-minimal-preset'
19
- export const inject = ['appReady']
20
-
21
- const VERSION = pkg.version
22
- const PRESET_ID = 'ptc-minimal'
23
- const MARKER = '.dsh-ptc-minimal.version'
24
-
25
- // dsh-tools keys its tool scheduler with this symbol description. On stock
26
- // hosts it is a module-local Symbol(), so any second dsh-tools instance
27
- // (duplicate profile copy, or the package's own dual build outputs on
28
- // 0.1.6-alpha) breaks the agent-loop lookup: every tool call then fails with
29
- // "Cannot read properties of undefined (reading 'prepare')".
30
- const SCHEDULER_SYMBOL_DESC = '@deepseek-ai/dsh-tools.scheduler'
31
-
32
- const packageDir = fileURLToPath(new URL('..', import.meta.url))
33
- const presetSourceDir = join(packageDir, 'presets', PRESET_ID)
34
-
35
- /** 与 @deepseek-ai/dsh-home-paths 相同的解析规则:DSH_HOME > ~/.dsh。 */
36
- function dshHomePath(...segments) {
37
- const env = process.env.DSH_HOME
38
- const fromEnv = typeof env === 'string' && env.trim().length > 0 ? env : null
39
- let base = fromEnv ?? join(homedir(), '.dsh')
40
- if (base === '~') base = homedir()
41
- if (base.startsWith('~/') || base.startsWith('~\\')) base = join(homedir(), base.slice(2))
42
- return resolve(base, ...segments)
43
- }
44
-
45
- function materialize(logger, modernRuntime) {
46
- const dir = dshHomePath('.agent-presets', PRESET_ID)
47
- mkdirSync(dir, { recursive: true })
48
- const revision = modernRuntime ? `${VERSION}:ptc-runtime` : VERSION
49
-
50
- let marker = null
51
- try {
52
- marker = readFileSync(join(dir, MARKER), 'utf8').trim()
53
- } catch {
54
- // 无标记:可能是首次安装,也可能是用户自建目录
55
- }
56
-
57
- if (marker === revision) return
58
- if (marker === null && existsSync(join(dir, 'agent.cordis.yml'))) {
59
- logger?.warn(`dsh-minimal-ptc: ${dir} exists without our marker; leaving it alone`)
60
- return
61
- }
62
-
63
- for (const file of ['agent.cordis.yml', 'preset.yml', 'gitbash-executor.mjs']) {
64
- let content = readFileSync(join(presetSourceDir, file), 'utf8')
65
- if (modernRuntime && file === 'agent.cordis.yml') {
66
- content = content.replaceAll('workflow-worker-thread', 'workflow-ptc')
67
- .replaceAll('`codeRuntime`', '`ptcRuntime`')
68
- }
69
- writeFileSync(join(dir, file), content)
70
- }
71
- writeFileSync(join(dir, MARKER), revision + '\n')
72
- logger?.info(`dsh-minimal-ptc: materialized agent preset "${PRESET_ID}" into ${dir}`)
73
- }
74
-
75
- export function apply(ctx) {
76
- ctx.effect(() => ctx.appReady.onReady(() => {
77
- try {
78
- materialize(ctx.logger, ctx.get('ptcRuntime') !== undefined)
79
- } catch (error) {
80
- ctx.logger?.warn(`dsh-minimal-ptc: preset materialization failed: ${String(error)}`)
81
- }
82
- try {
83
- healthCheck(ctx)
84
- } catch (error) {
85
- ctx.logger?.warn(`dsh-minimal-ptc: health check failed: ${String(error)}`)
86
- }
87
- }))
88
- }
89
-
90
- /**
91
- * Warn about the two known causes of "Cannot read properties of undefined
92
- * (reading 'prepare')" before the first session hits them. Warnings only —
93
- * nothing here blocks startup.
94
- */
95
- function healthCheck(ctx) {
96
- const logger = ctx.logger
97
-
98
- // Cause 1 (most common in the wild): a plugin or stale install left a
99
- // physical copy of @deepseek-ai/* inside some profile's node_modules. The
100
- // core must come from the CLI's own dependency tree only.
101
- for (const hit of findProfileCoreCopies()) {
102
- logger?.warn(
103
- `dsh-minimal-ptc: duplicate core package in profile: ${hit}\n`
104
- + ' A second @deepseek-ai copy breaks the tool scheduler key (module-local Symbol) '
105
- + 'and every tool call fails with "reading \'prepare\'".\n'
106
- + ' Fix: remove the @deepseek-ai directory from that profile\'s node_modules '
107
- + '(and reinstall the offending plugin with core packages in peerDependencies), then restart.',
108
- )
109
- }
110
-
111
- // Cause 2 (seen on stock 0.1.6-alpha): the host itself can load two dsh-tools
112
- // instances (bundled lib/index.js vs per-module lib/types/*.js). It is safe
113
- // only when the scheduler key survives multiple instances, i.e. the host was
114
- // built with Symbol.for. Probe exactly that.
115
- const status = schedulerKeyStatus(ctx.tools)
116
- if (status === 'module-local') {
117
- logger?.warn(
118
- 'dsh-minimal-ptc: this host keys the tool scheduler with a module-local Symbol '
119
- + '(unpatched dsh-tools). PTC sessions break with "reading \'prepare\'" '
120
- + 'whenever a second dsh-tools instance loads in this process.\n'
121
- + ' Fix: rebuild dsh-tools with `Symbol.for(\'@deepseek-ai/dsh-tools.scheduler\')` '
122
- + 'in packages/core/tools/src/index.ts, or keep a single dsh-tools copy.',
123
- )
124
- }
125
- }
126
-
127
- /**
128
- * Physical @deepseek-ai copies under any profile's node_modules.
129
- * @returns {string[]} paths like "<profile>/node_modules/@deepseek-ai/<pkg>"
130
- */
131
- export function findProfileCoreCopies(home = dshHomePath('profiles')) {
132
- const hits = []
133
- let profiles = []
134
- try {
135
- profiles = readdirSync(home, { withFileTypes: true })
136
- } catch {
137
- return hits
138
- }
139
- for (const profile of profiles) {
140
- if (!profile.isDirectory()) continue
141
- const scopeDir = join(home, profile.name, 'node_modules', '@deepseek-ai')
142
- let entries = []
143
- try {
144
- entries = readdirSync(scopeDir, { withFileTypes: true })
145
- } catch {
146
- continue
147
- }
148
- for (const entry of entries) {
149
- if (entry.isDirectory()) hits.push(join(scopeDir, entry.name))
150
- }
151
- }
152
- return hits
153
- }
154
-
155
- /**
156
- * How the host's tool registry exposes the scheduler key:
157
- * - 'global' — Symbol.for key works; safe across duplicate instances.
158
- * - 'module-local' — registry carries a same-description local Symbol; the
159
- * agent loop breaks if a second dsh-tools instance loads.
160
- * - 'absent' — no tools registry / no scheduler mounted (nothing to say).
161
- */
162
- export function schedulerKeyStatus(tools) {
163
- if (tools == null || (typeof tools !== 'object' && typeof tools !== 'function')) return 'absent'
164
- if (tools[Symbol.for(SCHEDULER_SYMBOL_DESC)] !== undefined) return 'global'
165
- const local = Object.getOwnPropertySymbols(tools).some(s => s.description === SCHEDULER_SYMBOL_DESC)
166
- return local ? 'module-local' : 'absent'
167
- }
1
+ // dsh-minimal-ptc 宿主行:把内置的 ptc-minimal 预设物化到用户预设根目录。
2
+ //
3
+ // 预设发现是实时重读的,因此安装完成后重启一次 web profile 进程,
4
+ // 选择器里就会出现「极简 PTC 模式」。
5
+ //
6
+ // 物化策略:目标目录不存在 → 写入全部文件并留版本标记;
7
+ // 版本标记低于当前版本 → 用插件自带文件刷新;
8
+ // 目录存在但无标记(视为用户自建)→ 不覆盖。
9
+ //
10
+ // 零运行时依赖:harness home 的解析逻辑内置(DSH_HOME 环境变量优先,
11
+ // 否则 ~/.dsh),与 dsh 官方规则一致。
12
+ import { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync } from 'node:fs'
13
+ import { homedir } from 'node:os'
14
+ import { join, resolve } from 'node:path'
15
+ import { fileURLToPath } from 'node:url'
16
+ import pkg from '../package.json' with { type: 'json' }
17
+
18
+ export const name = 'ptc-minimal-preset'
19
+ export const inject = ['appReady', 'tools']
20
+
21
+ const VERSION = pkg.version
22
+ const PRESET_ID = 'ptc-minimal'
23
+ const MARKER = '.dsh-ptc-minimal.version'
24
+
25
+ // dsh-tools keys its tool scheduler with this symbol description. On stock
26
+ // hosts it is a module-local Symbol(), so any second dsh-tools instance
27
+ // (duplicate profile copy, or the package's own dual build outputs on
28
+ // 0.1.6-alpha) breaks the agent-loop lookup: every tool call then fails with
29
+ // "Cannot read properties of undefined (reading 'prepare')".
30
+ const SCHEDULER_SYMBOL_DESC = '@deepseek-ai/dsh-tools.scheduler'
31
+
32
+ const packageDir = fileURLToPath(new URL('..', import.meta.url))
33
+ const presetSourceDir = join(packageDir, 'presets', PRESET_ID)
34
+
35
+ /** 与 @deepseek-ai/dsh-home-paths 相同的解析规则:DSH_HOME > ~/.dsh。 */
36
+ function dshHomePath(...segments) {
37
+ const env = process.env.DSH_HOME
38
+ const fromEnv = typeof env === 'string' && env.trim().length > 0 ? env : null
39
+ let base = fromEnv ?? join(homedir(), '.dsh')
40
+ if (base === '~') base = homedir()
41
+ if (base.startsWith('~/') || base.startsWith('~\\')) base = join(homedir(), base.slice(2))
42
+ return resolve(base, ...segments)
43
+ }
44
+
45
+ function materialize(logger, modernRuntime) {
46
+ const dir = dshHomePath('.agent-presets', PRESET_ID)
47
+ mkdirSync(dir, { recursive: true })
48
+ const revision = modernRuntime ? `${VERSION}:ptc-runtime` : VERSION
49
+
50
+ let marker = null
51
+ try {
52
+ marker = readFileSync(join(dir, MARKER), 'utf8').trim()
53
+ } catch {
54
+ // 无标记:可能是首次安装,也可能是用户自建目录
55
+ }
56
+
57
+ if (marker === revision) return
58
+ if (marker === null && existsSync(join(dir, 'agent.cordis.yml'))) {
59
+ logger?.warn(`dsh-minimal-ptc: ${dir} exists without our marker; leaving it alone`)
60
+ return
61
+ }
62
+
63
+ for (const file of ['agent.cordis.yml', 'preset.yml', 'gitbash-executor.mjs']) {
64
+ let content = readFileSync(join(presetSourceDir, file), 'utf8')
65
+ if (modernRuntime && file === 'agent.cordis.yml') {
66
+ content = content.replaceAll('workflow-worker-thread', 'workflow-ptc')
67
+ .replaceAll('`codeRuntime`', '`ptcRuntime`')
68
+ }
69
+ writeFileSync(join(dir, file), content)
70
+ }
71
+ writeFileSync(join(dir, MARKER), revision + '\n')
72
+ logger?.info(`dsh-minimal-ptc: materialized agent preset "${PRESET_ID}" into ${dir}`)
73
+ }
74
+
75
+ export function apply(ctx) {
76
+ ctx.effect(() => ctx.appReady.onReady(() => {
77
+ try {
78
+ // 0.1.7 discovers the declarative row shipped by this bundle. Never
79
+ // rewrite a user's retired directory while running on that host.
80
+ if (typeof ctx.get('agentPresets')?.register !== 'function') {
81
+ materialize(ctx.logger, ctx.get('ptcRuntime') !== undefined)
82
+ }
83
+ } catch (error) {
84
+ ctx.logger?.warn(`dsh-minimal-ptc: preset materialization failed: ${String(error)}`)
85
+ }
86
+ try {
87
+ healthCheck(ctx)
88
+ } catch (error) {
89
+ ctx.logger?.warn(`dsh-minimal-ptc: health check failed: ${String(error)}`)
90
+ }
91
+ }))
92
+ }
93
+
94
+ /**
95
+ * Warn about the two known causes of "Cannot read properties of undefined
96
+ * (reading 'prepare')" before the first session hits them. Warnings only —
97
+ * nothing here blocks startup.
98
+ */
99
+ function healthCheck(ctx) {
100
+ const logger = ctx.logger
101
+
102
+ // Cause 1 (most common in the wild): a plugin or stale install left a
103
+ // physical copy of @deepseek-ai/* inside some profile's node_modules. The
104
+ // core must come from the CLI's own dependency tree only.
105
+ for (const hit of findProfileCoreCopies()) {
106
+ logger?.warn(
107
+ `dsh-minimal-ptc: duplicate core package in profile: ${hit}\n`
108
+ + ' A second @deepseek-ai copy breaks the tool scheduler key (module-local Symbol) '
109
+ + 'and every tool call fails with "reading \'prepare\'".\n'
110
+ + ' Fix: update the plugin that brings in this runtime package, reinstall profile dependencies, '
111
+ + 'then restart. Shared helpers such as schemastery and cosmokit are supported dependencies.',
112
+ )
113
+ }
114
+
115
+ // Cause 2 (seen on stock 0.1.6-alpha): the host itself can load two dsh-tools
116
+ // instances (bundled lib/index.js vs per-module lib/types/*.js). It is safe
117
+ // only when the scheduler key survives multiple instances, i.e. the host was
118
+ // built with Symbol.for. Probe exactly that.
119
+ const status = schedulerKeyStatus(ctx.tools)
120
+ if (status === 'module-local') {
121
+ logger?.warn(
122
+ 'dsh-minimal-ptc: this host keys the tool scheduler with a module-local Symbol '
123
+ + '(unpatched dsh-tools). PTC sessions break with "reading \'prepare\'" '
124
+ + 'whenever a second dsh-tools instance loads in this process.\n'
125
+ + ' Fix: rebuild dsh-tools with `Symbol.for(\'@deepseek-ai/dsh-tools.scheduler\')` '
126
+ + 'in packages/core/tools/src/index.ts, or keep a single dsh-tools copy.',
127
+ )
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Physical @deepseek-ai copies under any profile's node_modules.
133
+ * @returns {string[]} paths like "<profile>/node_modules/@deepseek-ai/<pkg>"
134
+ */
135
+ export function findProfileCoreCopies(home = dshHomePath('profiles')) {
136
+ const hits = []
137
+ let profiles = []
138
+ try {
139
+ profiles = readdirSync(home, { withFileTypes: true })
140
+ } catch {
141
+ return hits
142
+ }
143
+ for (const profile of profiles) {
144
+ if (!profile.isDirectory()) continue
145
+ const scopeDir = join(home, profile.name, 'node_modules', '@deepseek-ai')
146
+ let entries = []
147
+ try {
148
+ entries = readdirSync(scopeDir, { withFileTypes: true })
149
+ } catch {
150
+ continue
151
+ }
152
+ for (const entry of entries) {
153
+ // Schema helpers are ordinary published dependencies, not another host.
154
+ if (entry.isDirectory() && (entry.name === 'dsh-tools' || entry.name === 'cordis')) hits.push(join(scopeDir, entry.name))
155
+ }
156
+ }
157
+ return hits
158
+ }
159
+
160
+ /**
161
+ * How the host's tool registry exposes the scheduler key:
162
+ * - 'global' — Symbol.for key works; safe across duplicate instances.
163
+ * - 'module-local' — registry carries a same-description local Symbol; the
164
+ * agent loop breaks if a second dsh-tools instance loads.
165
+ * - 'absent' — no tools registry / no scheduler mounted (nothing to say).
166
+ */
167
+ export function schedulerKeyStatus(tools) {
168
+ if (tools == null || (typeof tools !== 'object' && typeof tools !== 'function')) return 'absent'
169
+ if (tools[Symbol.for(SCHEDULER_SYMBOL_DESC)] !== undefined) return 'global'
170
+ const local = Object.getOwnPropertySymbols(tools).some(s => s.description === SCHEDULER_SYMBOL_DESC)
171
+ return local ? 'module-local' : 'absent'
172
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-minimal-ptc",
3
- "version": "0.4.7",
3
+ "version": "0.5.1",
4
4
  "description": "DeepSeek Harness 极简 PTC 预设:简洁提示词、run_code 工具编排、完整插件工具,以及 Windows Git Bash 和持久 PowerShell。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -9,7 +9,8 @@
9
9
  "default": "./lib/index.js"
10
10
  },
11
11
  "./cordis.patch.yml": "./cordis.patch.yml",
12
- "./package.json": "./package.json"
12
+ "./package.json": "./package.json",
13
+ "./gitbash-executor": "./presets/ptc-minimal/gitbash-executor.mjs"
13
14
  },
14
15
  "files": [
15
16
  "lib",
@@ -17,11 +18,15 @@
17
18
  "cordis.patch.yml",
18
19
  "README.md",
19
20
  "README.en.md",
20
- "LICENSE"
21
+ "LICENSE",
22
+ "ptc-minimal.patch.yml"
21
23
  ],
22
24
  "dsh": {
23
25
  "bundle": {
24
- "patch": "./cordis.patch.yml"
26
+ "patch": [
27
+ "./cordis.patch.yml",
28
+ "./ptc-minimal.patch.yml"
29
+ ]
25
30
  }
26
31
  },
27
32
  "keywords": [
@@ -0,0 +1,307 @@
1
+ # Harness 0.1.7 declarative preset; generated from the bundled agent composition.
2
+ - insert:
3
+ - id: preset-ptc-minimal
4
+ name: "@deepseek-ai/dsh-agent-preset"
5
+ config:
6
+ id: ptc-minimal
7
+ name: 极简 PTC 模式
8
+ description: 简洁提示词、完整插件工具与 PTC 编排;Windows 支持 Git Bash 和持久 PowerShell。
9
+ order: 4
10
+ plugins:
11
+ # The `ptc-minimal` agent preset: the `ptc` (PTC 模式) capabilities with the
12
+ # `minimal` (极简模式) prompt.
13
+ #
14
+ # Everything in `ptc` is here unchanged — full standard capabilities plus the
15
+ # PTC tool presentation (`tool-presentation` with `mode: ptc`), where the
16
+ # model composes a TypeScript program against a generated SDK and `run_code`
17
+ # executes it. What differs is the persona row, taken verbatim from `minimal`:
18
+ # a fixed one-line persona marked `complete: true` with
19
+ # `includeRuntimeContext: false`, so global identity, Web orientation, tool
20
+ # guidance, and later assembly listeners cannot add prompt text, and runtime
21
+ # context snapshots are suppressed. The `agent-instructions` row from `ptc` is
22
+ # dropped for the same reason — its workspace instruction baselines would add
23
+ # user-role text the minimal prompt policy excludes.
24
+ #
25
+ # This file is an AGENT-PLANE composition. It is mounted under one agent's
26
+ # scope context, so every tool it registers belongs to that session alone.
27
+ # A service row here MUST sit inside a group carrying an `isolate` realm.
28
+
29
+ # ── identity ────────────────────────────────────────────────────────────────
30
+
31
+ # The persona is the complete system prompt (minimal-mode prompt policy).
32
+ # dsh 0.1.3 renamed the persona config field `text` to `prefix` (required).
33
+ - id: persona
34
+ name: '@deepseek-ai/dsh-persona'
35
+ config:
36
+ prefix: You are a helpful software engineer assistant.
37
+ complete: true
38
+ includeRuntimeContext: false
39
+
40
+ # ── shell ───────────────────────────────────────────────────────────────────
41
+
42
+ # `shell-env` stays in the HOST composition: `apps/cli/src/web.ts` injects it to
43
+ # publish `DSH_WEB_URL`/`DSH_WEB_MODE`. Both shell tools consume the host
44
+ # registry from here; their executors are host-plane too.
45
+ - id: tool-bash
46
+ name: '@deepseek-ai/dsh-tool-bash'
47
+ disabled: !!js process.platform === 'win32'
48
+
49
+ - id: tool-pwsh
50
+ name: '@deepseek-ai/dsh-tool-pwsh'
51
+ disabled: true
52
+
53
+ # Windows persistent PowerShell PTY stack (rc.1 minimal parity). Replaces the
54
+ # one-shot pwsh row on win32; the gitbash group below keeps a stateless bash
55
+ # tool beside it. The model-facing tool name remains `pwsh`.
56
+ - id: persistent-shell
57
+ name: cordis:group
58
+ group: true
59
+ disabled: !!js process.platform !== 'win32'
60
+ isolate:
61
+ terminals: true
62
+ config:
63
+ - id: pty
64
+ name: '@deepseek-ai/dsh-terminal'
65
+
66
+ - id: terminal-pwsh
67
+ name: '@deepseek-ai/dsh-terminal-bash'
68
+ disabled: !!js process.platform !== 'win32'
69
+ config:
70
+ shellDialect: pwsh
71
+ timeoutMs: 300000
72
+
73
+ - id: persistent-pwsh
74
+ name: '@deepseek-ai/dsh-tool-pwsh-persistent'
75
+ disabled: !!js process.platform !== 'win32'
76
+ config:
77
+ timeoutMs: 300000
78
+ description: |-
79
+ Run commands in a PowerShell shell
80
+ * When invoking this tool, the contents of the "command" parameter does NOT need to be XML-escaped.
81
+ * Network access depends on the host environment.
82
+ * State is persistent across command calls and discussions with the user.
83
+ * Use native Windows paths (C:\...) and $env:NAME variables; this is PowerShell, not bash.
84
+ * Please avoid commands that may produce a very large amount of output.
85
+ * Please run long lived commands in the background, e.g. 'Start-Job' or start a server with Start-Process.
86
+
87
+ # Windows Git Bash shell stack. The preset-local executor runs every `bash`
88
+ # call through Git for Windows bash, keeping the model-facing tool name and
89
+ # stateless semantics identical to the POSIX `tool-bash` row above. Only
90
+ # mounted on win32; the POSIX host keeps the official bash runner.
91
+ - id: gitbash-shell
92
+ name: cordis:group
93
+ group: true
94
+ disabled: !!js process.platform !== 'win32'
95
+ isolate:
96
+ shell: true
97
+ config:
98
+ - id: gitbash-executor
99
+ name: dsh-minimal-ptc/gitbash-executor
100
+ config:
101
+ # 留空:executor 自动探测 GIT_BASH → 常见安装目录 → PATH → 'bash'
102
+ # 如需固定路径可显式写 shellPath: 'C:\\Program Files\\Git\\bin\\bash.exe'
103
+ timeoutMs: 120000
104
+ maxTimeoutMs: 600000
105
+ maxOutputBytes: 64000
106
+ maxSpillBytes: 67108864
107
+ graceMs: 3000
108
+
109
+ - id: tool-bash-win
110
+ name: '@deepseek-ai/dsh-tool-bash'
111
+ config:
112
+ enableRunInBackground: false
113
+
114
+ # ── filesystem ──────────────────────────────────────────────────────────────
115
+
116
+ # Both register into the host `tools` registry and provide nothing, so
117
+ # they need no realm. The `fs` service and its policy stay in the host.
118
+ - id: tool-fs
119
+ name: '@deepseek-ai/dsh-tool-fs'
120
+
121
+ - id: tool-fs-search
122
+ name: '@deepseek-ai/dsh-tool-fs-search'
123
+ config:
124
+ sampleOverCapGlobResults: false
125
+
126
+ # ── background jobs ────────────────────────────────────────────────────────
127
+
128
+ # Only the model-facing controls. The task REGISTRY stays on the host plane.
129
+ - id: tool-jobs
130
+ name: '@deepseek-ai/dsh-tool-jobs'
131
+
132
+ # ── skills ──────────────────────────────────────────────────────────────────
133
+
134
+ # The skill REGISTRY lives in the host composition and is layered per scope:
135
+ # these rows register into THIS preset's layer of it, so they need no realm.
136
+ - id: skill-filesystem
137
+ name: '@deepseek-ai/dsh-skill-filesystem'
138
+
139
+ - id: tool-skill
140
+ name: '@deepseek-ai/dsh-tool-skill'
141
+
142
+ # ── goals ───────────────────────────────────────────────────────────────────
143
+
144
+ # Only the model-facing tool plus the human command. The goal SERVICE, its
145
+ # session driver stay on the host plane.
146
+ - id: command-goal
147
+ name: '@deepseek-ai/dsh-command-goal'
148
+
149
+ - id: tool-goal
150
+ name: '@deepseek-ai/dsh-tool-goal'
151
+
152
+ # ── plan mode ───────────────────────────────────────────────────────────────
153
+
154
+ # Plan state is per-agent by nature, so an entry-local realm is not a
155
+ # workaround here — it is the correct lifetime.
156
+ - id: planning
157
+ name: cordis:group
158
+ group: true
159
+ isolate:
160
+ planMode: true
161
+ config:
162
+ - id: plan-mode
163
+ name: '@deepseek-ai/dsh-plan-mode'
164
+ config:
165
+ section: |
166
+ You are in plan mode. Stay in plan mode until exit_plan_mode succeeds or the user switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
167
+
168
+ Explore first. Use non-mutating reads, searches, static analysis, and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan. Prefer existing functions and patterns over new machinery.
169
+
170
+ The tool catalog stays the same across modes for request-cache stability. These plan-mode rules override any later tool description or guidance that suggests using mutation tools; those tools remain listed to keep the tool catalog unchanged. Do not use todo_write to track this planning phase: it tracks implementation after an approved plan, while the plan itself belongs in exit_plan_mode.
171
+
172
+ Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices or material ambiguity that inspection cannot answer. Do not ask the user where code lives or how current behavior works when you can find out.
173
+
174
+ Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
175
+
176
+ When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
177
+
178
+ # ── compaction ──────────────────────────────────────────────────────────────
179
+
180
+ # `compaction-basic` reads `toolResultPrune` through `ctx.get`, so the pruner
181
+ # must share this realm rather than sit outside it. `tokenMeter` stays HOST-side.
182
+ - id: compaction
183
+ name: cordis:group
184
+ group: true
185
+ isolate:
186
+ compaction: true
187
+ toolResultPruner: true
188
+ config:
189
+ - id: compaction-basic
190
+ name: '@deepseek-ai/dsh-compaction-basic'
191
+
192
+ - id: command-compact
193
+ name: '@deepseek-ai/dsh-command-compact'
194
+
195
+ - id: tool-result-pruner
196
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
197
+ config:
198
+ thresholdChars: 8192
199
+ headChars: 4096
200
+ tailChars: 1024
201
+
202
+ # ── delegation and workflows ────────────────────────────────────────────────
203
+
204
+ # The `subagents` registry and its spawn/fork backends live in the HOST
205
+ # composition. This preset contributes the delegation TOOLS. `workflows` shares
206
+ # one entry-local realm here, and a consumer left outside would resolve a host
207
+ # registry this preset does not populate.
208
+ - id: delegation
209
+ name: cordis:group
210
+ group: true
211
+ isolate:
212
+ workflowEngine: true
213
+ config:
214
+ - id: tool-subagent-control
215
+ name: '@deepseek-ai/dsh-tool-subagent-control'
216
+
217
+ - id: tool-subagent-list-agents
218
+ name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
219
+
220
+ - id: tool-subagent
221
+ name: '@deepseek-ai/dsh-tool-subagent'
222
+ config:
223
+ provider: spawn
224
+ toolName: subagent
225
+ modelSelectionSettings: true
226
+ backgroundMode: continuable
227
+
228
+ - id: tool-subagent-fork
229
+ name: '@deepseek-ai/dsh-tool-subagent'
230
+ config:
231
+ provider: fork
232
+ toolName: subagent_fork
233
+ backgroundMode: continuable
234
+
235
+ # Product providers are host-plane singletons. Remove `disabled` from
236
+ # either ordinary tool row to expose that product to agents on this preset.
237
+ - id: tool-subagent-codex
238
+ name: '@deepseek-ai/dsh-tool-subagent'
239
+ disabled: true
240
+ config:
241
+ provider: codex
242
+ toolName: subagent_codex
243
+ backgroundMode: one-shot
244
+ maxDepth: provider-managed
245
+
246
+ - id: tool-subagent-claude-code
247
+ name: '@deepseek-ai/dsh-tool-subagent'
248
+ disabled: true
249
+ config:
250
+ provider: claude-code
251
+ toolName: subagent_claude_code
252
+ backgroundMode: one-shot
253
+ maxDepth: provider-managed
254
+
255
+ - id: workflow-ptc
256
+ name: '@deepseek-ai/dsh-workflow-ptc'
257
+ config:
258
+ provider: spawn
259
+
260
+ - id: tool-workflow
261
+ name: '@deepseek-ai/dsh-tool-workflow'
262
+ # Keep the engine above for `ralph`, but do not publish a second
263
+ # model-authored orchestration surface beside `run_code` in PTC mode.
264
+ disabled: true
265
+
266
+ - id: tool-ralph
267
+ name: '@deepseek-ai/dsh-tool-ralph'
268
+ config:
269
+ subagentProvider: spawn
270
+ maxRounds: 64
271
+
272
+ # ── remaining model-facing rows ─────────────────────────────────────────────
273
+
274
+ - id: tool-ask-user
275
+ name: '@deepseek-ai/dsh-tool-ask-user'
276
+
277
+ - id: tool-todo
278
+ name: '@deepseek-ai/dsh-tool-todo'
279
+ config:
280
+ allowParallelInProgress: true
281
+
282
+ # The `web` service and its search provider stay in the host composition; only
283
+ # the model-facing tool is per-session.
284
+ - id: tool-web
285
+ name: '@deepseek-ai/dsh-tool-web'
286
+ config:
287
+ fetch: true
288
+ searchTimeoutMs: 60000
289
+
290
+ # ── presentation ────────────────────────────────────────────────────────────
291
+
292
+ # PTC for this agent alone. The row waits for the host's `ptcRuntime`
293
+ # rather than assuming it: a deployment that composes no TypeScript runtime
294
+ # fails this preset at mount, naming this id, instead of at the first request.
295
+ - id: tool-presentation
296
+ name: '@deepseek-ai/dsh-agent-tool-presentation'
297
+ config:
298
+ mode: ptc
299
+
300
+ # Official `ptc` parity rows (0.1.6): the deliverables presenter and the
301
+ # plugin-manager tools (off by default, mirroring the official preset).
302
+ - id: present
303
+ name: '@deepseek-ai/dsh-tool-present'
304
+
305
+ - id: tool-plugin-manager
306
+ name: '@deepseek-ai/dsh-plugin-manager/tools'
307
+ disabled: true