@jingyi0605/codingns4dsh 0.2.1-beta.1 → 0.2.1-beta.2
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 +25 -14
- package/README.md +17 -15
- package/data/build/dist/client/bundle.js +198 -47
- package/data/build/dist/client/bundle.js.map +1 -1
- package/data/build/dist/client/locales/fileWorkspace.d.ts.map +1 -1
- package/data/build/dist/client/locales/fileWorkspace.js +4 -0
- package/data/build/dist/client/locales/fileWorkspace.js.map +1 -1
- package/data/build/dist/client/session-changed-files-view.d.ts.map +1 -1
- package/data/build/dist/client/session-changed-files-view.js +162 -58
- package/data/build/dist/client/session-changed-files-view.js.map +1 -1
- package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts +8 -3
- package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/acp-cli-driver.js +99 -6
- package/data/build/dist/host/cli-adapters/acp-cli-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/acp-elicitation.d.ts +31 -0
- package/data/build/dist/host/cli-adapters/acp-elicitation.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/acp-elicitation.js +144 -0
- package/data/build/dist/host/cli-adapters/acp-elicitation.js.map +1 -0
- package/data/build/dist/host/cli-adapters/antigravity-driver.d.ts +2 -1
- package/data/build/dist/host/cli-adapters/antigravity-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/antigravity-driver.js +15 -2
- package/data/build/dist/host/cli-adapters/antigravity-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-driver.d.ts +10 -1
- package/data/build/dist/host/cli-adapters/claude-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-driver.js +134 -2
- package/data/build/dist/host/cli-adapters/claude-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/codebuddy-driver.d.ts +7 -1
- package/data/build/dist/host/cli-adapters/codebuddy-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/codebuddy-driver.js +143 -6
- package/data/build/dist/host/cli-adapters/codebuddy-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.js +20 -8
- package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/cursor-driver.d.ts +1 -1
- package/data/build/dist/host/cli-adapters/cursor-driver.js +2 -2
- package/data/build/dist/host/cli-adapters/cursor-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.js +1 -1
- package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.js.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.js +4 -2
- package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
- package/data/build/dist/host/cli-adapters/gemini-driver.d.ts +2 -1
- package/data/build/dist/host/cli-adapters/gemini-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/gemini-driver.js +66 -11
- package/data/build/dist/host/cli-adapters/gemini-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/grok-driver.d.ts +3 -2
- package/data/build/dist/host/cli-adapters/grok-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/grok-driver.js +65 -14
- package/data/build/dist/host/cli-adapters/grok-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/kiro-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/kiro-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/mcode-driver.d.ts +6 -2
- package/data/build/dist/host/cli-adapters/mcode-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/mcode-driver.js +93 -24
- package/data/build/dist/host/cli-adapters/mcode-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/native-subagent-dispatch.d.ts +55 -1
- package/data/build/dist/host/cli-adapters/native-subagent-dispatch.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/native-subagent-dispatch.js +148 -6
- package/data/build/dist/host/cli-adapters/native-subagent-dispatch.js.map +1 -1
- package/data/build/dist/host/cli-adapters/native-team-subagent.d.ts +7 -0
- package/data/build/dist/host/cli-adapters/native-team-subagent.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/native-team-subagent.js.map +1 -1
- package/data/build/dist/host/cli-adapters/qoder-driver.d.ts +4 -4
- package/data/build/dist/host/cli-adapters/qoder-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/qoder-driver.js +31 -8
- package/data/build/dist/host/cli-adapters/qoder-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/standard-stream-driver.js +3 -1
- package/data/build/dist/host/cli-adapters/standard-stream-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/subagent-tool.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/subagent-tool.js +40 -10
- package/data/build/dist/host/cli-adapters/subagent-tool.js.map +1 -1
- package/data/build/dist/host/cli-bridge/bridge-holder.d.ts +4 -1
- package/data/build/dist/host/cli-bridge/bridge-holder.d.ts.map +1 -1
- package/data/build/dist/host/cli-bridge/bridge-holder.js.map +1 -1
- package/data/build/dist/host/cli-bridge/bridge-server.d.ts +11 -3
- package/data/build/dist/host/cli-bridge/bridge-server.d.ts.map +1 -1
- package/data/build/dist/host/cli-bridge/bridge-server.js +8 -4
- package/data/build/dist/host/cli-bridge/bridge-server.js.map +1 -1
- package/data/build/dist/host/cli-bridge/command-code-mod.js +18 -2
- package/data/build/dist/host/cli-bridge/command-code-mod.js.map +1 -1
- package/data/build/dist/host/cli-bridge/dispatch.d.ts.map +1 -1
- package/data/build/dist/host/cli-bridge/dispatch.js +30 -5
- package/data/build/dist/host/cli-bridge/dispatch.js.map +1 -1
- package/data/build/dist/host/cli-bridge/injections.js +2 -2
- package/data/build/dist/host/cli-bridge/injections.js.map +1 -1
- package/data/build/dist/host/cli-bridge/mcp-stdio-entry.js +49 -7
- package/data/build/dist/host/cli-bridge/mcp-stdio-entry.js.map +1 -1
- package/data/build/dist/host/index.d.ts +1 -1
- package/data/build/dist/host/index.d.ts.map +1 -1
- package/data/build/dist/host/index.js +1 -1
- package/data/build/dist/host/index.js.map +1 -1
- package/data/build/dist/shared/contracts/version.d.ts +1 -1
- package/data/build/dist/shared/contracts/version.js +1 -1
- package/package.json +1 -1
- package/profile/README.md +2 -2
- package/profile/package.json +2 -2
- package/profile/version.json +1 -1
- package/version.json +1 -1
package/README.en.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
[简体中文](README.md) · **English**
|
|
13
13
|
|
|
14
|
-
**Current release `@jingyi0605/codingns4dsh@0.2.1-beta.
|
|
14
|
+
**Current release `@jingyi0605/codingns4dsh@0.2.1-beta.2`** · DSH **`>=0.2.0-rc.2 <=0.2.1-alpha.1`** (tested with `0.2.1-alpha.1`) · Node **`>= 22.19`** · macOS / Linux / Windows
|
|
15
15
|
|
|
16
16
|
**[GitHub](https://github.com/jingyi0605/Codingns4DSH)** · **[npm](https://www.npmjs.com/package/@jingyi0605/codingns4dsh)** · **QQ group 1092985965**
|
|
17
17
|
|
|
@@ -74,21 +74,32 @@ Notes: the sidebar terminal exists as soon as the plugin is installed — **Term
|
|
|
74
74
|
|
|
75
75
|
Detected on the Host by command name; version and models come from the CLI itself. Detected Agents are enabled by default and can be toggled individually. The built-in **DeepSeek Harness** Agent is always available.
|
|
76
76
|
|
|
77
|
-
| Agent | id | Command | Protocol | Capabilities |
|
|
78
|
-
| --- | --- | --- | --- | --- |
|
|
79
|
-
| Command Code | `command-code` | `command-code`, `commandcode`, `cmdc` | single-shot CLI | models, streaming, resume, interrupt, tools, thinking, usage |
|
|
80
|
-
| Claude Code | `claude-code` | `claude` | stream-json | models, streaming, resume, interrupt, tools, thinking, usage |
|
|
81
|
-
| Kimi CLI | `kimi` | `kimi`, `kimi-cli` | stream-json | all of the above + approvals, questions, steering |
|
|
82
|
-
| Gemini CLI | `gemini` | `gemini` | ACP | models, streaming, resume, interrupt, tools, thinking, usage, approvals |
|
|
83
|
-
| Pi Agent | `pi` | `pi`, `pi-agent` | JSON-RPC | models, streaming, resume, interrupt, tools, thinking, usage, steering |
|
|
84
|
-
| Codex | `codex` | `codex` | JSON-RPC (app-server) | all + approvals, questions, steering |
|
|
85
|
-
| OpenCode | `opencode` | `opencode`, or `OPENCODE_SERVER_URL` (default `http://127.0.0.1:4096`) | HTTP + SSE | all + approvals, questions |
|
|
86
|
-
| Grok Build | `grok` | `grok`, `grok-build` | ACP | models, streaming, tools, thinking, usage, approvals |
|
|
77
|
+
| Agent | id | Command | Protocol | Capabilities | Notes |
|
|
78
|
+
| --- | --- | --- | --- | --- | --- |
|
|
79
|
+
| Command Code | `command-code` | `command-code`, `commandcode`, `cmdc` | single-shot CLI | models, streaming, resume, interrupt, tools, thinking, usage | DSH permission state maps to CLI safety modes; no verifiable interactive approval/question wire |
|
|
80
|
+
| Claude Code | `claude-code` | `claude` | stream-json | models, streaming, resume, interrupt, tools, thinking, usage, approvals, questions | `can_use_tool` approvals and `AskUserQuestion` |
|
|
81
|
+
| Kimi CLI | `kimi` | `kimi`, `kimi-cli` | stream-json | all of the above + approvals, questions, steering | — |
|
|
82
|
+
| Gemini CLI | `gemini` | `gemini` | ACP | models, streaming, resume, interrupt, tools, thinking, usage, approvals, questions | ACP permissions and form elicitation |
|
|
83
|
+
| Pi Agent | `pi` | `pi`, `pi-agent` | JSON-RPC | models, streaming, resume, interrupt, tools, thinking, usage, steering | No verifiable DSH approval/question response wire in the current protocol |
|
|
84
|
+
| Codex | `codex` | `codex` | JSON-RPC (app-server) | all + approvals, questions, steering | — |
|
|
85
|
+
| OpenCode | `opencode` | `opencode`, or `OPENCODE_SERVER_URL` (default `http://127.0.0.1:4096`) | HTTP + SSE | all + approvals, questions | — |
|
|
86
|
+
| Grok Build | `grok` | `grok`, `grok-build` | ACP | models, streaming, tools, thinking, usage, approvals, questions | ACP permissions and form elicitation |
|
|
87
|
+
| MiniMax Code | `mcode` | `mcode` | ACP / stream-json | models, streaming, resume, interrupt, tools, thinking, usage, approvals, questions | Interactive requests use ACP; the explicit-effort `exec` path has no interactive response wire |
|
|
88
|
+
| ZCode | `zcode` | `zcode`, bundled desktop runtime | JSON-RPC bare envelope | models, streaming, resume, interrupt, usage | No verifiable DSH approval/question response wire |
|
|
89
|
+
| CodeBuddy (auto-detects CN/international) | `codebuddy` | `codebuddy`, `codebuddy-code`, `cbc`, and Windows `.cmd` entry points; region selected from environment and auth domain | ACP (`--acp`) | models, streaming, resume, interrupt, tools, thinking, usage, approvals, questions | Supports stdio ACP and HTTP sidecar ACP |
|
|
90
|
+
| WorkBuddy | `workbuddy` | `codebuddy` bundled in the WorkBuddy desktop app | ACP (`--acp`) | models, streaming, resume, interrupt, tools, thinking, approvals, questions | Permissions and form elicitation use the HTTP ACP sidecar |
|
|
91
|
+
| Cursor CLI | `cursor-cli` | `cursor-agent`, `agent` | ACP (`acp`) | models, streaming, resume, interrupt, tools, thinking, approvals, questions | Standard ACP permissions and form elicitation |
|
|
92
|
+
| Kiro CLI | `kiro-cli` | `kiro-cli` | ACP (`acp --agent-engine v3 --auth-method cli`) | models, streaming, resume, interrupt, tools, thinking, approvals, questions | Standard ACP permissions and form elicitation |
|
|
93
|
+
| Qoder | `qoder` | `qoder`, `qodercli` | ACP (`--acp`) | models, streaming, resume, interrupt, tools, thinking, approvals, questions | Standard ACP permissions and form elicitation |
|
|
94
|
+
| Qoder CN | `qoder-cn` | `qodercn`, `qoderclicn` | ACP (`--acp`) | models, streaming, resume, interrupt, tools, thinking, approvals, questions | Standard ACP permissions and form elicitation |
|
|
95
|
+
| Antigravity | `antigravity` | `agy` | stream-json (stdin NDJSON) | models, streaming, resume, interrupt, tools, thinking | Permission state maps to CLI safety modes; no interactive approval/question wire |
|
|
87
96
|
|
|
88
97
|
**models** model list · **streaming** live output · **resume** continue after restart · **interrupt** cancel a turn · **tools** tool calls in the conversation · **thinking** reasoning/effort · **usage** token or subscription limits · **approvals / questions** native DSH interactions · **steering** inject a message mid-turn.
|
|
89
98
|
|
|
90
99
|
Unlisted capabilities are unsupported by that CLI or version. Install and log in to each Agent outside DSH; Codingns4DSH never stores Agent credentials.
|
|
91
100
|
|
|
101
|
+
Approvals and questions are rendered by DSH's native components. Adapters with an interactive response wire normalize Provider requests into `permission-request` or `question-request` events, pass them to the native approval/question components, then send the typed answer back with the Provider's original request ID. ACP adapters use the standard `session/request_permission` and `elicitation/create` form requests; URL elicitation requires a browser security-consent flow and is not advertised. Agents without a verifiable response wire keep those capabilities undeclared; Command Code and Antigravity only map DSH permission state to CLI safety modes.
|
|
102
|
+
|
|
92
103
|
---
|
|
93
104
|
|
|
94
105
|
## Feature Details
|
|
@@ -223,7 +234,7 @@ The “access” line tells you whether you entered DSH Web locally, over the LA
|
|
|
223
234
|
DSH automatically initializes the `web` profile on first use. You do not need to create a config file or run `--dump-config`:
|
|
224
235
|
|
|
225
236
|
```bash
|
|
226
|
-
dsh plugin --profile web add @jingyi0605/codingns4dsh@0.2.1-beta.
|
|
237
|
+
dsh plugin --profile web add @jingyi0605/codingns4dsh@0.2.1-beta.2
|
|
227
238
|
dsh web
|
|
228
239
|
```
|
|
229
240
|
|
|
@@ -233,7 +244,7 @@ If you do not want to modify the built-in `web` profile, create a separate profi
|
|
|
233
244
|
|
|
234
245
|
```bash
|
|
235
246
|
dsh codingns --from-default-profile web --dump-config
|
|
236
|
-
dsh plugin --profile codingns add @jingyi0605/codingns4dsh@0.2.1-beta.
|
|
247
|
+
dsh plugin --profile codingns add @jingyi0605/codingns4dsh@0.2.1-beta.2
|
|
237
248
|
dsh codingns
|
|
238
249
|
```
|
|
239
250
|
|
|
@@ -254,7 +265,7 @@ dsh plugin --profile web remove @jingyi0605/codingns4dsh
|
|
|
254
265
|
```bash
|
|
255
266
|
git clone https://github.com/jingyi0605/Codingns4DSH.git && cd Codingns4DSH
|
|
256
267
|
pnpm install && pnpm build
|
|
257
|
-
dsh plugin --profile web add "$PWD" # or: npm pack, then add ./jingyi0605-codingns4dsh-0.2.1-beta.
|
|
268
|
+
dsh plugin --profile web add "$PWD" # or: npm pack, then add ./jingyi0605-codingns4dsh-0.2.1-beta.2.tgz
|
|
258
269
|
dsh web
|
|
259
270
|
```
|
|
260
271
|
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
**简体中文** · [English](README.en.md)
|
|
13
13
|
|
|
14
|
-
**当前版本 `@jingyi0605/codingns4dsh@0.2.1-beta.
|
|
14
|
+
**当前版本 `@jingyi0605/codingns4dsh@0.2.1-beta.2`** · DSH **`>=0.2.0-rc.2 <=0.2.1-alpha.1`**(已验证 `0.2.1-alpha.1`)· Node **`>= 22.19`** · macOS / Linux / Windows
|
|
15
15
|
|
|
16
16
|
**[GitHub](https://github.com/jingyi0605/Codingns4DSH)** · **[npm](https://www.npmjs.com/package/@jingyi0605/codingns4dsh)** · **QQ 群 1092985965**
|
|
17
17
|
|
|
@@ -76,28 +76,30 @@ DSH 原生部分不会被替换:对话、会话列表、侧栏、设置、权
|
|
|
76
76
|
|
|
77
77
|
| Agent | id | 命令 | 协议 | 能力 | 备注 |
|
|
78
78
|
| --- | --- | --- | --- | --- | --- |
|
|
79
|
-
| Command Code | `command-code` | `command-code`、`commandcode`、`cmdc` | 单轮 CLI | 模型、流式、恢复、打断、工具、思考、用量 |
|
|
80
|
-
| Claude Code | `claude-code` | `claude` | stream-json |
|
|
79
|
+
| Command Code | `command-code` | `command-code`、`commandcode`、`cmdc` | 单轮 CLI | 模型、流式、恢复、打断、工具、思考、用量 | 权限按 DSH 状态映射为 CLI 安全模式;没有可回传的交互式权限/提问协议 |
|
|
80
|
+
| Claude Code | `claude-code` | `claude` | stream-json | 模型、流式、恢复、打断、工具、思考、用量、权限确认、提问 | `can_use_tool` 权限确认与 `AskUserQuestion` 提问 |
|
|
81
81
|
| Kimi CLI | `kimi` | `kimi`、`kimi-cli` | stream-json | 上述全部 + 权限确认、提问、插话 | — |
|
|
82
|
-
| Gemini CLI | `gemini` | `gemini` | ACP |
|
|
83
|
-
| Pi Agent | `pi` | `pi`、`pi-agent` | JSON-RPC | 模型、流式、恢复、打断、工具、思考、用量、插话 |
|
|
82
|
+
| Gemini CLI | `gemini` | `gemini` | ACP | 模型、流式、恢复、打断、工具、思考、用量、权限确认、提问 | ACP 权限与 form elicitation(表单式询问) |
|
|
83
|
+
| Pi Agent | `pi` | `pi`、`pi-agent` | JSON-RPC | 模型、流式、恢复、打断、工具、思考、用量、插话 | 当前协议没有可验证的 DSH 权限/提问回传 |
|
|
84
84
|
| Codex | `codex` | `codex` | JSON-RPC(app-server) | 全部 + 权限确认、提问、插话 | — |
|
|
85
85
|
| OpenCode | `opencode` | `opencode`,或 `OPENCODE_SERVER_URL`(默认 `http://127.0.0.1:4096`) | HTTP + SSE | 全部 + 权限确认、提问 | — |
|
|
86
|
-
| Grok Build | `grok` | `grok`、`grok-build` | ACP |
|
|
87
|
-
| MiniMax Code | `mcode` | `mcode` | ACP / stream-json |
|
|
86
|
+
| Grok Build | `grok` | `grok`、`grok-build` | ACP | 模型、流式、工具、思考、用量、权限确认、提问 | ACP 权限与 form elicitation(表单式询问) |
|
|
87
|
+
| MiniMax Code | `mcode` | `mcode` | ACP / stream-json | 模型、流式、恢复、打断、工具、思考、用量、权限确认、提问 | 默认 ACP 路径支持交互;显式思考档位的 `exec` 路径没有交互式回传;上游贡献者:[chenjunyi000](https://github.com/chenjunyi000);提交 PR [#6](https://github.com/jingyi0605/Codingns4DSH/pull/6)、[#7](https://github.com/jingyi0605/Codingns4DSH/pull/7) |
|
|
88
88
|
| ZCode | `zcode` | `zcode`、桌面端内置运行时 | JSON-RPC 裸信封 | 模型、流式、恢复、打断、用量 | 上游贡献者:[chenjunyi000](https://github.com/chenjunyi000);提交 PR [#6](https://github.com/jingyi0605/Codingns4DSH/pull/6)、[#7](https://github.com/jingyi0605/Codingns4DSH/pull/7) |
|
|
89
|
-
| CodeBuddy(自动识别 CN/国际版) | `codebuddy` | `codebuddy`、`codebuddy-code`、`cbc` 及 Windows `.cmd` 入口;按环境变量与认证域名自动选择区域 | ACP(`--acp`) |
|
|
90
|
-
| WorkBuddy | `workbuddy` | WorkBuddy 桌面应用内置 `codebuddy` | ACP(`--acp`) |
|
|
91
|
-
| Cursor CLI | `cursor-cli` | `cursor-agent`、`agent` | ACP(`acp`) |
|
|
92
|
-
| Kiro CLI | `kiro-cli` | `kiro-cli` | ACP(`acp --agent-engine v3 --auth-method cli`) |
|
|
93
|
-
| Qoder | `qoder` | `qoder`、`qodercli` | ACP(`--acp`) |
|
|
94
|
-
| Qoder CN | `qoder-cn` | `qodercn`、`qoderclicn` | ACP(`--acp`) |
|
|
89
|
+
| CodeBuddy(自动识别 CN/国际版) | `codebuddy` | `codebuddy`、`codebuddy-code`、`cbc` 及 Windows `.cmd` 入口;按环境变量与认证域名自动选择区域 | ACP(`--acp`) | 模型、流式、恢复、打断、工具、思考、用量、权限确认、提问 | 支持 stdio ACP 与 HTTP sidecar(旁路服务) ACP;CodexHost 上游贡献者:[mouzhi](https://github.com/mouzhi);首次适配 [f30b000](https://github.com/BytePioneer-AI/codex-host/commit/f30b000f88950c40844b071eec2f6f385c6bcb49) |
|
|
90
|
+
| WorkBuddy | `workbuddy` | WorkBuddy 桌面应用内置 `codebuddy` | ACP(`--acp`) | 模型、流式、恢复、打断、工具、思考、权限确认、提问 | 通过 HTTP ACP sidecar(旁路服务)接入权限与 form elicitation(表单式询问);CodexHost 上游贡献者:[BytePioneer-AI(ChongWen)](https://github.com/BytePioneer-AI);首次适配 [6e9f365](https://github.com/BytePioneer-AI/codex-host/commit/6e9f365e2bf8ac61716f8250475530ae790f2d2f) |
|
|
91
|
+
| Cursor CLI | `cursor-cli` | `cursor-agent`、`agent` | ACP(`acp`) | 模型、流式、恢复、打断、工具、思考、权限确认、提问 | ACP 标准权限与 form elicitation(表单式询问);CodexHost 上游贡献者:[mouzhi](https://github.com/mouzhi);首次适配 [ad6ba8e](https://github.com/BytePioneer-AI/codex-host/commit/ad6ba8e04d294c473d2dcad99880496ff39c1f7e) |
|
|
92
|
+
| Kiro CLI | `kiro-cli` | `kiro-cli` | ACP(`acp --agent-engine v3 --auth-method cli`) | 模型、流式、恢复、打断、工具、思考、权限确认、提问 | ACP 标准权限与 form elicitation(表单式询问);CodexHost 上游贡献者:[gy212](https://github.com/gy212);首次适配 [79675cd](https://github.com/BytePioneer-AI/codex-host/commit/79675cdbfdc042eb37a849c3eb1539e9efc40a0d) |
|
|
93
|
+
| Qoder | `qoder` | `qoder`、`qodercli` | ACP(`--acp`) | 模型、流式、恢复、打断、工具、思考、权限确认、提问 | ACP 标准权限与 form elicitation(表单式询问);CodexHost 上游贡献者:[gy212](https://github.com/gy212)、[BytePioneer-AI(ChongWen)](https://github.com/BytePioneer-AI);PR #289 合并 [8926130](https://github.com/BytePioneer-AI/codex-host/commit/8926130af1426a467747b66d8d2dbf68f7764a7b) |
|
|
94
|
+
| Qoder CN | `qoder-cn` | `qodercn`、`qoderclicn` | ACP(`--acp`) | 模型、流式、恢复、打断、工具、思考、权限确认、提问 | ACP 标准权限与 form elicitation(表单式询问);CodexHost 上游贡献者:[gy212](https://github.com/gy212)、[BytePioneer-AI(ChongWen)](https://github.com/BytePioneer-AI);PR #289 合并 [8926130](https://github.com/BytePioneer-AI/codex-host/commit/8926130af1426a467747b66d8d2dbf68f7764a7b) |
|
|
95
95
|
| Antigravity | `antigravity` | `agy` | stream-json(stdin NDJSON) | 模型、流式、恢复、打断、工具、思考 | CodexHost 上游贡献者:[gy212](https://github.com/gy212);首次适配 [ed4e785](https://github.com/BytePioneer-AI/codex-host/commit/ed4e785116642eafc08e4186e92e83f3816c7765) |
|
|
96
96
|
|
|
97
97
|
**模型** 模型列表 · **流式** 实时输出 · **恢复** 重启后继续 · **打断** 取消当前回合 · **工具** 对话中渲染工具调用 · **思考** 推理/思考强度 · **用量** token 或订阅额度 · **权限确认 / 提问** 变成 DSH 原生交互 · **插话** 回合中追加消息。
|
|
98
98
|
|
|
99
99
|
未列出的能力表示该 CLI 或其版本不支持;Agent 的安装与登录都在 DSH 之外完成,Codingns4DSH 不保存 Agent 凭据。
|
|
100
100
|
|
|
101
|
+
权限确认和提问都由 DSH 原生组件承载。支持交互式回传的适配器会把 Provider 请求转换为公共的 `permission-request` 或 `question-request` 事件,交给 DSH 原生审批/问题组件,再按 Provider 协议和原始请求 ID 回传。ACP 适配器接入标准 `session/request_permission` 与 `elicitation/create` form(表单式询问);URL elicitation(URL 询问)需要浏览器安全确认流程,当前不宣告该能力。没有可验证回传协议的 Agent 保持能力未声明;Command Code 和 Antigravity 只根据 DSH 权限状态下发 CLI 安全模式。
|
|
102
|
+
|
|
101
103
|
---
|
|
102
104
|
|
|
103
105
|
## 功能详解
|
|
@@ -238,7 +240,7 @@ DSH 设置按钮旁的账户入口会显示登录状态、访问路径与延迟
|
|
|
238
240
|
DSH 的 `web` Profile 会在首次使用时自动初始化,不需要手动创建配置文件,也不需要执行 `--dump-config`:
|
|
239
241
|
|
|
240
242
|
```bash
|
|
241
|
-
dsh plugin --profile web add @jingyi0605/codingns4dsh@0.2.1-beta.
|
|
243
|
+
dsh plugin --profile web add @jingyi0605/codingns4dsh@0.2.1-beta.2
|
|
242
244
|
dsh web
|
|
243
245
|
```
|
|
244
246
|
|
|
@@ -248,7 +250,7 @@ dsh web
|
|
|
248
250
|
|
|
249
251
|
```bash
|
|
250
252
|
dsh codingns --from-default-profile web --dump-config
|
|
251
|
-
dsh plugin --profile codingns add @jingyi0605/codingns4dsh@0.2.1-beta.
|
|
253
|
+
dsh plugin --profile codingns add @jingyi0605/codingns4dsh@0.2.1-beta.2
|
|
252
254
|
dsh codingns
|
|
253
255
|
```
|
|
254
256
|
|
|
@@ -296,6 +296,8 @@ window.__ModuleLoader__.load({
|
|
|
296
296
|
"sessionFiles.title": "Changed files",
|
|
297
297
|
"sessionFiles.count": "{count} files",
|
|
298
298
|
"sessionFiles.refresh": "Refresh",
|
|
299
|
+
"sessionFiles.close": "Close diff",
|
|
300
|
+
"sessionFiles.loadingDiff": "Reading diff…",
|
|
299
301
|
"sessionFiles.stageAll": "Stage all",
|
|
300
302
|
"sessionFiles.loading": "Reading session changes…",
|
|
301
303
|
"sessionFiles.empty": "No changed files were detected in this session",
|
|
@@ -362,6 +364,8 @@ window.__ModuleLoader__.load({
|
|
|
362
364
|
"sessionFiles.title": "修改文件",
|
|
363
365
|
"sessionFiles.count": "{count} 个文件",
|
|
364
366
|
"sessionFiles.refresh": "刷新",
|
|
367
|
+
"sessionFiles.close": "关闭 Diff",
|
|
368
|
+
"sessionFiles.loadingDiff": "正在读取 Diff…",
|
|
365
369
|
"sessionFiles.stageAll": "全部暂存",
|
|
366
370
|
"sessionFiles.loading": "正在读取会话修改…",
|
|
367
371
|
"sessionFiles.empty": "本次会话没有已识别的修改文件",
|
|
@@ -2788,7 +2792,7 @@ window.__ModuleLoader__.load({
|
|
|
2788
2792
|
return /^0\.1\.5(?:-|$)/u.test(version);
|
|
2789
2793
|
}
|
|
2790
2794
|
/** Codingns4DSH 插件自身的 npm 版本。 */
|
|
2791
|
-
const CODINGNS_VERSION = "0.2.1-beta.
|
|
2795
|
+
const CODINGNS_VERSION = "0.2.1-beta.2";
|
|
2792
2796
|
/** 判断宿主版本是否落在当前插件声明的 DSH 兼容范围内;范围省略上界时不校验上限。 */
|
|
2793
2797
|
function isDshVersionCompatible(version) {
|
|
2794
2798
|
const match = /^>=([^ ]+)(?: <=([^ ]+))?$/u.exec(DSH_COMPATIBILITY);
|
|
@@ -56021,8 +56025,11 @@ window.__ModuleLoader__.load({
|
|
|
56021
56025
|
}
|
|
56022
56026
|
//#endregion
|
|
56023
56027
|
//#region src/client/session-changed-files-view.ts
|
|
56028
|
+
init_popup_dismiss();
|
|
56024
56029
|
init_locale();
|
|
56025
56030
|
const SESSION_CHANGED_FILES_VIEW_ID = "codingns4dsh/session-changed-files";
|
|
56031
|
+
/** 后台轮询只负责兜底发现外部文件变化,不能和页面交互争夺刷新节奏。 */
|
|
56032
|
+
const SESSION_CHANGED_FILES_BACKGROUND_REFRESH_MS = 3e4;
|
|
56026
56033
|
/** 会话“修改文件”视图;数据只通过插件 RPC 和现有 Git RPC 读取。 */
|
|
56027
56034
|
function SessionChangedFilesView(props) {
|
|
56028
56035
|
const t = props.t;
|
|
@@ -56031,50 +56038,68 @@ window.__ModuleLoader__.load({
|
|
|
56031
56038
|
const [changes, setChanges] = (0, react.useState)([]);
|
|
56032
56039
|
const [selectedPath, setSelectedPath] = (0, react.useState)();
|
|
56033
56040
|
const [diff, setDiff] = (0, react.useState)();
|
|
56041
|
+
const [diffLoading, setDiffLoading] = (0, react.useState)(false);
|
|
56042
|
+
const [mobileDiffOpen, setMobileDiffOpen] = (0, react.useState)(false);
|
|
56034
56043
|
const [collapsed, setCollapsed] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
56035
56044
|
const [hoveredPath, setHoveredPath] = (0, react.useState)();
|
|
56036
56045
|
const [loading, setLoading] = (0, react.useState)(true);
|
|
56037
56046
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
56038
56047
|
const [error, setError] = (0, react.useState)();
|
|
56039
56048
|
const requestGeneration = (0, react.useRef)(0);
|
|
56040
|
-
const
|
|
56049
|
+
const inFlightLoad = (0, react.useRef)();
|
|
56050
|
+
const load = (foreground = false) => {
|
|
56051
|
+
if (inFlightLoad.current !== void 0) return inFlightLoad.current;
|
|
56041
56052
|
const generation = requestGeneration.current + 1;
|
|
56042
56053
|
requestGeneration.current = generation;
|
|
56043
|
-
|
|
56044
|
-
|
|
56045
|
-
|
|
56046
|
-
const resolved = await resolveGitWorkspaceId(props.remote, props.sessionId);
|
|
56047
|
-
if (resolved === void 0) throw new Error("当前会话没有可用的工作区");
|
|
56048
|
-
const [sessionFiles, status] = await Promise.all([call(props.rpc, "fileManagement/session-changes", {
|
|
56049
|
-
sessionId: props.sessionId,
|
|
56050
|
-
workspaceId: resolved
|
|
56051
|
-
}), call(props.rpc, "git/status", { workspaceId: resolved })]);
|
|
56052
|
-
if (generation !== requestGeneration.current) return;
|
|
56053
|
-
const next = selectSessionChangedFiles(sessionFiles, status);
|
|
56054
|
-
setWorkspaceId(resolved);
|
|
56055
|
-
setChanges(next);
|
|
56056
|
-
props.reportCount?.(props.sessionId, next.length);
|
|
56057
|
-
setSelectedPath((current) => current !== void 0 && next.some((item) => item.path === current) ? current : next[0]?.path);
|
|
56058
|
-
} catch (cause) {
|
|
56059
|
-
if (generation !== requestGeneration.current) return;
|
|
56060
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
56061
|
-
setChanges([]);
|
|
56062
|
-
setWorkspaceId(void 0);
|
|
56063
|
-
props.reportCount?.(props.sessionId, 0);
|
|
56064
|
-
} finally {
|
|
56065
|
-
if (generation === requestGeneration.current) setLoading(false);
|
|
56054
|
+
if (foreground) {
|
|
56055
|
+
setLoading(true);
|
|
56056
|
+
setError(void 0);
|
|
56066
56057
|
}
|
|
56058
|
+
const tracked = (async () => {
|
|
56059
|
+
try {
|
|
56060
|
+
const resolved = await resolveGitWorkspaceId(props.remote, props.sessionId);
|
|
56061
|
+
if (resolved === void 0) throw new Error("当前会话没有可用的工作区");
|
|
56062
|
+
const [sessionFiles, status] = await Promise.all([call(props.rpc, "fileManagement/session-changes", {
|
|
56063
|
+
sessionId: props.sessionId,
|
|
56064
|
+
workspaceId: resolved
|
|
56065
|
+
}), call(props.rpc, "git/status", { workspaceId: resolved })]);
|
|
56066
|
+
if (generation !== requestGeneration.current) return;
|
|
56067
|
+
const next = selectSessionChangedFiles(sessionFiles, status);
|
|
56068
|
+
setWorkspaceId((current) => current === resolved ? current : resolved);
|
|
56069
|
+
setChanges((current) => mergeChangedFiles(current, next));
|
|
56070
|
+
props.reportCount?.(props.sessionId, next.length);
|
|
56071
|
+
setSelectedPath((current) => current !== void 0 && next.some((item) => item.path === current) ? current : next[0]?.path);
|
|
56072
|
+
setError(void 0);
|
|
56073
|
+
} catch (cause) {
|
|
56074
|
+
if (generation !== requestGeneration.current) return;
|
|
56075
|
+
if (foreground) {
|
|
56076
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
56077
|
+
setChanges([]);
|
|
56078
|
+
setWorkspaceId(void 0);
|
|
56079
|
+
props.reportCount?.(props.sessionId, 0);
|
|
56080
|
+
} else setError(cause instanceof Error ? cause.message : String(cause));
|
|
56081
|
+
} finally {
|
|
56082
|
+
if (generation === requestGeneration.current && foreground) setLoading(false);
|
|
56083
|
+
}
|
|
56084
|
+
})().finally(() => {
|
|
56085
|
+
if (inFlightLoad.current === tracked) inFlightLoad.current = void 0;
|
|
56086
|
+
});
|
|
56087
|
+
inFlightLoad.current = tracked;
|
|
56088
|
+
return tracked;
|
|
56067
56089
|
};
|
|
56068
56090
|
(0, react.useEffect)(() => {
|
|
56069
56091
|
setDiff(void 0);
|
|
56092
|
+
setDiffLoading(false);
|
|
56093
|
+
setMobileDiffOpen(false);
|
|
56070
56094
|
setCollapsed(/* @__PURE__ */ new Set());
|
|
56071
56095
|
setWorkspaceId(void 0);
|
|
56072
|
-
load();
|
|
56096
|
+
load(true);
|
|
56073
56097
|
const timer = globalThis.setInterval(() => {
|
|
56074
56098
|
load();
|
|
56075
|
-
},
|
|
56099
|
+
}, SESSION_CHANGED_FILES_BACKGROUND_REFRESH_MS);
|
|
56076
56100
|
return () => {
|
|
56077
56101
|
requestGeneration.current += 1;
|
|
56102
|
+
inFlightLoad.current = void 0;
|
|
56078
56103
|
globalThis.clearInterval(timer);
|
|
56079
56104
|
};
|
|
56080
56105
|
}, [
|
|
@@ -56096,11 +56121,18 @@ window.__ModuleLoader__.load({
|
|
|
56096
56121
|
(0, react.useEffect)(() => {
|
|
56097
56122
|
if (workspaceId === void 0 || selectedPath === void 0) {
|
|
56098
56123
|
setDiff(void 0);
|
|
56124
|
+
setDiffLoading(false);
|
|
56099
56125
|
return;
|
|
56100
56126
|
}
|
|
56101
56127
|
const selected = changes.find((item) => item.path === selectedPath);
|
|
56102
|
-
if (selected === void 0)
|
|
56128
|
+
if (selected === void 0) {
|
|
56129
|
+
setDiff(void 0);
|
|
56130
|
+
setDiffLoading(false);
|
|
56131
|
+
return;
|
|
56132
|
+
}
|
|
56103
56133
|
let cancelled = false;
|
|
56134
|
+
setDiff(void 0);
|
|
56135
|
+
setDiffLoading(true);
|
|
56104
56136
|
call(props.rpc, "git/diff", {
|
|
56105
56137
|
workspaceId,
|
|
56106
56138
|
path: selected.path,
|
|
@@ -56109,6 +56141,8 @@ window.__ModuleLoader__.load({
|
|
|
56109
56141
|
if (!cancelled) setDiff(value);
|
|
56110
56142
|
}).catch((cause) => {
|
|
56111
56143
|
if (!cancelled) setError(cause instanceof Error ? cause.message : String(cause));
|
|
56144
|
+
}).finally(() => {
|
|
56145
|
+
if (!cancelled) setDiffLoading(false);
|
|
56112
56146
|
});
|
|
56113
56147
|
return () => {
|
|
56114
56148
|
cancelled = true;
|
|
@@ -56119,6 +56153,14 @@ window.__ModuleLoader__.load({
|
|
|
56119
56153
|
selectedPath,
|
|
56120
56154
|
workspaceId
|
|
56121
56155
|
]);
|
|
56156
|
+
(0, react.useEffect)(() => {
|
|
56157
|
+
if (!compactLayout) setMobileDiffOpen(false);
|
|
56158
|
+
if (selectedPath === void 0 || !changes.some((item) => item.path === selectedPath)) setMobileDiffOpen(false);
|
|
56159
|
+
}, [
|
|
56160
|
+
changes,
|
|
56161
|
+
compactLayout,
|
|
56162
|
+
selectedPath
|
|
56163
|
+
]);
|
|
56122
56164
|
const tree = (0, react.useMemo)(() => buildTree(changes), [changes]);
|
|
56123
56165
|
const unstaged = changes.filter((item) => !item.staged);
|
|
56124
56166
|
const stageTargets = async (targets, action) => {
|
|
@@ -56130,7 +56172,7 @@ window.__ModuleLoader__.load({
|
|
|
56130
56172
|
targets
|
|
56131
56173
|
});
|
|
56132
56174
|
notifyGitWorkspaceChanged(workspaceId);
|
|
56133
|
-
await load();
|
|
56175
|
+
await load(true);
|
|
56134
56176
|
} catch (cause) {
|
|
56135
56177
|
setError(cause instanceof Error ? cause.message : String(cause));
|
|
56136
56178
|
} finally {
|
|
@@ -56146,6 +56188,11 @@ window.__ModuleLoader__.load({
|
|
|
56146
56188
|
});
|
|
56147
56189
|
};
|
|
56148
56190
|
const hasChanges = changes.length > 0;
|
|
56191
|
+
const selectedChange = selectedPath === void 0 ? void 0 : changes.find((item) => item.path === selectedPath);
|
|
56192
|
+
const selectPath = (path) => {
|
|
56193
|
+
setSelectedPath(path);
|
|
56194
|
+
if (compactLayout) setMobileDiffOpen(true);
|
|
56195
|
+
};
|
|
56149
56196
|
const viewRootStyle = {
|
|
56150
56197
|
...rootStyle,
|
|
56151
56198
|
padding: compactLayout ? "0 16px" : rootStyle.padding
|
|
@@ -56167,7 +56214,7 @@ window.__ModuleLoader__.load({
|
|
|
56167
56214
|
return (0, react.createElement)("div", { style: viewRootStyle }, (0, react.createElement)("div", { style: viewToolbarStyle }, (0, react.createElement)("strong", { style: { fontSize: 15 } }, t("sessionFiles.title")), (0, react.createElement)("span", { style: countStyle }, t("sessionFiles.count", { count: changes.length })), (0, react.createElement)("span", { style: { flex: 1 } }), (0, react.createElement)("button", {
|
|
56168
56215
|
type: "button",
|
|
56169
56216
|
disabled: loading || busy,
|
|
56170
|
-
onClick: () => void load(),
|
|
56217
|
+
onClick: () => void load(true),
|
|
56171
56218
|
style: toolbarRefreshButtonStyle,
|
|
56172
56219
|
title: t("sessionFiles.refresh"),
|
|
56173
56220
|
"aria-label": t("sessionFiles.refresh")
|
|
@@ -56181,7 +56228,24 @@ window.__ModuleLoader__.load({
|
|
|
56181
56228
|
}, (0, react.createElement)(StageIcon))), error === void 0 ? null : (0, react.createElement)("div", {
|
|
56182
56229
|
role: "alert",
|
|
56183
56230
|
style: errorStyle
|
|
56184
|
-
}, error), (0, react.createElement)("div", { style: viewContentStyle }, (0, react.createElement)("div", { style: viewTreePaneStyle }, loading ? (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.loading")) : changes.length === 0 ? (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.empty")) : tree.map((node) => renderNode(node, 0, collapsed, hoveredPath, selectedPath, toggle,
|
|
56231
|
+
}, error), (0, react.createElement)("div", { style: viewContentStyle }, (0, react.createElement)("div", { style: viewTreePaneStyle }, loading ? (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.loading")) : changes.length === 0 ? (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.empty")) : tree.map((node) => renderNode(node, 0, collapsed, hoveredPath, selectedPath, toggle, selectPath, setHoveredPath, stageTargets, t))), !compactLayout && hasChanges ? (0, react.createElement)("div", { style: diffPaneStyle }, selectedPath === void 0 ? (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.selectFile")) : diffLoading ? (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.loadingDiff")) : diff?.content ? (0, react.createElement)("pre", { style: diffStyle }, renderDiff(diff.content)) : (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.noDiff"))) : null), compactLayout && mobileDiffOpen && selectedPath !== void 0 ? (0, react.createElement)("div", {
|
|
56232
|
+
style: mobileDiffOverlayStyle,
|
|
56233
|
+
onPointerDown: backdropPointerDownHandler(() => setMobileDiffOpen(false))
|
|
56234
|
+
}, (0, react.createElement)("section", {
|
|
56235
|
+
role: "dialog",
|
|
56236
|
+
"aria-modal": true,
|
|
56237
|
+
"aria-label": selectedChange?.path ?? t("sessionFiles.title"),
|
|
56238
|
+
style: mobileDiffModalStyle
|
|
56239
|
+
}, (0, react.createElement)("header", { style: mobileDiffHeaderStyle }, (0, react.createElement)("strong", {
|
|
56240
|
+
style: mobileDiffTitleStyle,
|
|
56241
|
+
title: selectedChange?.path
|
|
56242
|
+
}, selectedChange?.path ?? t("sessionFiles.title")), (0, react.createElement)("button", {
|
|
56243
|
+
type: "button",
|
|
56244
|
+
onClick: () => setMobileDiffOpen(false),
|
|
56245
|
+
style: mobileDiffCloseStyle,
|
|
56246
|
+
title: t("sessionFiles.close"),
|
|
56247
|
+
"aria-label": t("sessionFiles.close")
|
|
56248
|
+
}, "×")), (0, react.createElement)("div", { style: mobileDiffBodyStyle }, diffLoading ? (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.loadingDiff")) : diff?.content ? (0, react.createElement)("pre", { style: diffStyle }, renderDiff(diff.content)) : (0, react.createElement)("div", { style: emptyStyle }, t("sessionFiles.noDiff"))))) : null);
|
|
56185
56249
|
}
|
|
56186
56250
|
/** 注册 DSH 原生 conversation.view Slot;标签由 DSH 根据 Slot 的 id/label 自动投影。 */
|
|
56187
56251
|
function registerSessionChangedFilesView(ctx, rpc, remote, locale) {
|
|
@@ -56264,37 +56328,51 @@ window.__ModuleLoader__.load({
|
|
|
56264
56328
|
(0, react.useEffect)(() => {
|
|
56265
56329
|
let disposed = false;
|
|
56266
56330
|
let generation = 0;
|
|
56331
|
+
let hasSuccessfulLoad = false;
|
|
56332
|
+
let subscribedWorkspaceId;
|
|
56333
|
+
let inFlight;
|
|
56267
56334
|
let disposeWorkspaceSubscription;
|
|
56268
56335
|
const updateWorkspaceSubscription = (workspaceId) => {
|
|
56336
|
+
if (subscribedWorkspaceId === workspaceId) return;
|
|
56269
56337
|
disposeWorkspaceSubscription?.();
|
|
56338
|
+
subscribedWorkspaceId = workspaceId;
|
|
56270
56339
|
disposeWorkspaceSubscription = workspaceId === void 0 ? void 0 : subscribeGitWorkspaceChanged(workspaceId, () => {
|
|
56271
56340
|
load();
|
|
56272
56341
|
});
|
|
56273
56342
|
};
|
|
56274
|
-
const load =
|
|
56343
|
+
const load = () => {
|
|
56344
|
+
if (inFlight !== void 0) return inFlight;
|
|
56275
56345
|
const currentGeneration = ++generation;
|
|
56276
|
-
|
|
56277
|
-
|
|
56278
|
-
|
|
56279
|
-
|
|
56280
|
-
|
|
56281
|
-
|
|
56282
|
-
|
|
56283
|
-
|
|
56284
|
-
|
|
56285
|
-
|
|
56286
|
-
|
|
56287
|
-
|
|
56288
|
-
|
|
56289
|
-
|
|
56346
|
+
const tracked = (async () => {
|
|
56347
|
+
try {
|
|
56348
|
+
const workspaceId = await resolveGitWorkspaceId(props.remote, props.sessionId);
|
|
56349
|
+
if (workspaceId === void 0) throw new Error("当前会话没有可用的工作区");
|
|
56350
|
+
const [sessionFiles, status] = await Promise.all([call(props.rpc, "fileManagement/session-changes", {
|
|
56351
|
+
sessionId: props.sessionId,
|
|
56352
|
+
workspaceId
|
|
56353
|
+
}), call(props.rpc, "git/status", { workspaceId })]);
|
|
56354
|
+
if (disposed || currentGeneration !== generation) return;
|
|
56355
|
+
updateWorkspaceSubscription(workspaceId);
|
|
56356
|
+
const count = selectSessionChangedFiles(sessionFiles, status).length;
|
|
56357
|
+
hasSuccessfulLoad = true;
|
|
56358
|
+
props.reportCount(props.sessionId, count);
|
|
56359
|
+
} catch {
|
|
56360
|
+
if (!disposed && currentGeneration === generation && !hasSuccessfulLoad) props.reportCount(props.sessionId, 0);
|
|
56361
|
+
}
|
|
56362
|
+
})().finally(() => {
|
|
56363
|
+
if (inFlight === tracked) inFlight = void 0;
|
|
56364
|
+
});
|
|
56365
|
+
inFlight = tracked;
|
|
56366
|
+
return tracked;
|
|
56290
56367
|
};
|
|
56291
56368
|
load();
|
|
56292
56369
|
const timer = globalThis.setInterval(() => {
|
|
56293
56370
|
load();
|
|
56294
|
-
},
|
|
56371
|
+
}, SESSION_CHANGED_FILES_BACKGROUND_REFRESH_MS);
|
|
56295
56372
|
return () => {
|
|
56296
56373
|
disposed = true;
|
|
56297
56374
|
generation += 1;
|
|
56375
|
+
inFlight = void 0;
|
|
56298
56376
|
globalThis.clearInterval(timer);
|
|
56299
56377
|
disposeWorkspaceSubscription?.();
|
|
56300
56378
|
};
|
|
@@ -56313,6 +56391,19 @@ window.__ModuleLoader__.load({
|
|
|
56313
56391
|
style: diffLineStyle(line)
|
|
56314
56392
|
}, `${line}${index < lines.length - 1 ? "\n" : ""}`));
|
|
56315
56393
|
}
|
|
56394
|
+
/** 只替换真正变化的行对象,后台刷新时保持未变化文件的引用和交互状态。 */
|
|
56395
|
+
function mergeChangedFiles(current, next) {
|
|
56396
|
+
if (current.length === next.length && current.every((item, index) => sameChange(item, next[index]))) return current;
|
|
56397
|
+
const previous = new Map(current.map((item) => [item.path, item]));
|
|
56398
|
+
return next.map((item) => {
|
|
56399
|
+
const old = previous.get(item.path);
|
|
56400
|
+
return old !== void 0 && sameChange(old, item) ? old : item;
|
|
56401
|
+
});
|
|
56402
|
+
}
|
|
56403
|
+
function sameChange(left, right) {
|
|
56404
|
+
if (left === void 0 || right === void 0) return left === right;
|
|
56405
|
+
return left.path === right.path && left.status === right.status && left.staged === right.staged && left.oldPath === right.oldPath && left.binary === right.binary && left.stagedStatus === right.stagedStatus && left.worktreeStatus === right.worktreeStatus;
|
|
56406
|
+
}
|
|
56316
56407
|
/** 只显示当前 Git 状态中仍属于本会话触及范围的文件。 */
|
|
56317
56408
|
function selectSessionChangedFiles(sessionFiles, status) {
|
|
56318
56409
|
const touched = new Set(sessionFiles.paths.map(normalizePath));
|
|
@@ -56663,6 +56754,66 @@ window.__ModuleLoader__.load({
|
|
|
56663
56754
|
wordBreak: "break-word",
|
|
56664
56755
|
font: "12px/1.55 var(--dsw-font-mono,ui-monospace,monospace)"
|
|
56665
56756
|
};
|
|
56757
|
+
const mobileDiffOverlayStyle = {
|
|
56758
|
+
position: "fixed",
|
|
56759
|
+
inset: 0,
|
|
56760
|
+
zIndex: 1e3,
|
|
56761
|
+
display: "flex",
|
|
56762
|
+
alignItems: "stretch",
|
|
56763
|
+
justifyContent: "center",
|
|
56764
|
+
padding: 10,
|
|
56765
|
+
boxSizing: "border-box",
|
|
56766
|
+
background: "rgba(0,0,0,.48)"
|
|
56767
|
+
};
|
|
56768
|
+
const mobileDiffModalStyle = {
|
|
56769
|
+
display: "flex",
|
|
56770
|
+
flexDirection: "column",
|
|
56771
|
+
width: "100%",
|
|
56772
|
+
maxWidth: 720,
|
|
56773
|
+
maxHeight: "100%",
|
|
56774
|
+
minHeight: 0,
|
|
56775
|
+
overflow: "hidden",
|
|
56776
|
+
borderRadius: 10,
|
|
56777
|
+
background: "var(--dsw-alias-bg-layer-1,#fff)",
|
|
56778
|
+
boxShadow: "0 12px 40px rgba(0,0,0,.3)"
|
|
56779
|
+
};
|
|
56780
|
+
const mobileDiffHeaderStyle = {
|
|
56781
|
+
display: "flex",
|
|
56782
|
+
alignItems: "center",
|
|
56783
|
+
gap: 8,
|
|
56784
|
+
minHeight: 46,
|
|
56785
|
+
padding: "0 12px",
|
|
56786
|
+
borderBottom: "1px solid var(--dsw-alias-border-l3,#ddd)",
|
|
56787
|
+
flex: "0 0 auto"
|
|
56788
|
+
};
|
|
56789
|
+
const mobileDiffTitleStyle = {
|
|
56790
|
+
minWidth: 0,
|
|
56791
|
+
flex: 1,
|
|
56792
|
+
overflow: "hidden",
|
|
56793
|
+
textOverflow: "ellipsis",
|
|
56794
|
+
whiteSpace: "nowrap",
|
|
56795
|
+
fontSize: 13
|
|
56796
|
+
};
|
|
56797
|
+
const mobileDiffCloseStyle = {
|
|
56798
|
+
display: "inline-flex",
|
|
56799
|
+
alignItems: "center",
|
|
56800
|
+
justifyContent: "center",
|
|
56801
|
+
width: 32,
|
|
56802
|
+
height: 32,
|
|
56803
|
+
border: 0,
|
|
56804
|
+
borderRadius: 6,
|
|
56805
|
+
padding: 0,
|
|
56806
|
+
background: "transparent",
|
|
56807
|
+
color: "var(--dsw-alias-label-secondary,#777)",
|
|
56808
|
+
cursor: "pointer",
|
|
56809
|
+
fontSize: 22,
|
|
56810
|
+
lineHeight: 1
|
|
56811
|
+
};
|
|
56812
|
+
const mobileDiffBodyStyle = {
|
|
56813
|
+
minHeight: 0,
|
|
56814
|
+
overflow: "auto",
|
|
56815
|
+
background: "var(--dsw-alias-bg-layer-1,transparent)"
|
|
56816
|
+
};
|
|
56666
56817
|
const diffHeaderLineStyle = {
|
|
56667
56818
|
display: "block",
|
|
56668
56819
|
color: "var(--dsw-alias-label-tertiary,#777)"
|