relay-dsh-plugin-claude 0.1.3 → 0.1.4
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 +98 -13
- package/README.zh.md +85 -12
- package/docs/spec/claude-local-plugins.md +56 -0
- package/docs/spec/claude-native-session-import.md +114 -0
- package/docs/spec/claude-search-tools.md +40 -0
- package/docs/spec/claude-tool-output-redaction.md +68 -0
- package/lib/client.js +575 -0
- package/lib/client.js.map +1 -1
- package/lib/host-plugin.js +1013 -28
- package/lib/host-plugin.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -6,23 +6,36 @@
|
|
|
6
6
|
[](https://github.com/yangbobo2021/relay-dsh-plugin-claude/stargazers)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
9
|
-
[](https://www.npmjs.com/package/relay-dsh-plugin-claude/v/0.1.
|
|
9
|
+
[](https://www.npmjs.com/package/relay-dsh-plugin-claude/v/0.1.4)
|
|
10
10
|
|
|
11
11
|
English | [中文](README.zh.md)
|
|
12
12
|
|
|
13
13
|
**npm package:** [`relay-dsh-plugin-claude`](https://www.npmjs.com/package/relay-dsh-plugin-claude)
|
|
14
14
|
· [All Relay DSH plugins](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.md)
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
**Run Claude Code inside official DeepSeek Harness without switching interfaces
|
|
17
|
+
or maintaining a DSH fork.**
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
`relay-dsh-plugin-claude` adds **Claude Code as a native conversation backend**
|
|
20
|
+
to the official [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
21
|
+
(DSH) Web UI. You keep DSH's workspace, conversation history, composer,
|
|
22
|
+
approvals, questions, and tool display while each DSH Session continues one
|
|
23
|
+
Claude Agent SDK session. The plugin installs independently; no Relay checkout
|
|
24
|
+
is required.
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
## Try It on Official DSH
|
|
27
|
+
|
|
28
|
+
Complete normal Claude Code authentication with `claude` before the first
|
|
29
|
+
Session. The install requires Node.js 22.13 or newer and `pnpm` on `PATH`. Then
|
|
30
|
+
stop DSH Web, install the tested release candidate, and restart DSH:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add relay-dsh-plugin-claude@next
|
|
34
|
+
npx @deepseek-ai/dsh@0.1.1-rc.2 web
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Open **New Session**, select a workspace, choose **Claude Code** from the mode
|
|
38
|
+
menu, and send a message.
|
|
26
39
|
|
|
27
40
|

|
|
28
41
|
|
|
@@ -30,6 +43,13 @@ The screenshot was captured from official DSH `0.1.1-rc.2` with the Codex and
|
|
|
30
43
|
Claude plugins installed. If you install only this plugin, only **Claude Code**
|
|
31
44
|
is added.
|
|
32
45
|
|
|
46
|
+
[Review all Relay DSH plugins](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.md)
|
|
47
|
+
· [report an install result](https://github.com/yangbobo2021/relay-dsh-plugin-claude/issues)
|
|
48
|
+
|
|
49
|
+
If this removes an interface switch from your DSH workflow,
|
|
50
|
+
[star this plugin](https://github.com/yangbobo2021/relay-dsh-plugin-claude).
|
|
51
|
+
That signal helps other DSH users find a tested Claude Code backend.
|
|
52
|
+
|
|
33
53
|
## Do I Need This Plugin?
|
|
34
54
|
|
|
35
55
|
Install it when you want to:
|
|
@@ -45,7 +65,7 @@ Install it when you want to:
|
|
|
45
65
|
You do not need it to use DSH's standard agents. It also does not add Relay
|
|
46
66
|
Events, file browsing, or a terminal panel. Those are separate optional plugins.
|
|
47
67
|
|
|
48
|
-
##
|
|
68
|
+
## Complete Setup and Compatibility
|
|
49
69
|
|
|
50
70
|
The steps below were validated with:
|
|
51
71
|
|
|
@@ -89,7 +109,7 @@ Use `@latest` to install the current stable release:
|
|
|
89
109
|
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add relay-dsh-plugin-claude@latest
|
|
90
110
|
```
|
|
91
111
|
|
|
92
|
-
At the time of writing, `latest` resolves to stable version `0.1.
|
|
112
|
+
At the time of writing, `latest` resolves to stable version `0.1.4`. The linked
|
|
93
113
|
npm page is the source of truth for the current version.
|
|
94
114
|
|
|
95
115
|
#### npm prerelease (recommended during DSH preview)
|
|
@@ -102,7 +122,7 @@ contains the latest model-selection synchronization fix:
|
|
|
102
122
|
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add relay-dsh-plugin-claude@next
|
|
103
123
|
```
|
|
104
124
|
|
|
105
|
-
At the time of writing, `next` resolves to `0.1.
|
|
125
|
+
At the time of writing, `next` resolves to `0.1.4`.
|
|
106
126
|
|
|
107
127
|
#### GitHub development build
|
|
108
128
|
|
|
@@ -116,7 +136,7 @@ npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add github:yangbobo2021/rel
|
|
|
116
136
|
full Commit SHA instead. For example:
|
|
117
137
|
|
|
118
138
|
```bash
|
|
119
|
-
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add github:yangbobo2021/relay-dsh-plugin-claude#v0.1.
|
|
139
|
+
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add github:yangbobo2021/relay-dsh-plugin-claude#v0.1.4
|
|
120
140
|
```
|
|
121
141
|
|
|
122
142
|
The official DSH CLI initializes the `web` Profile if it does not exist, asks
|
|
@@ -151,6 +171,31 @@ at startup, so restarting after installation, update, or removal is required.
|
|
|
151
171
|
There is no separate activation command. A successful install plus a DSH restart
|
|
152
172
|
activates the bundle and registers the managed **Claude Code** mode automatically.
|
|
153
173
|
|
|
174
|
+
### 5. Import an existing Claude terminal Session
|
|
175
|
+
|
|
176
|
+
1. Open the target Workspace or one of its Sessions in DSH.
|
|
177
|
+
2. Select **Import Claude Sessions** below the Workspace list.
|
|
178
|
+
3. Review the full Session IDs, titles, source paths, activity times, and import
|
|
179
|
+
status. Select one, several, or all Sessions.
|
|
180
|
+
4. Select **Import selected**, then open the imported DSH Session.
|
|
181
|
+
5. Send the next message and confirm that it continues the same native Claude
|
|
182
|
+
Session.
|
|
183
|
+
|
|
184
|
+
The selector uses the Claude Agent SDK's public Session APIs and matches the
|
|
185
|
+
terminal `/resume` scope. It excludes worktrees, SDK/headless Sessions,
|
|
186
|
+
already-bound Sessions, and Sessions outside the exact registered Workspace.
|
|
187
|
+
The imported history is a one-time presentation snapshot of user text, visible
|
|
188
|
+
assistant text and thinking, and completed textual tool activity. Unknown or
|
|
189
|
+
private blocks are skipped; Claude's source transcript is never modified.
|
|
190
|
+
|
|
191
|
+
The SDK inventory does not expose a durable running/idle status. Avoid writing
|
|
192
|
+
the same Session from another Claude client while continuing it in DSH. If
|
|
193
|
+
resume fails, DSH keeps the exact imported binding for retry and never silently
|
|
194
|
+
creates a replacement Session. Import is unavailable with the CLI fallback.
|
|
195
|
+
See
|
|
196
|
+
[`docs/spec/claude-native-session-import.md`](docs/spec/claude-native-session-import.md)
|
|
197
|
+
for the complete contract and delivery cases.
|
|
198
|
+
|
|
154
199
|
## What Works
|
|
155
200
|
|
|
156
201
|
- One persistent Claude Agent SDK session per DSH Session
|
|
@@ -161,7 +206,47 @@ activates the bundle and registers the managed **Claude Code** mode automaticall
|
|
|
161
206
|
final answer
|
|
162
207
|
- DSH approval and user-question flows
|
|
163
208
|
- Interruption and session continuation
|
|
209
|
+
- Selective import and exact-ID continuation of existing Claude terminal Sessions
|
|
164
210
|
- Generic DSH tools exposed through an in-process Claude SDK MCP server
|
|
211
|
+
- Dedicated native Claude `Glob` and `Grep` search tools on every SDK query
|
|
212
|
+
- Pre-persistence redaction of sensitive environment values from tool output
|
|
213
|
+
|
|
214
|
+
### Sensitive environment output
|
|
215
|
+
|
|
216
|
+
Before each new or resumed SDK turn, the plugin resolves Claude's effective
|
|
217
|
+
environment and classifies credential-bearing variable names such as `SECRET`,
|
|
218
|
+
`TOKEN`, `PASSWORD`, and `API_KEY`. Exact occurrences of those values in tool
|
|
219
|
+
results are replaced before the result reaches Claude, DSH activity, or the
|
|
220
|
+
native Claude JSONL transcript. Variables explicitly listed in Claude sandbox
|
|
221
|
+
credential settings are protected as well. Ordinary environment values and
|
|
222
|
+
successful tool outputs without a match are left unchanged.
|
|
223
|
+
|
|
224
|
+
This protection covers successful tool results; it does not rewrite user
|
|
225
|
+
prompts, tool inputs, arbitrary values that are not identifiable from host
|
|
226
|
+
configuration, or SDK execution failures without a replaceable tool output.
|
|
227
|
+
See
|
|
228
|
+
[`docs/spec/claude-tool-output-redaction.md`](docs/spec/claude-tool-output-redaction.md)
|
|
229
|
+
for the complete contract and acceptance cases.
|
|
230
|
+
|
|
231
|
+
### Explicit local Claude plugins
|
|
232
|
+
|
|
233
|
+
Trusted Host configuration can load an uninstalled local Claude plugin into
|
|
234
|
+
business conversations by setting `claudePlugins` on this DSH plugin:
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
config:
|
|
238
|
+
claudePlugins:
|
|
239
|
+
- type: local
|
|
240
|
+
path: /absolute/path/to/plugin
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The order and optional `skipMcpDiscovery` Boolean are forwarded to every new and
|
|
244
|
+
resumed Claude Agent SDK query. Hidden title-generation Sessions use no local
|
|
245
|
+
plugins. A non-empty list is rejected when the CLI fallback is active because
|
|
246
|
+
the CLI backend cannot honor this SDK option. Local plugins execute as the DSH
|
|
247
|
+
user, so configure only reviewed paths. See
|
|
248
|
+
[`docs/spec/claude-local-plugins.md`](docs/spec/claude-local-plugins.md) for the
|
|
249
|
+
full contract and acceptance cases.
|
|
165
250
|
|
|
166
251
|
Tools execute through the owning Agent's DSH tool runtime and remain subject to
|
|
167
252
|
DSH permissions and Claude approval behavior. The tool bridge requires the
|
package/README.zh.md
CHANGED
|
@@ -6,29 +6,48 @@
|
|
|
6
6
|
[](https://github.com/yangbobo2021/relay-dsh-plugin-claude/stargazers)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
9
|
-
[](https://www.npmjs.com/package/relay-dsh-plugin-claude/v/0.1.
|
|
9
|
+
[](https://www.npmjs.com/package/relay-dsh-plugin-claude/v/0.1.4)
|
|
10
10
|
|
|
11
11
|
[English](README.md) | 中文
|
|
12
12
|
|
|
13
13
|
**npm 包名:** [`relay-dsh-plugin-claude`](https://www.npmjs.com/package/relay-dsh-plugin-claude)
|
|
14
14
|
· [全部 Relay DSH 插件](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.zh.md)
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*演示来自官方 DSH 上的真实 npm 安装:Codex 与 Claude 返回真实回复,Files
|
|
19
|
-
预览工作区文件,Terminal 实际执行命令。[观看 H.264
|
|
20
|
-
MP4](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/media/dsh-plugin-suite-demo.mp4?raw=1)。*
|
|
16
|
+
**无需切换界面或维护 DSH Fork,直接在官方 DeepSeek Harness 中运行 Claude
|
|
17
|
+
Code。**
|
|
21
18
|
|
|
22
19
|
`relay-dsh-plugin-claude` 为官方
|
|
23
20
|
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)Web
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
界面增加原生 **Claude Code 对话后端**。你可以继续使用 DSH 的工作区、对话
|
|
22
|
+
历史、输入框、审批、提问和工具展示;每个 DSH Session 会持续绑定一个 Claude
|
|
23
|
+
Agent SDK Session。本插件可独立安装,不需要下载 Relay 仓库。
|
|
24
|
+
|
|
25
|
+
## 在官方 DSH 中立即试用
|
|
26
|
+
|
|
27
|
+
首次创建 Session 前,请先运行 `claude` 完成 Claude Code 的正常认证。安装
|
|
28
|
+
要求 Node.js 22.13 或更高版本,并且 `pnpm` 已加入 `PATH`。然后停止 DSH Web,
|
|
29
|
+
安装经过测试的候选版本并重新启动:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add relay-dsh-plugin-claude@next
|
|
33
|
+
npx @deepseek-ai/dsh@0.1.1-rc.2 web
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
打开 **New Session**,选择工作区,再从模式菜单中选择 **Claude Code** 并发送
|
|
37
|
+
消息。
|
|
26
38
|
|
|
27
39
|

|
|
28
40
|
|
|
29
41
|
上图来自安装了 Codex 和 Claude 插件的官方 DSH `0.1.1-rc.2`。如果只安装
|
|
30
42
|
本插件,菜单中只会新增 **Claude Code**。
|
|
31
43
|
|
|
44
|
+
[查看全部 Relay DSH 插件](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.zh.md)
|
|
45
|
+
· [反馈安装结果](https://github.com/yangbobo2021/relay-dsh-plugin-claude/issues)
|
|
46
|
+
|
|
47
|
+
如果它能让你少切换一个界面,欢迎
|
|
48
|
+
[Star 本插件](https://github.com/yangbobo2021/relay-dsh-plugin-claude)。
|
|
49
|
+
这些真实信号能帮助更多 DSH 用户找到经过验证的 Claude Code 后端。
|
|
50
|
+
|
|
32
51
|
## 什么情况下需要这个插件?
|
|
33
52
|
|
|
34
53
|
以下情况适合安装:
|
|
@@ -44,7 +63,7 @@ MP4](https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/medi
|
|
|
44
63
|
使用 DSH 标准 Agent 不需要安装本插件。本插件也不提供 Relay Events、文件
|
|
45
64
|
浏览和终端面板,这些能力由其他可选插件提供。
|
|
46
65
|
|
|
47
|
-
##
|
|
66
|
+
## 完整安装与兼容性说明
|
|
48
67
|
|
|
49
68
|
以下步骤已经在这些版本上实际验证:
|
|
50
69
|
|
|
@@ -85,7 +104,7 @@ claude
|
|
|
85
104
|
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add relay-dsh-plugin-claude@latest
|
|
86
105
|
```
|
|
87
106
|
|
|
88
|
-
本文更新时,`latest` 指向稳定版 `0.1.
|
|
107
|
+
本文更新时,`latest` 指向稳定版 `0.1.4`。最新版本请以链接中的 npm 页面
|
|
89
108
|
为准。
|
|
90
109
|
|
|
91
110
|
#### npm 预发布版(DSH 预览阶段推荐)
|
|
@@ -97,7 +116,7 @@ npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add relay-dsh-plugin-claude
|
|
|
97
116
|
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add relay-dsh-plugin-claude@next
|
|
98
117
|
```
|
|
99
118
|
|
|
100
|
-
本文更新时,`next` 指向 `0.1.
|
|
119
|
+
本文更新时,`next` 指向 `0.1.4`。
|
|
101
120
|
|
|
102
121
|
#### GitHub 开发版
|
|
103
122
|
|
|
@@ -111,7 +130,7 @@ npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add github:yangbobo2021/rel
|
|
|
111
130
|
SHA。例如:
|
|
112
131
|
|
|
113
132
|
```bash
|
|
114
|
-
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add github:yangbobo2021/relay-dsh-plugin-claude#v0.1.
|
|
133
|
+
npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add github:yangbobo2021/relay-dsh-plugin-claude#v0.1.4
|
|
115
134
|
```
|
|
116
135
|
|
|
117
136
|
官方 DSH CLI 会在需要时初始化 `web` Profile,通过 `pnpm` 安装所选软件包和
|
|
@@ -143,6 +162,27 @@ npx @deepseek-ai/dsh@0.1.1-rc.2 web
|
|
|
143
162
|
插件不需要单独的激活命令。安装成功并重启 DSH 后,Bundle 会自动激活,
|
|
144
163
|
并注册由插件管理的 **Claude Code** 模式。
|
|
145
164
|
|
|
165
|
+
### 5. 导入已有的 Claude 终端会话
|
|
166
|
+
|
|
167
|
+
1. 在 DSH 中打开目标工作区或其中一个 Session。
|
|
168
|
+
2. 点击工作区列表下方的 **导入 Claude 会话**。
|
|
169
|
+
3. 检查完整 Session ID、标题、源路径、活动时间和导入状态,然后选择一个、
|
|
170
|
+
多个或全部会话。
|
|
171
|
+
4. 点击 **导入所选会话**,再打开导入后的 DSH Session。
|
|
172
|
+
5. 发送下一条消息,确认它继续的是同一个原生 Claude Session。
|
|
173
|
+
|
|
174
|
+
选择器只使用 Claude Agent SDK 的公开 Session API,其范围与终端 `/resume`
|
|
175
|
+
一致。它会排除 worktree、SDK/headless、已经绑定以及不属于当前精确注册工作区
|
|
176
|
+
的 Session。导入历史是一次性的展示快照,包含用户文本、可见的助手文本与
|
|
177
|
+
thinking,以及已有结果的文本工具活动。未知或私有块会被跳过,Claude 源转录
|
|
178
|
+
不会被修改。
|
|
179
|
+
|
|
180
|
+
SDK 列表不提供持久的 running/idle 状态。通过 DSH 继续会话时,应避免另一个
|
|
181
|
+
Claude 客户端同时写入同一个 Session。如果恢复失败,DSH 会保留原始绑定供
|
|
182
|
+
重试,绝不会静默创建替代 Session。CLI fallback 不支持导入。完整契约和交付
|
|
183
|
+
用例见
|
|
184
|
+
[`docs/spec/claude-native-session-import.md`](docs/spec/claude-native-session-import.md)。
|
|
185
|
+
|
|
146
186
|
## 支持的能力
|
|
147
187
|
|
|
148
188
|
- 每个 DSH Session 持续绑定一个 Claude Agent SDK Session
|
|
@@ -152,7 +192,40 @@ npx @deepseek-ai/dsh@0.1.1-rc.2 web
|
|
|
152
192
|
- 在对话中持久展示 Claude 最终回答所引用的工作区图片
|
|
153
193
|
- DSH 原生审批和用户提问流程
|
|
154
194
|
- 中断和会话延续
|
|
195
|
+
- 选择性导入已有 Claude 终端会话,并通过原始 ID 继续
|
|
155
196
|
- 通过进程内 Claude SDK MCP Server 提供通用 DSH 工具
|
|
197
|
+
- 在每次 SDK 查询中启用 Claude 原生 `Glob` 与 `Grep` 专用搜索工具
|
|
198
|
+
- 在工具结果持久化前脱敏其中的敏感环境变量值
|
|
199
|
+
|
|
200
|
+
### 敏感环境变量输出脱敏
|
|
201
|
+
|
|
202
|
+
每次新建或恢复 SDK turn 前,插件都会解析 Claude 的有效环境,并识别变量名中
|
|
203
|
+
含有 `SECRET`、`TOKEN`、`PASSWORD`、`API_KEY` 等凭据特征的值。工具结果中
|
|
204
|
+
与这些值完全相同的内容,会在进入 Claude、DSH activity 或 Claude 原生 JSONL
|
|
205
|
+
转录之前替换。Claude sandbox 凭据设置中显式列出的环境变量也会受到保护。
|
|
206
|
+
普通环境值及没有命中的成功工具输出保持不变。
|
|
207
|
+
|
|
208
|
+
该保护仅覆盖成功工具结果,不会改写用户消息、工具输入、无法从 Host 配置
|
|
209
|
+
识别的任意内容,或 SDK 未提供可替换输出的执行失败。完整契约与验收用例见
|
|
210
|
+
[`docs/spec/claude-tool-output-redaction.md`](docs/spec/claude-tool-output-redaction.md)。
|
|
211
|
+
|
|
212
|
+
### 显式加载本地 Claude 插件
|
|
213
|
+
|
|
214
|
+
可信的 Host 配置可以通过本 DSH 插件的 `claudePlugins` 字段,将未安装的
|
|
215
|
+
本地 Claude 插件加载到业务对话中:
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
config:
|
|
219
|
+
claudePlugins:
|
|
220
|
+
- type: local
|
|
221
|
+
path: /absolute/path/to/plugin
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
插件顺序和可选的 Boolean 字段 `skipMcpDiscovery` 会传递给每次新建及恢复的
|
|
225
|
+
Claude Agent SDK 查询。标题生成等隐藏辅助 Session 不加载这些插件。CLI
|
|
226
|
+
fallback 无法实现该 SDK 能力,因此非空列表会被明确拒绝。因为本地插件以
|
|
227
|
+
DSH 用户身份运行,只应配置经过审查的路径。完整契约和验收用例见
|
|
228
|
+
[`docs/spec/claude-local-plugins.md`](docs/spec/claude-local-plugins.md)。
|
|
156
229
|
|
|
157
230
|
工具通过当前 Agent 的 DSH 工具运行时执行,并继续受到 DSH 权限和 Claude
|
|
158
231
|
审批机制约束。工具桥接依赖默认 SDK 后端。如果开发者明确选择 CLI fallback,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Claude Local Plugin Loading
|
|
2
|
+
|
|
3
|
+
## Contract
|
|
4
|
+
|
|
5
|
+
The DSH host configuration may provide `claudePlugins`, an ordered array of
|
|
6
|
+
Claude Agent SDK local-plugin descriptors:
|
|
7
|
+
|
|
8
|
+
```yaml
|
|
9
|
+
config:
|
|
10
|
+
claudePlugins:
|
|
11
|
+
- type: local
|
|
12
|
+
path: /absolute/path/to/plugin
|
|
13
|
+
skipMcpDiscovery: false
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Each descriptor must contain `type: local` and a non-empty `path`.
|
|
17
|
+
`skipMcpDiscovery`, when present, must be Boolean. Unknown fields are rejected.
|
|
18
|
+
Relative paths remain relative and are interpreted by the Claude Agent SDK.
|
|
19
|
+
Relay does not check path existence before the SDK starts, avoiding a separate
|
|
20
|
+
check/use result from the SDK's authoritative load.
|
|
21
|
+
|
|
22
|
+
The configuration is trusted startup configuration: a local Claude plugin can
|
|
23
|
+
load instructions, hooks, agents, commands, Skills, and MCP definitions with the
|
|
24
|
+
same operating-system access as the Claude process. It is not accepted from a
|
|
25
|
+
conversation message or model output.
|
|
26
|
+
|
|
27
|
+
## Session behavior
|
|
28
|
+
|
|
29
|
+
- A configured list is cloned into every new business Claude SDK Session.
|
|
30
|
+
- A linked DSH Session resumed after a Host restart receives the current Host
|
|
31
|
+
list, including when its older link record predates this option.
|
|
32
|
+
- Every query for that Claude Session carries the same ordered list, including
|
|
33
|
+
resumed queries.
|
|
34
|
+
- Message-level plugin replacement is rejected before `query()`; conversation
|
|
35
|
+
input and model output cannot introduce a local plugin path.
|
|
36
|
+
- An explicit empty list disables configured plugins for that Session.
|
|
37
|
+
- Hidden auxiliary Sessions, including title generation, always use an explicit
|
|
38
|
+
empty list. They must not run user plugin hooks or discover user plugin Skills.
|
|
39
|
+
- With no configured list, Relay omits the SDK `plugins` option and preserves
|
|
40
|
+
existing behavior.
|
|
41
|
+
- The CLI backend cannot load SDK local-plugin paths. It rejects a non-empty list
|
|
42
|
+
with `CLAUDE_LOCAL_PLUGINS_REQUIRE_SDK` instead of silently dropping it.
|
|
43
|
+
|
|
44
|
+
## Delivery acceptance
|
|
45
|
+
|
|
46
|
+
| ID | Scenario | Required result |
|
|
47
|
+
| --- | --- | --- |
|
|
48
|
+
| LP1 | New Session | Runtime creation and first SDK query receive the exact ordered descriptors. |
|
|
49
|
+
| LP2 | Continued Session | A later query uses `resume` and receives the same descriptors. |
|
|
50
|
+
| LP3 | Host restart | Runtime resume receives the current configured descriptors without relying on the persisted link record. |
|
|
51
|
+
| LP4 | No configuration | Runtime and SDK options do not gain a `plugins` property. |
|
|
52
|
+
| LP5 | Auxiliary Session | Runtime creation receives `plugins: []`. |
|
|
53
|
+
| LP6 | Invalid configuration | Relay fails before creating a Session or invoking `query()`. |
|
|
54
|
+
| LP7 | CLI backend | A non-empty descriptor list fails explicitly and spawns no process. |
|
|
55
|
+
| LP8 | Real SDK load | With no CLI installation or setting source, SDK init reports the target plugin and namespaced Skill exactly once. |
|
|
56
|
+
| LP9 | Message injection | A message-level `plugins` field fails before SDK `query()` and does not alter the Session list. |
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Native Claude Session Import
|
|
2
|
+
|
|
3
|
+
This specification defines how `relay-dsh-plugin-claude` discovers an existing
|
|
4
|
+
Claude terminal Session, creates its DSH presentation, and continues the exact
|
|
5
|
+
same native Session. It is the delivery contract for migration case
|
|
6
|
+
`CLD-SES-004`.
|
|
7
|
+
|
|
8
|
+
## Supported backend and source boundary
|
|
9
|
+
|
|
10
|
+
Import is available only when the active Claude Agent SDK exposes the public
|
|
11
|
+
`listSessions`, `getSessionInfo`, and `getSessionMessages` functions. The Host
|
|
12
|
+
must call those APIs and must not parse Claude's private JSONL storage. The CLI
|
|
13
|
+
fallback reports `CLAUDE_SESSION_IMPORT_UNAVAILABLE`; it must not return an empty
|
|
14
|
+
or fabricated inventory.
|
|
15
|
+
|
|
16
|
+
The scan calls `listSessions` with the exact registered DSH Workspace path,
|
|
17
|
+
`includeWorktrees: false`, and `includeProgrammatic: false`. This matches the
|
|
18
|
+
Claude terminal `/resume` inventory: SDK/headless, daemon, worktree, sidechain,
|
|
19
|
+
and other-Workspace Sessions are not import candidates. Every returned `cwd` is
|
|
20
|
+
canonicalized and checked again by the plugin because SDK filtering alone is not
|
|
21
|
+
the authorization boundary.
|
|
22
|
+
|
|
23
|
+
The public SDK inventory is a point-in-time snapshot. It does not expose a
|
|
24
|
+
durable running/idle field, so DSH must not label a candidate as completed or
|
|
25
|
+
promise that another Claude client is no longer writing it.
|
|
26
|
+
|
|
27
|
+
## Inventory and selection
|
|
28
|
+
|
|
29
|
+
Each candidate exposes the full native Session ID, deterministic title, source
|
|
30
|
+
path, source `lastModified`, and either `ready` or `recoverable` status. The
|
|
31
|
+
ordering is descending source activity time with Session ID as a deterministic
|
|
32
|
+
tie-breaker. Already-bound Sessions remain in aggregate counts but are not
|
|
33
|
+
selectable or disclosed as candidates. Sessions outside the exact Workspace are
|
|
34
|
+
neither counted nor disclosed.
|
|
35
|
+
|
|
36
|
+
The UI defaults to every eligible candidate and supports selecting one, several,
|
|
37
|
+
all, or none. An empty selection cannot be submitted. The request carries the
|
|
38
|
+
exact selected `sessionIds`. Before creating or mutating a DSH Session, the Host
|
|
39
|
+
rescans and validates the entire selection. Empty, malformed, duplicate,
|
|
40
|
+
unknown, cross-Workspace, stale, or already-bound IDs reject the selection
|
|
41
|
+
without partial mutation. Omitting `sessionIds` retains the Host's import-all
|
|
42
|
+
API behavior; an explicit empty array is invalid.
|
|
43
|
+
|
|
44
|
+
After selection validation, an individual persistence or DSH composition
|
|
45
|
+
failure may produce a partial batch result. Its durable import state remains
|
|
46
|
+
recoverable and retrying the same source must continue that transaction instead
|
|
47
|
+
of creating a second DSH Session.
|
|
48
|
+
|
|
49
|
+
## History projection
|
|
50
|
+
|
|
51
|
+
The Host reads the selected source again with `getSessionInfo` and
|
|
52
|
+
`getSessionMessages` immediately before reserving its binding. The source ID and
|
|
53
|
+
canonical `cwd` must still match. DSH receives a deterministic presentation seed
|
|
54
|
+
containing:
|
|
55
|
+
|
|
56
|
+
- top-level user text, whether the public SDK returns it as a string or text blocks;
|
|
57
|
+
- visible assistant text and SDK `thinking` blocks as DSH reasoning;
|
|
58
|
+
- a tool call only when its matching tool result exists;
|
|
59
|
+
- textual tool-result content and its error flag.
|
|
60
|
+
|
|
61
|
+
Malformed messages, pre-turn assistant content, system/private blocks, unmatched
|
|
62
|
+
tool calls or results, non-text tool-result blocks, and unknown future block
|
|
63
|
+
types are skipped and counted. They must never be converted into explanatory
|
|
64
|
+
model text. The source transcript is read-only and is never changed by import.
|
|
65
|
+
|
|
66
|
+
The initial DSH title comes from `customTitle`, `summary`, or `firstPrompt`, and
|
|
67
|
+
the DSH list recency comes from the source timestamps. History projection and
|
|
68
|
+
title persistence must complete before Workspace attachment is committed.
|
|
69
|
+
|
|
70
|
+
Import creates a one-time DSH presentation snapshot. It does not poll the source
|
|
71
|
+
or merge turns written later by a second Claude client. Turns sent through DSH
|
|
72
|
+
after import are persisted normally by DSH and the native Claude Session.
|
|
73
|
+
|
|
74
|
+
## Binding and recovery
|
|
75
|
+
|
|
76
|
+
One DSH Session binds at most one native Claude Session, and one native Claude
|
|
77
|
+
Session binds at most one DSH Session. Imported DSH IDs are deterministic from
|
|
78
|
+
the complete source Session ID. The binding and the monotonic transaction states
|
|
79
|
+
`reserved`, `session-created`, `hydrated`, `attached`, and `committed` are
|
|
80
|
+
persisted before the next state is attempted.
|
|
81
|
+
|
|
82
|
+
Restart, duplicate request, concurrent request, and retry must converge on the
|
|
83
|
+
same DSH Session and native Session. Opening or sending the next DSH turn resumes
|
|
84
|
+
the exact imported native Session ID. If resume fails because the source is busy,
|
|
85
|
+
missing, or temporarily unavailable, the plugin reports
|
|
86
|
+
`CLAUDE_IMPORTED_SESSION_RESUME_FAILED`, keeps the binding, and creates no
|
|
87
|
+
replacement Session.
|
|
88
|
+
|
|
89
|
+
## Web route
|
|
90
|
+
|
|
91
|
+
The Host exposes one exact POST route at `/api/relay/claude/import`. It accepts
|
|
92
|
+
JSON only, bounds request size, resolves the requested path through DSH's
|
|
93
|
+
registered Workspace service, and returns no-store responses. Loopback requests
|
|
94
|
+
are accepted. A non-loopback caller requires a constant-time checked Bearer token
|
|
95
|
+
configured by `claudeImportToken` or `RELAY_CLAUDE_IMPORT_TOKEN`.
|
|
96
|
+
|
|
97
|
+
## Delivery acceptance
|
|
98
|
+
|
|
99
|
+
Delivery requires all of the following evidence:
|
|
100
|
+
|
|
101
|
+
1. The historical plugin revision reproduces the absence of native Session
|
|
102
|
+
discovery/import for the same source fixture.
|
|
103
|
+
2. Focused tests cover SDK capability failure, exact inventory options,
|
|
104
|
+
Workspace isolation, deterministic ordering, selection atomicity, source
|
|
105
|
+
revalidation, projection, one-to-one durability, concurrency, retry, and the
|
|
106
|
+
no-replacement resume rule.
|
|
107
|
+
3. Client tests cover Workspace choice, selection, request payloads, chunked
|
|
108
|
+
NDJSON progress, error handling, disabled empty submission, and refresh order.
|
|
109
|
+
4. A real installed SDK lists and reads a native terminal Session using only the
|
|
110
|
+
public APIs.
|
|
111
|
+
5. Official DSH imports that Session, displays the projected history and title,
|
|
112
|
+
and sends the next turn to the same complete native Session ID.
|
|
113
|
+
6. Typecheck, the full repository test suite, build, package-content inspection,
|
|
114
|
+
and remote CI all pass.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Claude Search Tool Contract
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
The Claude Agent SDK backend exposes Claude's dedicated `Glob` and `Grep`
|
|
6
|
+
tools on every business and auxiliary query. This contract does not apply to
|
|
7
|
+
the text-only CLI fallback.
|
|
8
|
+
|
|
9
|
+
## Availability
|
|
10
|
+
|
|
11
|
+
Native Claude builds may otherwise provide filename and content search only
|
|
12
|
+
through Bash. The plugin must opt into `Glob` and `Grep` through the SDK's
|
|
13
|
+
`allowedTools` option so both dedicated tools are present without an approval
|
|
14
|
+
round trip. It must do so for new and resumed Sessions and whether or not the
|
|
15
|
+
owning DSH turn contributes tools.
|
|
16
|
+
|
|
17
|
+
The bare allow entries intentionally auto-approve only these two native,
|
|
18
|
+
read-only search tools, so the SDK does not call `canUseTool` for them. They do
|
|
19
|
+
not grant any mutation tool. The plugin still registers the permission callback
|
|
20
|
+
for every tool that is not otherwise allowed, and the SDK remains authoritative
|
|
21
|
+
for search path resolution and access enforcement.
|
|
22
|
+
|
|
23
|
+
The search entries augment the allowlist. They must never replace an
|
|
24
|
+
`mcp__dsh__*` entry created by the DSH tool bridge or alter the configured
|
|
25
|
+
permission mode, permission callback, working directory, plugins, or Session
|
|
26
|
+
continuation options.
|
|
27
|
+
|
|
28
|
+
## Delivery Acceptance
|
|
29
|
+
|
|
30
|
+
1. A query without DSH-contributed tools allows exactly the dedicated `Glob`
|
|
31
|
+
and `Grep` additions and does not create a DSH MCP server.
|
|
32
|
+
2. A query with DSH-contributed tools preserves every generated
|
|
33
|
+
`mcp__dsh__*` allow entry after `Glob` and `Grep`.
|
|
34
|
+
3. A fresh real SDK Session uses native `Glob` followed by native `Grep` to
|
|
35
|
+
find a precommitted unique path and marker, with no Bash fallback, approval,
|
|
36
|
+
or workspace mutation.
|
|
37
|
+
4. The same run returns the exact expected path and marker, and the recorded
|
|
38
|
+
SDK initialization advertises both tool names.
|
|
39
|
+
5. Existing SDK option, interaction, image, plugin, and DSH tool-bridge tests
|
|
40
|
+
remain green.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Claude Tool-Output Redaction
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
This document defines the plugin-owned secret-redaction contract for the
|
|
6
|
+
default Claude Agent SDK backend. It is the tracked delivery specification for
|
|
7
|
+
`CLD-ENV-003` and GitHub Issue #29.
|
|
8
|
+
|
|
9
|
+
## Contract
|
|
10
|
+
|
|
11
|
+
The plugin must resolve the effective Claude settings before every new or
|
|
12
|
+
resumed turn, using the same workspace and `settingSources` passed to the SDK.
|
|
13
|
+
The effective environment is the SDK process environment overlaid with the
|
|
14
|
+
resolved settings environment.
|
|
15
|
+
|
|
16
|
+
An environment value is sensitive when its non-empty variable name contains a
|
|
17
|
+
credential-bearing segment such as `SECRET`, `TOKEN`, `PASSWORD`, `PASSWD`,
|
|
18
|
+
`API_KEY`, `ACCESS_KEY`, `PRIVATE_KEY`, or `CREDENTIALS`. A variable explicitly
|
|
19
|
+
listed under `sandbox.credentials.envVars` is also sensitive, regardless of its
|
|
20
|
+
name. If multiple sensitive names have the same value, the lexicographically
|
|
21
|
+
first name supplies the deterministic replacement marker.
|
|
22
|
+
|
|
23
|
+
Before a successful tool result is delivered to the model, SDK consumers, or
|
|
24
|
+
native Session persistence, the plugin must run a synchronous SDK `PostToolUse`
|
|
25
|
+
callback. Every exact occurrence of a sensitive value in a string anywhere in
|
|
26
|
+
the structured tool response is replaced with
|
|
27
|
+
`[REDACTED_ENV:<VARIABLE_NAME>]`. Longer values are processed first so an
|
|
28
|
+
overlapping shorter value cannot partially expose them.
|
|
29
|
+
|
|
30
|
+
The callback must not return `updatedToolOutput` when no configured value
|
|
31
|
+
occurs. This preserves the original object and avoids an identity rewrite that
|
|
32
|
+
could compete with another legitimate output-rewriting hook.
|
|
33
|
+
|
|
34
|
+
The redacted result, not the raw result, must be visible in both normalized SDK
|
|
35
|
+
activity and the native Claude JSONL transcript. Tool execution status and
|
|
36
|
+
non-sensitive output remain unchanged.
|
|
37
|
+
|
|
38
|
+
## Boundaries
|
|
39
|
+
|
|
40
|
+
This contract protects tool output containing values from the effective Claude
|
|
41
|
+
environment. It does not rewrite user prompts, tool inputs, arbitrary values
|
|
42
|
+
that cannot be classified from host configuration, files created by tools, or
|
|
43
|
+
errors for which the SDK emits `PostToolUseFailure` without a replaceable tool
|
|
44
|
+
output. It applies to the SDK backend; the explicit CLI fallback does not offer
|
|
45
|
+
the required pre-persistence hook contract.
|
|
46
|
+
|
|
47
|
+
The implementation must use the supported SDK result-replacement lifecycle.
|
|
48
|
+
Post-hoc edits to Claude JSONL files are forbidden because they are racy and can
|
|
49
|
+
damage Session continuation.
|
|
50
|
+
|
|
51
|
+
Claude treats output rewrites from multiple synchronous hooks as competing
|
|
52
|
+
replacements. A trusted administrator who installs another `PostToolUse` hook
|
|
53
|
+
that supersedes this plugin's redacted result must ensure that replacement does
|
|
54
|
+
not reintroduce a protected value; the plugin cannot sanitize output created
|
|
55
|
+
after its callback has returned.
|
|
56
|
+
|
|
57
|
+
## Delivery Acceptance
|
|
58
|
+
|
|
59
|
+
1. The historical `CLD-ENV-003` probe reproduces the pre-fix leak while the
|
|
60
|
+
Bash tool completes successfully.
|
|
61
|
+
2. The same probe against the fixed plugin executes Bash exactly once, keeps
|
|
62
|
+
the expected final marker, and finds zero raw-secret occurrences in SDK
|
|
63
|
+
activity, the native transcript, diagnostics, and final text.
|
|
64
|
+
3. Focused tests cover sensitive-name detection, explicit credential names,
|
|
65
|
+
nested structured output, ordinary values, no-op output, and both new and
|
|
66
|
+
resumed turns.
|
|
67
|
+
4. Typecheck, the complete test suite, build, package dry-run, a real SDK probe,
|
|
68
|
+
and an official DSH end-to-end run all pass.
|