@openma/deepseek-harness-acp 0.4.21 → 0.4.23-beta.0
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 +12 -10
- package/dist/bin.js +328 -0
- package/dist/bridge.js +13 -1
- package/dist/index.js +127 -64
- package/dist/plugin.js +13 -1
- package/dist/server.js +13 -1
- package/package.json +80 -63
- package/vendor/dsh-runtime.tgz +0 -0
- package/vendor/runtime.json +5 -0
package/README.md
CHANGED
|
@@ -29,14 +29,14 @@ config options, slash commands, skills, and MCP servers. Credentials never
|
|
|
29
29
|
touch your editor config — it reuses the key you saved in the dsh Web UI, or
|
|
30
30
|
`dsh-acp login` saves one to the same store.
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## One package, standalone or plugin
|
|
33
33
|
|
|
34
34
|
| | **A · dsh profile plugin (recommended)** | **B · Standalone server** |
|
|
35
35
|
|---|---|---|
|
|
36
36
|
| Best for | Normal installation and upgrades | Connecting an ACP client without managing a dsh profile |
|
|
37
37
|
| Install | `dsh plugin --profile acp add @openma/deepseek-harness-acp@latest` | `npm i -g @openma/deepseek-harness-acp` |
|
|
38
38
|
| Zed runs | `dsh --profile acp` | `dsh-acp` |
|
|
39
|
-
| Harness | The dsh that owns the profile | Your installed dsh
|
|
39
|
+
| Harness | The dsh that owns the profile | Your installed dsh, then the package's locked private runtime |
|
|
40
40
|
| Composition | dsh-base + this bundle + your profile's own patches | dsh-base + this bundle (profile machinery booted in-process) |
|
|
41
41
|
|
|
42
42
|
Both shapes share `$DSH_HOME`: the same credential store, settings, presets,
|
|
@@ -95,10 +95,11 @@ dsh-acp login # interactive; or save the key in the dsh Web UI
|
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
The standalone binary finds DeepSeek Harness via `--dsh-path` / `DSH_PATH`,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
`./node_modules`, `dsh` on PATH, or `npm root -g`, then falls back to the exact
|
|
99
|
+
runtime archived inside this package. DSH is only a wildcard optional peer for
|
|
100
|
+
Host integration, never an npm-installed dependency: plugin mode uses the
|
|
101
|
+
Host's tree, while standalone maps the same imports to the private runtime.
|
|
102
|
+
When a real `$DSH_HOME/profiles/acp` exists, that profile owns the composition.
|
|
102
103
|
|
|
103
104
|
## Plugin and extension model
|
|
104
105
|
|
|
@@ -216,7 +217,7 @@ another provider.
|
|
|
216
217
|
- **Live model catalog** — providers × models from the running composition (third-party providers added in the Web UI appear immediately), plus reasoning-effort selection that follows your product default.
|
|
217
218
|
- **Slash commands** — adapter built-ins (`/status`, `/model`) plus the harness command registry (`/compact`, `/goal`, `/permission`, `/plan`, …) executed without a model turn, plus **skills** (`/skill-name` — the harness's own invocation gesture). Login and logout are ACP methods, not chat commands.
|
|
218
219
|
- **Plans & usage** — `todo_write` snapshots as ACP plans; token accounting as `usage_update` and per-turn usage.
|
|
219
|
-
- **Sessions** — `session/load` with full history replay, `session/list`, silent restore when a client prompts an old session after an agent restart, titles as `session_info_update`.
|
|
220
|
+
- **Sessions** — `session/load` with full history replay, `session/list`, silent restore when a client prompts an old session after an agent restart, titles as `session_info_update`. Multi-root sessions are not advertised: non-empty `additionalDirectories` on `session/new` or `session/load` return `Invalid params` until [dsh supports multiple workspace roots](https://github.com/deepseek-ai/deepseek-harness/discussions/2474).
|
|
220
221
|
- **MCP servers** — per-session `mcpServers` mount `@deepseek-ai/dsh-mcp-client` instances (stdio + streamable HTTP); tools join as `mcp__<server>__<tool>`; a failing server never takes the session down.
|
|
221
222
|
- **Real cancellation** — `session/cancel` interrupts the live turn through the harness agent.
|
|
222
223
|
|
|
@@ -257,9 +258,10 @@ ACP client (Zed, …)
|
|
|
257
258
|
│ ACP JSON-RPC over stdio
|
|
258
259
|
▼
|
|
259
260
|
dsh-acp
|
|
261
|
+
├─ src/bin.ts selects one DSH tree before Host imports evaluate
|
|
260
262
|
├─ src/profile-boot.ts boots the harness's own profile machinery
|
|
261
263
|
│ (dsh-base + this bundle + $DSH_HOME layers)
|
|
262
|
-
├─ src/harness.ts host discovery (DSH_PATH → cwd → PATH → npm -g →
|
|
264
|
+
├─ src/harness.ts host discovery (DSH_PATH → cwd → PATH → npm -g → bundled runtime)
|
|
263
265
|
└─ src/bridge/ the ACP bridge (a cordis plugin)
|
|
264
266
|
├─ index.ts sessions, prompts, cancel, modes, options,
|
|
265
267
|
│ commands, credentials, MCP mounts
|
|
@@ -267,8 +269,8 @@ dsh-acp
|
|
|
267
269
|
├─ history.ts stored-log replay for session/load (pure)
|
|
268
270
|
└─ prompt.ts ACP prompt blocks → harness content blocks (pure)
|
|
269
271
|
▼
|
|
270
|
-
|
|
271
|
-
|
|
272
|
+
external or package-bundled dsh (agent spine, llm, persistence, sandbox,
|
|
273
|
+
tools, presets, skills, compaction, …)
|
|
272
274
|
```
|
|
273
275
|
|
|
274
276
|
When embedded by another surface, only the transport edge changes:
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/bin.ts
|
|
4
|
+
import { registerHooks } from "node:module";
|
|
5
|
+
|
|
6
|
+
// src/harness.ts
|
|
7
|
+
import { execFileSync } from "node:child_process";
|
|
8
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, realpathSync } from "node:fs";
|
|
9
|
+
import { delimiter, dirname as dirname2, isAbsolute, join as join2, resolve, sep } from "node:path";
|
|
10
|
+
import { pathToFileURL } from "node:url";
|
|
11
|
+
|
|
12
|
+
// src/log.ts
|
|
13
|
+
var PREFIX = "[dsh-acp]";
|
|
14
|
+
function logError(message) {
|
|
15
|
+
process.stderr.write(`${PREFIX} error: ${message}
|
|
16
|
+
`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// src/runtime.ts
|
|
20
|
+
import { createHash } from "node:crypto";
|
|
21
|
+
import {
|
|
22
|
+
existsSync,
|
|
23
|
+
mkdirSync,
|
|
24
|
+
mkdtempSync,
|
|
25
|
+
readFileSync,
|
|
26
|
+
renameSync,
|
|
27
|
+
rmSync,
|
|
28
|
+
writeFileSync
|
|
29
|
+
} from "node:fs";
|
|
30
|
+
import { homedir } from "node:os";
|
|
31
|
+
import { dirname, join } from "node:path";
|
|
32
|
+
import { fileURLToPath } from "node:url";
|
|
33
|
+
import * as tar from "tar";
|
|
34
|
+
function cacheRoot() {
|
|
35
|
+
const explicit = process.env["DSH_ACP_CACHE_DIR"];
|
|
36
|
+
if (explicit !== void 0 && explicit.length > 0) return explicit;
|
|
37
|
+
if (process.platform === "win32") {
|
|
38
|
+
const local = process.env["LOCALAPPDATA"];
|
|
39
|
+
if (local !== void 0 && local.length > 0) return join(local, "dsh-acp");
|
|
40
|
+
}
|
|
41
|
+
const xdg = process.env["XDG_CACHE_HOME"];
|
|
42
|
+
return join(xdg !== void 0 && xdg.length > 0 ? xdg : join(homedir(), ".cache"), "dsh-acp");
|
|
43
|
+
}
|
|
44
|
+
function readMetadata(packageRoot) {
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(readFileSync(join(packageRoot, "vendor/runtime.json"), "utf8"));
|
|
47
|
+
if (typeof parsed.archive !== "string" || typeof parsed.dsh !== "string" || typeof parsed.sha256 !== "string") return void 0;
|
|
48
|
+
return parsed;
|
|
49
|
+
} catch {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function resolveVendoredRuntime() {
|
|
54
|
+
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
55
|
+
const metadata = readMetadata(packageRoot);
|
|
56
|
+
if (metadata === void 0) return void 0;
|
|
57
|
+
const archive = join(packageRoot, "vendor", metadata.archive);
|
|
58
|
+
if (!existsSync(archive)) return void 0;
|
|
59
|
+
const target = join(cacheRoot(), `${metadata.dsh}-${metadata.sha256.slice(0, 12)}`);
|
|
60
|
+
const marker = join(target, ".dsh-acp-runtime");
|
|
61
|
+
if (existsSync(marker)) return target;
|
|
62
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
63
|
+
const actual = createHash("sha256").update(readFileSync(archive)).digest("hex");
|
|
64
|
+
if (actual !== metadata.sha256) throw new Error(`bundled DSH runtime integrity check failed: ${archive}`);
|
|
65
|
+
if (existsSync(target)) rmSync(target, { recursive: true, force: true });
|
|
66
|
+
const temporary = mkdtempSync(join(dirname(target), ".extract-"));
|
|
67
|
+
try {
|
|
68
|
+
tar.x({ cwd: temporary, file: archive, sync: true, strict: true });
|
|
69
|
+
writeFileSync(join(temporary, ".dsh-acp-runtime"), `${metadata.dsh}
|
|
70
|
+
`);
|
|
71
|
+
try {
|
|
72
|
+
renameSync(temporary, target);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (!existsSync(marker)) throw error;
|
|
75
|
+
}
|
|
76
|
+
} finally {
|
|
77
|
+
if (existsSync(temporary)) rmSync(temporary, { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
return target;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/harness.ts
|
|
83
|
+
var HarnessNotFoundError = class extends Error {
|
|
84
|
+
constructor(probed) {
|
|
85
|
+
super(
|
|
86
|
+
[
|
|
87
|
+
"could not find a DeepSeek Harness installation.",
|
|
88
|
+
"",
|
|
89
|
+
"The bundled DeepSeek Harness runtime is missing or invalid.",
|
|
90
|
+
"Reinstall @openma/deepseek-harness-acp, or point it at an existing installation:",
|
|
91
|
+
" DSH_PATH=/path/to/dsh dsh-acp (dsh binary, package dir, or npm root)",
|
|
92
|
+
"",
|
|
93
|
+
probed.length > 0 ? `Probed:
|
|
94
|
+
${probed.map((p) => ` ${p}`).join("\n")}` : ""
|
|
95
|
+
].join("\n").trimEnd()
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
var ANCHOR = "@deepseek-ai/dsh-agent";
|
|
100
|
+
var PROFILE_LAUNCHER = "@deepseek-ai/dsh";
|
|
101
|
+
function packageDirFrom(base, name) {
|
|
102
|
+
let dir = resolve(base);
|
|
103
|
+
for (; ; ) {
|
|
104
|
+
const candidate = join2(dir, "node_modules", ...name.split("/"));
|
|
105
|
+
if (existsSync2(join2(candidate, "package.json"))) return candidate;
|
|
106
|
+
const direct = join2(dir, ...name.split("/"));
|
|
107
|
+
if (dir.endsWith(`${sep}node_modules`) && existsSync2(join2(direct, "package.json"))) return direct;
|
|
108
|
+
const parent = dirname2(dir);
|
|
109
|
+
if (parent === dir) return void 0;
|
|
110
|
+
dir = parent;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function versionOf(packageDir) {
|
|
114
|
+
try {
|
|
115
|
+
const parsed = JSON.parse(readFileSync2(join2(packageDir, "package.json"), "utf8"));
|
|
116
|
+
return typeof parsed.version === "string" ? parsed.version : void 0;
|
|
117
|
+
} catch {
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function hostAt(base, source) {
|
|
122
|
+
const anchor = packageDirFrom(base, ANCHOR);
|
|
123
|
+
const launcher = packageDirFrom(base, PROFILE_LAUNCHER);
|
|
124
|
+
if (anchor === void 0 || launcher === void 0) return void 0;
|
|
125
|
+
return { base: resolve(base), version: versionOf(anchor), source };
|
|
126
|
+
}
|
|
127
|
+
function hostFromExplicit(explicit) {
|
|
128
|
+
const path = resolve(explicit);
|
|
129
|
+
const bases = [];
|
|
130
|
+
let stat;
|
|
131
|
+
try {
|
|
132
|
+
stat = realpathSync(path) !== void 0 && existsSync2(join2(path, ".")) ? "dir" : "file";
|
|
133
|
+
} catch {
|
|
134
|
+
stat = void 0;
|
|
135
|
+
}
|
|
136
|
+
if (existsSync2(path)) {
|
|
137
|
+
try {
|
|
138
|
+
const real = realpathSync(path);
|
|
139
|
+
stat = real === path && existsSync2(join2(path, "package.json")) ? "dir" : stat;
|
|
140
|
+
bases.push(dirname2(real));
|
|
141
|
+
} catch {
|
|
142
|
+
bases.push(dirname2(path));
|
|
143
|
+
}
|
|
144
|
+
bases.push(path, join2(path, "node_modules"), join2(path, "lib", "node_modules"));
|
|
145
|
+
}
|
|
146
|
+
for (const base of bases) {
|
|
147
|
+
const host = hostAt(base, `--dsh-path/DSH_PATH (${explicit})`);
|
|
148
|
+
if (host !== void 0) return host;
|
|
149
|
+
}
|
|
150
|
+
return void 0;
|
|
151
|
+
}
|
|
152
|
+
function hostFromPathLookup() {
|
|
153
|
+
const pathEnv = process.env["PATH"] ?? "";
|
|
154
|
+
for (const dir of pathEnv.split(delimiter)) {
|
|
155
|
+
if (dir.length === 0) continue;
|
|
156
|
+
const candidate = join2(dir, "dsh");
|
|
157
|
+
if (!existsSync2(candidate)) continue;
|
|
158
|
+
try {
|
|
159
|
+
const real = realpathSync(candidate);
|
|
160
|
+
const host = hostAt(dirname2(real), `dsh on PATH (${candidate})`);
|
|
161
|
+
if (host !== void 0) return host;
|
|
162
|
+
} catch {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return void 0;
|
|
167
|
+
}
|
|
168
|
+
function hostFromGlobalNpm() {
|
|
169
|
+
try {
|
|
170
|
+
const root = execFileSync("npm", ["root", "-g"], { encoding: "utf8", timeout: 1e4 }).trim();
|
|
171
|
+
if (root.length > 0 && isAbsolute(root)) return hostAt(root, `npm root -g (${root})`);
|
|
172
|
+
} catch {
|
|
173
|
+
}
|
|
174
|
+
return void 0;
|
|
175
|
+
}
|
|
176
|
+
function resolveHost(explicit) {
|
|
177
|
+
const probed = [];
|
|
178
|
+
if (explicit !== void 0) {
|
|
179
|
+
const host = hostFromExplicit(explicit);
|
|
180
|
+
if (host !== void 0) return host;
|
|
181
|
+
probed.push(`--dsh-path/DSH_PATH: ${explicit}`);
|
|
182
|
+
throw new HarnessNotFoundError(probed);
|
|
183
|
+
}
|
|
184
|
+
const local = hostAt(process.cwd(), `invoking directory (${process.cwd()})`);
|
|
185
|
+
if (local !== void 0) return local;
|
|
186
|
+
probed.push(`invoking directory: ${process.cwd()}`);
|
|
187
|
+
const onPath = hostFromPathLookup();
|
|
188
|
+
if (onPath !== void 0) return onPath;
|
|
189
|
+
probed.push("dsh on PATH");
|
|
190
|
+
const globalNpm = hostFromGlobalNpm();
|
|
191
|
+
if (globalNpm !== void 0) return globalNpm;
|
|
192
|
+
probed.push("npm root -g");
|
|
193
|
+
const vendored = resolveVendoredRuntime();
|
|
194
|
+
if (vendored !== void 0) {
|
|
195
|
+
const host = hostAt(vendored, "bundled standalone runtime");
|
|
196
|
+
if (host !== void 0) return host;
|
|
197
|
+
}
|
|
198
|
+
probed.push("bundled standalone runtime");
|
|
199
|
+
throw new HarnessNotFoundError(probed);
|
|
200
|
+
}
|
|
201
|
+
function entryFile(packageDir, subpath) {
|
|
202
|
+
const manifest = JSON.parse(readFileSync2(join2(packageDir, "package.json"), "utf8"));
|
|
203
|
+
const key = subpath === void 0 ? "." : `./${subpath}`;
|
|
204
|
+
const exportsMap = manifest.exports;
|
|
205
|
+
let target;
|
|
206
|
+
if (typeof exportsMap === "string") {
|
|
207
|
+
if (key === ".") target = exportsMap;
|
|
208
|
+
} else if (exportsMap !== null && typeof exportsMap === "object") {
|
|
209
|
+
const entry = exportsMap[key];
|
|
210
|
+
target = entry;
|
|
211
|
+
}
|
|
212
|
+
if (target !== null && typeof target === "object") {
|
|
213
|
+
const conditions = target;
|
|
214
|
+
target = conditions["import"] ?? conditions["default"] ?? conditions["node"];
|
|
215
|
+
if (target !== null && typeof target === "object") {
|
|
216
|
+
const nested = target;
|
|
217
|
+
target = nested["default"] ?? nested["import"];
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (typeof target !== "string" && key === "." && typeof manifest.main === "string") {
|
|
221
|
+
target = manifest.main;
|
|
222
|
+
}
|
|
223
|
+
if (typeof target !== "string") {
|
|
224
|
+
throw new Error(`cannot resolve entry ${key} of ${packageDir}`);
|
|
225
|
+
}
|
|
226
|
+
return join2(packageDir, target);
|
|
227
|
+
}
|
|
228
|
+
function hostModuleUrl(host, specifier) {
|
|
229
|
+
const [scope, packageName, ...rest] = specifier.split("/");
|
|
230
|
+
if (scope === void 0 || packageName === void 0) throw new Error(`invalid specifier: ${specifier}`);
|
|
231
|
+
const name = `${scope}/${packageName}`;
|
|
232
|
+
const packageDir = packageDirFrom(host.base, name);
|
|
233
|
+
if (packageDir === void 0) {
|
|
234
|
+
throw new Error(
|
|
235
|
+
`the DeepSeek Harness installation at ${host.base} (${host.source}) does not provide ${name}`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
if (rest.length === 1 && rest[0] === "package.json") {
|
|
239
|
+
return pathToFileURL(join2(packageDir, "package.json")).href;
|
|
240
|
+
}
|
|
241
|
+
return pathToFileURL(entryFile(packageDir, rest.length > 0 ? rest.join("/") : void 0)).href;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/settings.ts
|
|
245
|
+
var HELP_TEXT = `Usage: dsh-acp [options]
|
|
246
|
+
dsh-acp login [--provider <route>] [api-key]
|
|
247
|
+
Save a provider API key (interactive when omitted)
|
|
248
|
+
dsh-acp update Self-update via npm
|
|
249
|
+
|
|
250
|
+
Agent Client Protocol (ACP) stdio server for DeepSeek Harness. Speak ACP on
|
|
251
|
+
stdin/stdout from an ACP client such as Zed; diagnostics go to stderr.
|
|
252
|
+
|
|
253
|
+
Options:
|
|
254
|
+
--dsh-path <path> DeepSeek Harness installation: the dsh binary, its
|
|
255
|
+
package dir, or any dir carrying node_modules/@deepseek-ai
|
|
256
|
+
(DSH_PATH; auto-detected when unset \u2014 own tree, ./node_modules,
|
|
257
|
+
dsh on PATH, npm root -g)
|
|
258
|
+
--bundle <package-dir> Add a dsh bundle layer to the agent tree (repeatable)
|
|
259
|
+
--provider <route> Provider route (DSH_PROVIDER, default deepseek-official)
|
|
260
|
+
--model <id> Default model (DSH_MODEL, default deepseek-v4-flash)
|
|
261
|
+
--models <a,b,...> Selectable models for the session "Model" option
|
|
262
|
+
(DSH_ACP_MODELS, default deepseek-v4-flash,deepseek-v4-pro)
|
|
263
|
+
--max-tokens <n> Per-request output-token cap (DSH_MAX_TOKENS)
|
|
264
|
+
--permission-mode <mode> read-only | workspace-write | danger-full-access
|
|
265
|
+
(DSH_PERMISSION_MODE; otherwise use the Host default)
|
|
266
|
+
--session-root <dir> JSONL session store (DSH_SESSION_ROOT, default ~/.dsh-acp/sessions)
|
|
267
|
+
--persona <text> System-prompt persona (DSH_SYSTEM_PROMPT)
|
|
268
|
+
--reasoning-effort <level> off | high | max (DSH_REASONING_EFFORT, default high)
|
|
269
|
+
--no-thinking Disable model thinking output
|
|
270
|
+
--bash-timeout <ms> Foreground bash timeout (DSH_BASH_TIMEOUT_MS, default 60000)
|
|
271
|
+
--version Print version and exit
|
|
272
|
+
--help Show this help
|
|
273
|
+
|
|
274
|
+
Environment:
|
|
275
|
+
DSH_PATH DeepSeek Harness installation (see --dsh-path)
|
|
276
|
+
DEEPSEEK_API_KEY DeepSeek (or compatible) API credential
|
|
277
|
+
DEEPSEEK_BASE_URL OpenAI-compatible endpoint override
|
|
278
|
+
DSH_ACP_DEBUG Verbose stderr diagnostics
|
|
279
|
+
`;
|
|
280
|
+
|
|
281
|
+
// src/version.ts
|
|
282
|
+
import { createRequire } from "node:module";
|
|
283
|
+
var VERSION = createRequire(import.meta.url)("../package.json").version;
|
|
284
|
+
|
|
285
|
+
// src/bin.ts
|
|
286
|
+
var NAME = "@openma/deepseek-harness-acp";
|
|
287
|
+
function explicitDshPath(argv) {
|
|
288
|
+
const index = argv.indexOf("--dsh-path");
|
|
289
|
+
if (index >= 0) return argv[index + 1];
|
|
290
|
+
const env = process.env["DSH_PATH"];
|
|
291
|
+
return env !== void 0 && env.length > 0 ? env : void 0;
|
|
292
|
+
}
|
|
293
|
+
async function bootstrap() {
|
|
294
|
+
const argv = process.argv.slice(2);
|
|
295
|
+
if (argv.includes("--version")) {
|
|
296
|
+
console.log(`${NAME} ${VERSION}`);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (argv.includes("--help")) {
|
|
300
|
+
console.log(HELP_TEXT.trimEnd());
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
let host;
|
|
304
|
+
try {
|
|
305
|
+
host = resolveHost(explicitDshPath(argv));
|
|
306
|
+
} catch (error) {
|
|
307
|
+
if (error instanceof HarnessNotFoundError) {
|
|
308
|
+
logError(error.message);
|
|
309
|
+
process.exitCode = 1;
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
throw error;
|
|
313
|
+
}
|
|
314
|
+
registerHooks({
|
|
315
|
+
resolve(specifier, context, nextResolve) {
|
|
316
|
+
if (specifier === "@deepseek-ai/cordis" || specifier.startsWith("@deepseek-ai/")) {
|
|
317
|
+
return { shortCircuit: true, url: hostModuleUrl(host, specifier) };
|
|
318
|
+
}
|
|
319
|
+
return nextResolve(specifier, context);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
const cli = import.meta.url.endsWith(".ts") ? "./index.ts" : "./index.js";
|
|
323
|
+
await import(cli);
|
|
324
|
+
}
|
|
325
|
+
bootstrap().catch((error) => {
|
|
326
|
+
logError(error instanceof Error ? error.stack ?? error.message : String(error));
|
|
327
|
+
process.exit(1);
|
|
328
|
+
});
|
package/dist/bridge.js
CHANGED
|
@@ -54,6 +54,7 @@ __export(bridge_exports, {
|
|
|
54
54
|
answerFromElicitation: () => answerFromElicitation,
|
|
55
55
|
apply: () => apply3,
|
|
56
56
|
askUserQuestionsOverAcp: () => askUserQuestionsOverAcp,
|
|
57
|
+
createElicitation: () => createElicitation,
|
|
57
58
|
inject: () => inject3,
|
|
58
59
|
installAcpUserQuestionProvider: () => installAcpUserQuestionProvider,
|
|
59
60
|
name: () => name3,
|
|
@@ -1593,6 +1594,7 @@ function apply(ctx, config) {
|
|
|
1593
1594
|
var user_questions_plugin_exports = {};
|
|
1594
1595
|
__export(user_questions_plugin_exports, {
|
|
1595
1596
|
apply: () => apply2,
|
|
1597
|
+
createElicitation: () => createElicitation,
|
|
1596
1598
|
inject: () => inject2,
|
|
1597
1599
|
name: () => name2
|
|
1598
1600
|
});
|
|
@@ -1725,6 +1727,9 @@ async function askUserQuestionsOverAcp(request, sessionId, create) {
|
|
|
1725
1727
|
}
|
|
1726
1728
|
return answer;
|
|
1727
1729
|
}
|
|
1730
|
+
function createElicitation(connection, request) {
|
|
1731
|
+
return connection.createElicitation(request);
|
|
1732
|
+
}
|
|
1728
1733
|
var ROUTERS_KEY = /* @__PURE__ */ Symbol.for("@openma/deepseek-harness-acp/user-question-routers");
|
|
1729
1734
|
var routers = globalThis[ROUTERS_KEY] ??= /* @__PURE__ */ new WeakMap();
|
|
1730
1735
|
function installAcpUserQuestionProvider(service, options) {
|
|
@@ -2878,6 +2883,7 @@ async function apply3(ctx, config = {}) {
|
|
|
2878
2883
|
await requireCredential(config.provider);
|
|
2879
2884
|
mark("credential");
|
|
2880
2885
|
validateCwd(params.cwd);
|
|
2886
|
+
validateAdditionalDirectories(params.additionalDirectories);
|
|
2881
2887
|
syncMcpServers(params.mcpServers, params.cwd);
|
|
2882
2888
|
mark("request setup");
|
|
2883
2889
|
const sessionId = SessionId2(randomUUID());
|
|
@@ -2922,6 +2928,7 @@ async function apply3(ctx, config = {}) {
|
|
|
2922
2928
|
assertOpen();
|
|
2923
2929
|
await requireCredential(config.provider);
|
|
2924
2930
|
validateCwd(params.cwd);
|
|
2931
|
+
validateAdditionalDirectories(params.additionalDirectories);
|
|
2925
2932
|
syncMcpServers(params.mcpServers, params.cwd);
|
|
2926
2933
|
requirePersistence();
|
|
2927
2934
|
const record = await restoreSession(params.sessionId, { replay: true, cwd: params.cwd });
|
|
@@ -3165,6 +3172,11 @@ async function apply3(ctx, config = {}) {
|
|
|
3165
3172
|
function validateCwd(cwd) {
|
|
3166
3173
|
if (!isAbsolute(cwd)) throw invalidParams(`cwd must be an absolute path: ${cwd}`);
|
|
3167
3174
|
}
|
|
3175
|
+
function validateAdditionalDirectories(additionalDirectories) {
|
|
3176
|
+
if (additionalDirectories !== void 0 && additionalDirectories.length > 0) {
|
|
3177
|
+
throw invalidParams("additionalDirectories is not supported");
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3168
3180
|
const mcpMounts = /* @__PURE__ */ new Map();
|
|
3169
3181
|
let warnedNoMcpClient = false;
|
|
3170
3182
|
const sanitizeServerName = (raw2) => {
|
|
@@ -3262,7 +3274,7 @@ async function apply3(ctx, config = {}) {
|
|
|
3262
3274
|
const record = ownedRecord(request.agent);
|
|
3263
3275
|
return record === void 0 ? void 0 : String(record.agent.session.id);
|
|
3264
3276
|
},
|
|
3265
|
-
create: (request) => conn
|
|
3277
|
+
create: (request) => createElicitation(conn, request)
|
|
3266
3278
|
});
|
|
3267
3279
|
let quiescing;
|
|
3268
3280
|
const quiesce = () => {
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,8 @@ import { spawnSync } from "node:child_process";
|
|
|
5
5
|
|
|
6
6
|
// src/harness.ts
|
|
7
7
|
import { execFileSync } from "node:child_process";
|
|
8
|
-
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
9
|
-
import { delimiter, dirname, isAbsolute, join, resolve, sep } from "node:path";
|
|
10
|
-
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
8
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, realpathSync } from "node:fs";
|
|
9
|
+
import { delimiter, dirname as dirname2, isAbsolute, join as join2, resolve, sep } from "node:path";
|
|
11
10
|
|
|
12
11
|
// src/log.ts
|
|
13
12
|
var PREFIX = "[dsh-acp]";
|
|
@@ -24,6 +23,69 @@ function logInfo(message) {
|
|
|
24
23
|
`);
|
|
25
24
|
}
|
|
26
25
|
|
|
26
|
+
// src/runtime.ts
|
|
27
|
+
import { createHash } from "node:crypto";
|
|
28
|
+
import {
|
|
29
|
+
existsSync,
|
|
30
|
+
mkdirSync,
|
|
31
|
+
mkdtempSync,
|
|
32
|
+
readFileSync,
|
|
33
|
+
renameSync,
|
|
34
|
+
rmSync,
|
|
35
|
+
writeFileSync
|
|
36
|
+
} from "node:fs";
|
|
37
|
+
import { homedir } from "node:os";
|
|
38
|
+
import { dirname, join } from "node:path";
|
|
39
|
+
import { fileURLToPath } from "node:url";
|
|
40
|
+
import * as tar from "tar";
|
|
41
|
+
function cacheRoot() {
|
|
42
|
+
const explicit = process.env["DSH_ACP_CACHE_DIR"];
|
|
43
|
+
if (explicit !== void 0 && explicit.length > 0) return explicit;
|
|
44
|
+
if (process.platform === "win32") {
|
|
45
|
+
const local = process.env["LOCALAPPDATA"];
|
|
46
|
+
if (local !== void 0 && local.length > 0) return join(local, "dsh-acp");
|
|
47
|
+
}
|
|
48
|
+
const xdg = process.env["XDG_CACHE_HOME"];
|
|
49
|
+
return join(xdg !== void 0 && xdg.length > 0 ? xdg : join(homedir(), ".cache"), "dsh-acp");
|
|
50
|
+
}
|
|
51
|
+
function readMetadata(packageRoot) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(readFileSync(join(packageRoot, "vendor/runtime.json"), "utf8"));
|
|
54
|
+
if (typeof parsed.archive !== "string" || typeof parsed.dsh !== "string" || typeof parsed.sha256 !== "string") return void 0;
|
|
55
|
+
return parsed;
|
|
56
|
+
} catch {
|
|
57
|
+
return void 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function resolveVendoredRuntime() {
|
|
61
|
+
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
62
|
+
const metadata = readMetadata(packageRoot);
|
|
63
|
+
if (metadata === void 0) return void 0;
|
|
64
|
+
const archive = join(packageRoot, "vendor", metadata.archive);
|
|
65
|
+
if (!existsSync(archive)) return void 0;
|
|
66
|
+
const target = join(cacheRoot(), `${metadata.dsh}-${metadata.sha256.slice(0, 12)}`);
|
|
67
|
+
const marker = join(target, ".dsh-acp-runtime");
|
|
68
|
+
if (existsSync(marker)) return target;
|
|
69
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
70
|
+
const actual = createHash("sha256").update(readFileSync(archive)).digest("hex");
|
|
71
|
+
if (actual !== metadata.sha256) throw new Error(`bundled DSH runtime integrity check failed: ${archive}`);
|
|
72
|
+
if (existsSync(target)) rmSync(target, { recursive: true, force: true });
|
|
73
|
+
const temporary = mkdtempSync(join(dirname(target), ".extract-"));
|
|
74
|
+
try {
|
|
75
|
+
tar.x({ cwd: temporary, file: archive, sync: true, strict: true });
|
|
76
|
+
writeFileSync(join(temporary, ".dsh-acp-runtime"), `${metadata.dsh}
|
|
77
|
+
`);
|
|
78
|
+
try {
|
|
79
|
+
renameSync(temporary, target);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (!existsSync(marker)) throw error;
|
|
82
|
+
}
|
|
83
|
+
} finally {
|
|
84
|
+
if (existsSync(temporary)) rmSync(temporary, { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
return target;
|
|
87
|
+
}
|
|
88
|
+
|
|
27
89
|
// src/harness.ts
|
|
28
90
|
var HarnessNotFoundError = class extends Error {
|
|
29
91
|
constructor(probed) {
|
|
@@ -31,10 +93,8 @@ var HarnessNotFoundError = class extends Error {
|
|
|
31
93
|
[
|
|
32
94
|
"could not find a DeepSeek Harness installation.",
|
|
33
95
|
"",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"",
|
|
37
|
-
"or point dsh-acp at an existing installation:",
|
|
96
|
+
"The bundled DeepSeek Harness runtime is missing or invalid.",
|
|
97
|
+
"Reinstall @openma/deepseek-harness-acp, or point it at an existing installation:",
|
|
38
98
|
" DSH_PATH=/path/to/dsh dsh-acp (dsh binary, package dir, or npm root)",
|
|
39
99
|
"",
|
|
40
100
|
probed.length > 0 ? `Probed:
|
|
@@ -48,18 +108,18 @@ var PROFILE_LAUNCHER = "@deepseek-ai/dsh";
|
|
|
48
108
|
function packageDirFrom(base, name) {
|
|
49
109
|
let dir = resolve(base);
|
|
50
110
|
for (; ; ) {
|
|
51
|
-
const candidate =
|
|
52
|
-
if (
|
|
53
|
-
const direct =
|
|
54
|
-
if (dir.endsWith(`${sep}node_modules`) &&
|
|
55
|
-
const parent =
|
|
111
|
+
const candidate = join2(dir, "node_modules", ...name.split("/"));
|
|
112
|
+
if (existsSync2(join2(candidate, "package.json"))) return candidate;
|
|
113
|
+
const direct = join2(dir, ...name.split("/"));
|
|
114
|
+
if (dir.endsWith(`${sep}node_modules`) && existsSync2(join2(direct, "package.json"))) return direct;
|
|
115
|
+
const parent = dirname2(dir);
|
|
56
116
|
if (parent === dir) return void 0;
|
|
57
117
|
dir = parent;
|
|
58
118
|
}
|
|
59
119
|
}
|
|
60
120
|
function versionOf(packageDir) {
|
|
61
121
|
try {
|
|
62
|
-
const parsed = JSON.parse(
|
|
122
|
+
const parsed = JSON.parse(readFileSync2(join2(packageDir, "package.json"), "utf8"));
|
|
63
123
|
return typeof parsed.version === "string" ? parsed.version : void 0;
|
|
64
124
|
} catch {
|
|
65
125
|
return void 0;
|
|
@@ -76,19 +136,19 @@ function hostFromExplicit(explicit) {
|
|
|
76
136
|
const bases = [];
|
|
77
137
|
let stat;
|
|
78
138
|
try {
|
|
79
|
-
stat = realpathSync(path) !== void 0 &&
|
|
139
|
+
stat = realpathSync(path) !== void 0 && existsSync2(join2(path, ".")) ? "dir" : "file";
|
|
80
140
|
} catch {
|
|
81
141
|
stat = void 0;
|
|
82
142
|
}
|
|
83
|
-
if (
|
|
143
|
+
if (existsSync2(path)) {
|
|
84
144
|
try {
|
|
85
145
|
const real = realpathSync(path);
|
|
86
|
-
stat = real === path &&
|
|
87
|
-
bases.push(
|
|
146
|
+
stat = real === path && existsSync2(join2(path, "package.json")) ? "dir" : stat;
|
|
147
|
+
bases.push(dirname2(real));
|
|
88
148
|
} catch {
|
|
89
|
-
bases.push(
|
|
149
|
+
bases.push(dirname2(path));
|
|
90
150
|
}
|
|
91
|
-
bases.push(path,
|
|
151
|
+
bases.push(path, join2(path, "node_modules"), join2(path, "lib", "node_modules"));
|
|
92
152
|
}
|
|
93
153
|
for (const base of bases) {
|
|
94
154
|
const host = hostAt(base, `--dsh-path/DSH_PATH (${explicit})`);
|
|
@@ -100,11 +160,11 @@ function hostFromPathLookup() {
|
|
|
100
160
|
const pathEnv = process.env["PATH"] ?? "";
|
|
101
161
|
for (const dir of pathEnv.split(delimiter)) {
|
|
102
162
|
if (dir.length === 0) continue;
|
|
103
|
-
const candidate =
|
|
104
|
-
if (!
|
|
163
|
+
const candidate = join2(dir, "dsh");
|
|
164
|
+
if (!existsSync2(candidate)) continue;
|
|
105
165
|
try {
|
|
106
166
|
const real = realpathSync(candidate);
|
|
107
|
-
const host = hostAt(
|
|
167
|
+
const host = hostAt(dirname2(real), `dsh on PATH (${candidate})`);
|
|
108
168
|
if (host !== void 0) return host;
|
|
109
169
|
} catch {
|
|
110
170
|
continue;
|
|
@@ -137,20 +197,23 @@ function resolveHost(explicit) {
|
|
|
137
197
|
const globalNpm = hostFromGlobalNpm();
|
|
138
198
|
if (globalNpm !== void 0) return globalNpm;
|
|
139
199
|
probed.push("npm root -g");
|
|
140
|
-
const
|
|
141
|
-
if (
|
|
142
|
-
|
|
200
|
+
const vendored = resolveVendoredRuntime();
|
|
201
|
+
if (vendored !== void 0) {
|
|
202
|
+
const host = hostAt(vendored, "bundled standalone runtime");
|
|
203
|
+
if (host !== void 0) return host;
|
|
204
|
+
}
|
|
205
|
+
probed.push("bundled standalone runtime");
|
|
143
206
|
throw new HarnessNotFoundError(probed);
|
|
144
207
|
}
|
|
145
208
|
|
|
146
209
|
// src/profile-boot.ts
|
|
147
|
-
import { existsSync as
|
|
210
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
148
211
|
import { createRequire } from "node:module";
|
|
149
|
-
import { dirname as
|
|
150
|
-
import { pathToFileURL
|
|
212
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3, resolve as resolve2, sep as sep2 } from "node:path";
|
|
213
|
+
import { pathToFileURL } from "node:url";
|
|
151
214
|
var BIN = "dsh-acp";
|
|
152
215
|
function ownRoot() {
|
|
153
|
-
return
|
|
216
|
+
return dirname3(createRequire(import.meta.url).resolve("../package.json"));
|
|
154
217
|
}
|
|
155
218
|
var OWN_BRIDGE_SPECIFIER = "@openma/deepseek-harness-acp/bridge";
|
|
156
219
|
var OWN_SERVER_SPECIFIER = "@openma/deepseek-harness-acp/server";
|
|
@@ -171,19 +234,19 @@ function rewriteOwnRows(row, entries) {
|
|
|
171
234
|
}
|
|
172
235
|
}
|
|
173
236
|
function bundlePatchPath(packageJsonPath) {
|
|
174
|
-
const pkg = JSON.parse(
|
|
237
|
+
const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
|
|
175
238
|
const declared = pkg.dsh?.bundle?.patch;
|
|
176
239
|
if (declared === void 0) {
|
|
177
240
|
throw new Error(`${BIN}: bundle ${pkg.name ?? packageJsonPath} declares no dsh.bundle in its package.json`);
|
|
178
241
|
}
|
|
179
|
-
return
|
|
242
|
+
return join3(dirname3(packageJsonPath), declared);
|
|
180
243
|
}
|
|
181
244
|
function resolveBundlePackageJson(specifier) {
|
|
182
245
|
const candidate = resolve2(specifier);
|
|
183
|
-
if (
|
|
184
|
-
return candidate.endsWith("package.json") ? candidate :
|
|
246
|
+
if (existsSync3(candidate)) {
|
|
247
|
+
return candidate.endsWith("package.json") ? candidate : join3(candidate, "package.json");
|
|
185
248
|
}
|
|
186
|
-
const req = createRequire(
|
|
249
|
+
const req = createRequire(join3(process.cwd(), "noop.js"));
|
|
187
250
|
try {
|
|
188
251
|
return req.resolve(`${specifier}/package.json`);
|
|
189
252
|
} catch (cause) {
|
|
@@ -198,8 +261,8 @@ function rewriteBundleRows(row, packageJsonPath, manifest) {
|
|
|
198
261
|
row["name"] = req.resolve(name);
|
|
199
262
|
} catch (cause) {
|
|
200
263
|
if (name === manifest.name && manifest.main !== void 0) {
|
|
201
|
-
const entry = resolve2(
|
|
202
|
-
if (
|
|
264
|
+
const entry = resolve2(dirname3(packageJsonPath), manifest.main);
|
|
265
|
+
if (existsSync3(entry)) row["name"] = entry;
|
|
203
266
|
else throw new Error(`${BIN}: bundle entry does not exist: ${entry}`, { cause });
|
|
204
267
|
} else {
|
|
205
268
|
throw new Error(
|
|
@@ -220,45 +283,45 @@ function rewriteBundleRows(row, packageJsonPath, manifest) {
|
|
|
220
283
|
}
|
|
221
284
|
function loadBundleLayer(appBoot, specifier) {
|
|
222
285
|
const packageJsonPath = resolveBundlePackageJson(specifier);
|
|
223
|
-
const manifest = JSON.parse(
|
|
286
|
+
const manifest = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
|
|
224
287
|
const patches = appBoot.loadOverlayPatches(BIN, bundlePatchPath(packageJsonPath));
|
|
225
288
|
for (const row of patches) rewriteBundleRows(row, packageJsonPath, manifest);
|
|
226
289
|
return patches;
|
|
227
290
|
}
|
|
228
291
|
async function bootAcpProfile(host, overrides) {
|
|
229
|
-
const req = createRequire(
|
|
292
|
+
const req = createRequire(join3(host.base, "noop.js"));
|
|
230
293
|
const dshPkgPath = req.resolve("@deepseek-ai/dsh/package.json");
|
|
231
|
-
const dshDir =
|
|
232
|
-
const appBoot = await import(
|
|
233
|
-
const homePaths = await import(
|
|
294
|
+
const dshDir = dirname3(dshPkgPath);
|
|
295
|
+
const appBoot = await import(pathToFileURL(req.resolve("@deepseek-ai/dsh-app-boot")).href);
|
|
296
|
+
const homePaths = await import(pathToFileURL(req.resolve("@deepseek-ai/dsh-home-paths")).href);
|
|
234
297
|
const home = homePaths.resolveDshHome();
|
|
235
298
|
let bundlePatches;
|
|
236
299
|
let profilePatches = [];
|
|
237
300
|
let profilePatchPath;
|
|
238
|
-
let rootConfigPath =
|
|
239
|
-
let bareModuleBaseUrl =
|
|
240
|
-
const distBridge =
|
|
241
|
-
const bridgeEntry = import.meta.url.endsWith(".ts") || !
|
|
242
|
-
const distServer =
|
|
243
|
-
const serverEntry = import.meta.url.endsWith(".ts") || !
|
|
244
|
-
const distPlugin =
|
|
245
|
-
const pluginEntry = import.meta.url.endsWith(".ts") || !
|
|
246
|
-
const distStdio =
|
|
247
|
-
const stdioEntry = import.meta.url.endsWith(".ts") || !
|
|
248
|
-
const realProfileDir =
|
|
249
|
-
if (
|
|
301
|
+
let rootConfigPath = join3(ownRoot(), "profile-root.cordis.yml");
|
|
302
|
+
let bareModuleBaseUrl = pathToFileURL(dshDir + sep2).href;
|
|
303
|
+
const distBridge = join3(ownRoot(), "dist", "bridge.js");
|
|
304
|
+
const bridgeEntry = import.meta.url.endsWith(".ts") || !existsSync3(distBridge) ? join3(ownRoot(), "src", "bundle.ts") : distBridge;
|
|
305
|
+
const distServer = join3(ownRoot(), "dist", "server.js");
|
|
306
|
+
const serverEntry = import.meta.url.endsWith(".ts") || !existsSync3(distServer) ? join3(ownRoot(), "src", "server.ts") : distServer;
|
|
307
|
+
const distPlugin = join3(ownRoot(), "dist", "plugin.js");
|
|
308
|
+
const pluginEntry = import.meta.url.endsWith(".ts") || !existsSync3(distPlugin) ? join3(ownRoot(), "src", "plugin.ts") : distPlugin;
|
|
309
|
+
const distStdio = join3(ownRoot(), "dist", "stdio.js");
|
|
310
|
+
const stdioEntry = import.meta.url.endsWith(".ts") || !existsSync3(distStdio) ? join3(ownRoot(), "src", "stdio.ts") : distStdio;
|
|
311
|
+
const realProfileDir = join3(home, "profiles", "acp");
|
|
312
|
+
if (existsSync3(join3(realProfileDir, "package.json"))) {
|
|
250
313
|
appBoot.healProfilesModuleFallback(dshPkgPath);
|
|
251
314
|
const profile = appBoot.loadProfile(BIN, "acp", dshPkgPath);
|
|
252
315
|
bundlePatches = profile.layers.flatMap((layer) => layer.patches);
|
|
253
316
|
profilePatches = profile.patches;
|
|
254
|
-
profilePatchPath =
|
|
255
|
-
const realRoot =
|
|
256
|
-
if (
|
|
317
|
+
profilePatchPath = join3(profile.dir, "cordis.patch.yml");
|
|
318
|
+
const realRoot = join3(profile.dir, "cordis.yml");
|
|
319
|
+
if (existsSync3(realRoot)) rootConfigPath = realRoot;
|
|
257
320
|
bareModuleBaseUrl = void 0;
|
|
258
321
|
logDebug(`profile: real (${profile.dir})`);
|
|
259
322
|
} else {
|
|
260
323
|
const basePatch = bundlePatchPath(req.resolve("@deepseek-ai/dsh-base/package.json"));
|
|
261
|
-
const ownPatch = bundlePatchPath(
|
|
324
|
+
const ownPatch = bundlePatchPath(join3(ownRoot(), "package.json"));
|
|
262
325
|
bundlePatches = [
|
|
263
326
|
...appBoot.loadOverlayPatches(BIN, basePatch),
|
|
264
327
|
...appBoot.loadOverlayPatches(BIN, ownPatch)
|
|
@@ -277,15 +340,15 @@ async function bootAcpProfile(host, overrides) {
|
|
|
277
340
|
stdio: stdioEntry
|
|
278
341
|
});
|
|
279
342
|
}
|
|
280
|
-
const homePatchPath =
|
|
343
|
+
const homePatchPath = join3(home, "cordis.patch.yml");
|
|
281
344
|
const homePatches = appBoot.loadOptionalPatches(BIN, homePatchPath) ?? [];
|
|
282
345
|
const rows = /* @__PURE__ */ new Map();
|
|
283
346
|
for (const row of appBoot.composeEntries([bundlePatches, profilePatches, homePatches])) {
|
|
284
347
|
if (typeof row.id === "string") rows.set(row.id, row);
|
|
285
348
|
}
|
|
286
349
|
const overlays = [];
|
|
287
|
-
const shippedPresets =
|
|
288
|
-
if (rows.has("agent-presets") &&
|
|
350
|
+
const shippedPresets = join3(dshDir, "config", "agent-presets") + sep2;
|
|
351
|
+
if (rows.has("agent-presets") && existsSync3(shippedPresets)) {
|
|
289
352
|
overlays.push({
|
|
290
353
|
id: "agent-presets",
|
|
291
354
|
config: {
|
|
@@ -315,7 +378,7 @@ async function bootAcpProfile(host, overrides) {
|
|
|
315
378
|
}
|
|
316
379
|
const allPatches = [...bundlePatches, ...profilePatches, ...homePatches, ...overlays];
|
|
317
380
|
const launchEnvironment = appBoot.loadLayeredEnv("dsh");
|
|
318
|
-
const launchEnvKey = (await import(
|
|
381
|
+
const launchEnvKey = (await import(pathToFileURL(req.resolve("@deepseek-ai/dsh-launch-environment")).href)).DSH_LAUNCH_ENVIRONMENT_KEY;
|
|
319
382
|
const ctx = await appBoot.boot(
|
|
320
383
|
BIN,
|
|
321
384
|
rootConfigPath,
|
|
@@ -447,8 +510,8 @@ The dsh Web UI and every dsh surface share this credential.
|
|
|
447
510
|
}
|
|
448
511
|
|
|
449
512
|
// src/settings.ts
|
|
450
|
-
import { homedir } from "node:os";
|
|
451
|
-
import { join as
|
|
513
|
+
import { homedir as homedir2 } from "node:os";
|
|
514
|
+
import { join as join4 } from "node:path";
|
|
452
515
|
var DEFAULT_PERSONA = `You are a coding assistant powered by the {{model}} model, working inside an editor via the Agent Client Protocol. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox \u2014 a \`[sandbox: file access denied \u2026]\` result is policy, not a command bug.
|
|
453
516
|
|
|
454
517
|
Verify your work by running the code or tests. Keep answers brief and factual.`;
|
|
@@ -552,7 +615,7 @@ function resolveSettings(argv) {
|
|
|
552
615
|
models,
|
|
553
616
|
maxTokens,
|
|
554
617
|
permissionMode,
|
|
555
|
-
sessionRoot: stringFlag(parsed, "session-root") ?? envString("DSH_SESSION_ROOT") ??
|
|
618
|
+
sessionRoot: stringFlag(parsed, "session-root") ?? envString("DSH_SESSION_ROOT") ?? join4(homedir2(), ".dsh-acp", "sessions"),
|
|
556
619
|
persona: stringFlag(parsed, "persona") ?? envString("DSH_SYSTEM_PROMPT") ?? DEFAULT_PERSONA,
|
|
557
620
|
thinking: !parsed.flags.has("no-thinking"),
|
|
558
621
|
reasoningEffort: reasoningRaw,
|
package/dist/plugin.js
CHANGED
|
@@ -56,6 +56,7 @@ __export(bridge_exports, {
|
|
|
56
56
|
answerFromElicitation: () => answerFromElicitation,
|
|
57
57
|
apply: () => apply3,
|
|
58
58
|
askUserQuestionsOverAcp: () => askUserQuestionsOverAcp,
|
|
59
|
+
createElicitation: () => createElicitation,
|
|
59
60
|
inject: () => inject3,
|
|
60
61
|
installAcpUserQuestionProvider: () => installAcpUserQuestionProvider,
|
|
61
62
|
name: () => name3,
|
|
@@ -1595,6 +1596,7 @@ function apply(ctx, config) {
|
|
|
1595
1596
|
var user_questions_plugin_exports = {};
|
|
1596
1597
|
__export(user_questions_plugin_exports, {
|
|
1597
1598
|
apply: () => apply2,
|
|
1599
|
+
createElicitation: () => createElicitation,
|
|
1598
1600
|
inject: () => inject2,
|
|
1599
1601
|
name: () => name2
|
|
1600
1602
|
});
|
|
@@ -1727,6 +1729,9 @@ async function askUserQuestionsOverAcp(request, sessionId, create) {
|
|
|
1727
1729
|
}
|
|
1728
1730
|
return answer;
|
|
1729
1731
|
}
|
|
1732
|
+
function createElicitation(connection, request) {
|
|
1733
|
+
return connection.createElicitation(request);
|
|
1734
|
+
}
|
|
1730
1735
|
var ROUTERS_KEY = /* @__PURE__ */ Symbol.for("@openma/deepseek-harness-acp/user-question-routers");
|
|
1731
1736
|
var routers = globalThis[ROUTERS_KEY] ??= /* @__PURE__ */ new WeakMap();
|
|
1732
1737
|
function installAcpUserQuestionProvider(service, options) {
|
|
@@ -2880,6 +2885,7 @@ async function apply3(ctx, config = {}) {
|
|
|
2880
2885
|
await requireCredential(config.provider);
|
|
2881
2886
|
mark("credential");
|
|
2882
2887
|
validateCwd(params.cwd);
|
|
2888
|
+
validateAdditionalDirectories(params.additionalDirectories);
|
|
2883
2889
|
syncMcpServers(params.mcpServers, params.cwd);
|
|
2884
2890
|
mark("request setup");
|
|
2885
2891
|
const sessionId = SessionId2(randomUUID());
|
|
@@ -2924,6 +2930,7 @@ async function apply3(ctx, config = {}) {
|
|
|
2924
2930
|
assertOpen();
|
|
2925
2931
|
await requireCredential(config.provider);
|
|
2926
2932
|
validateCwd(params.cwd);
|
|
2933
|
+
validateAdditionalDirectories(params.additionalDirectories);
|
|
2927
2934
|
syncMcpServers(params.mcpServers, params.cwd);
|
|
2928
2935
|
requirePersistence();
|
|
2929
2936
|
const record = await restoreSession(params.sessionId, { replay: true, cwd: params.cwd });
|
|
@@ -3167,6 +3174,11 @@ async function apply3(ctx, config = {}) {
|
|
|
3167
3174
|
function validateCwd(cwd) {
|
|
3168
3175
|
if (!isAbsolute(cwd)) throw invalidParams(`cwd must be an absolute path: ${cwd}`);
|
|
3169
3176
|
}
|
|
3177
|
+
function validateAdditionalDirectories(additionalDirectories) {
|
|
3178
|
+
if (additionalDirectories !== void 0 && additionalDirectories.length > 0) {
|
|
3179
|
+
throw invalidParams("additionalDirectories is not supported");
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3170
3182
|
const mcpMounts = /* @__PURE__ */ new Map();
|
|
3171
3183
|
let warnedNoMcpClient = false;
|
|
3172
3184
|
const sanitizeServerName = (raw2) => {
|
|
@@ -3264,7 +3276,7 @@ async function apply3(ctx, config = {}) {
|
|
|
3264
3276
|
const record = ownedRecord(request.agent);
|
|
3265
3277
|
return record === void 0 ? void 0 : String(record.agent.session.id);
|
|
3266
3278
|
},
|
|
3267
|
-
create: (request) => conn
|
|
3279
|
+
create: (request) => createElicitation(conn, request)
|
|
3268
3280
|
});
|
|
3269
3281
|
let quiescing;
|
|
3270
3282
|
const quiesce = () => {
|
package/dist/server.js
CHANGED
|
@@ -50,6 +50,7 @@ __export(bridge_exports, {
|
|
|
50
50
|
answerFromElicitation: () => answerFromElicitation,
|
|
51
51
|
apply: () => apply3,
|
|
52
52
|
askUserQuestionsOverAcp: () => askUserQuestionsOverAcp,
|
|
53
|
+
createElicitation: () => createElicitation,
|
|
53
54
|
inject: () => inject3,
|
|
54
55
|
installAcpUserQuestionProvider: () => installAcpUserQuestionProvider,
|
|
55
56
|
name: () => name3,
|
|
@@ -1589,6 +1590,7 @@ function apply(ctx, config) {
|
|
|
1589
1590
|
var user_questions_plugin_exports = {};
|
|
1590
1591
|
__export(user_questions_plugin_exports, {
|
|
1591
1592
|
apply: () => apply2,
|
|
1593
|
+
createElicitation: () => createElicitation,
|
|
1592
1594
|
inject: () => inject2,
|
|
1593
1595
|
name: () => name2
|
|
1594
1596
|
});
|
|
@@ -1721,6 +1723,9 @@ async function askUserQuestionsOverAcp(request, sessionId, create) {
|
|
|
1721
1723
|
}
|
|
1722
1724
|
return answer;
|
|
1723
1725
|
}
|
|
1726
|
+
function createElicitation(connection, request) {
|
|
1727
|
+
return connection.createElicitation(request);
|
|
1728
|
+
}
|
|
1724
1729
|
var ROUTERS_KEY = /* @__PURE__ */ Symbol.for("@openma/deepseek-harness-acp/user-question-routers");
|
|
1725
1730
|
var routers = globalThis[ROUTERS_KEY] ??= /* @__PURE__ */ new WeakMap();
|
|
1726
1731
|
function installAcpUserQuestionProvider(service, options) {
|
|
@@ -2874,6 +2879,7 @@ async function apply3(ctx, config = {}) {
|
|
|
2874
2879
|
await requireCredential(config.provider);
|
|
2875
2880
|
mark("credential");
|
|
2876
2881
|
validateCwd(params.cwd);
|
|
2882
|
+
validateAdditionalDirectories(params.additionalDirectories);
|
|
2877
2883
|
syncMcpServers(params.mcpServers, params.cwd);
|
|
2878
2884
|
mark("request setup");
|
|
2879
2885
|
const sessionId = SessionId2(randomUUID());
|
|
@@ -2918,6 +2924,7 @@ async function apply3(ctx, config = {}) {
|
|
|
2918
2924
|
assertOpen();
|
|
2919
2925
|
await requireCredential(config.provider);
|
|
2920
2926
|
validateCwd(params.cwd);
|
|
2927
|
+
validateAdditionalDirectories(params.additionalDirectories);
|
|
2921
2928
|
syncMcpServers(params.mcpServers, params.cwd);
|
|
2922
2929
|
requirePersistence();
|
|
2923
2930
|
const record = await restoreSession(params.sessionId, { replay: true, cwd: params.cwd });
|
|
@@ -3161,6 +3168,11 @@ async function apply3(ctx, config = {}) {
|
|
|
3161
3168
|
function validateCwd(cwd) {
|
|
3162
3169
|
if (!isAbsolute(cwd)) throw invalidParams(`cwd must be an absolute path: ${cwd}`);
|
|
3163
3170
|
}
|
|
3171
|
+
function validateAdditionalDirectories(additionalDirectories) {
|
|
3172
|
+
if (additionalDirectories !== void 0 && additionalDirectories.length > 0) {
|
|
3173
|
+
throw invalidParams("additionalDirectories is not supported");
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3164
3176
|
const mcpMounts = /* @__PURE__ */ new Map();
|
|
3165
3177
|
let warnedNoMcpClient = false;
|
|
3166
3178
|
const sanitizeServerName = (raw2) => {
|
|
@@ -3258,7 +3270,7 @@ async function apply3(ctx, config = {}) {
|
|
|
3258
3270
|
const record = ownedRecord(request.agent);
|
|
3259
3271
|
return record === void 0 ? void 0 : String(record.agent.session.id);
|
|
3260
3272
|
},
|
|
3261
|
-
create: (request) => conn
|
|
3273
|
+
create: (request) => createElicitation(conn, request)
|
|
3262
3274
|
});
|
|
3263
3275
|
let quiescing;
|
|
3264
3276
|
const quiesce = () => {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.4.
|
|
6
|
+
"version": "0.4.23-beta.0",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/openma-ai/deepseek-harness-acp.git"
|
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
"description": "Agent Client Protocol (ACP) adapter for DeepSeek Harness — use DeepSeek Harness from ACP clients such as Zed.",
|
|
16
16
|
"main": "dist/index.js",
|
|
17
17
|
"bin": {
|
|
18
|
-
"dsh-acp": "dist/
|
|
18
|
+
"dsh-acp": "dist/bin.js"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
+
"dist/bin.js",
|
|
21
22
|
"dist/index.js",
|
|
22
23
|
"dist/bridge.js",
|
|
23
24
|
"dist/server.js",
|
|
@@ -28,18 +29,21 @@
|
|
|
28
29
|
"LICENSE",
|
|
29
30
|
"package.json",
|
|
30
31
|
"profile-root.cordis.yml",
|
|
32
|
+
"vendor/*.json",
|
|
33
|
+
"vendor/*.tgz",
|
|
31
34
|
"assets/icon.svg"
|
|
32
35
|
],
|
|
33
36
|
"scripts": {
|
|
34
|
-
"
|
|
37
|
+
"prepack": "npm run build && npm run runtime:pack",
|
|
35
38
|
"build": "node build.mjs",
|
|
39
|
+
"runtime:pack": "node scripts/pack-runtime.mjs",
|
|
36
40
|
"start": "node --import tsx src/index.ts",
|
|
37
41
|
"pretest": "npm run build",
|
|
38
42
|
"test": "vitest run",
|
|
39
43
|
"test:host": "vitest run test/e2e.test.ts -t \"serves session controls through the host tree\"",
|
|
40
44
|
"test:watch": "vitest",
|
|
41
45
|
"typecheck": "tsc --noEmit",
|
|
42
|
-
"pack:local": "npm
|
|
46
|
+
"pack:local": "npm pack"
|
|
43
47
|
},
|
|
44
48
|
"license": "Apache-2.0",
|
|
45
49
|
"type": "module",
|
|
@@ -49,62 +53,62 @@
|
|
|
49
53
|
"devDependencies": {
|
|
50
54
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
51
55
|
"@deepseek-ai/cordis-plugin-timer": "^1.1.3",
|
|
52
|
-
"@deepseek-ai/dsh": "
|
|
53
|
-
"@deepseek-ai/dsh-agent": "
|
|
54
|
-
"@deepseek-ai/dsh-agent-instructions": "
|
|
55
|
-
"@deepseek-ai/dsh-agent-loop": "
|
|
56
|
-
"@deepseek-ai/dsh-agent-spine-demo": "
|
|
57
|
-
"@deepseek-ai/dsh-anonymous-user-id": "
|
|
58
|
-
"@deepseek-ai/dsh-attachment": "
|
|
59
|
-
"@deepseek-ai/dsh-bash-sandbox": "
|
|
60
|
-
"@deepseek-ai/dsh-brand": "
|
|
61
|
-
"@deepseek-ai/dsh-commands": "
|
|
62
|
-
"@deepseek-ai/dsh-compaction": "
|
|
63
|
-
"@deepseek-ai/dsh-compaction-basic": "
|
|
64
|
-
"@deepseek-ai/dsh-compaction-tool-result-pruner": "
|
|
65
|
-
"@deepseek-ai/dsh-credentials": "
|
|
66
|
-
"@deepseek-ai/dsh-credentials-local": "
|
|
67
|
-
"@deepseek-ai/dsh-fs": "
|
|
68
|
-
"@deepseek-ai/dsh-fs-local": "
|
|
69
|
-
"@deepseek-ai/dsh-fs-observation-policy": "
|
|
70
|
-
"@deepseek-ai/dsh-fs-sandbox": "
|
|
71
|
-
"@deepseek-ai/dsh-goal": "
|
|
72
|
-
"@deepseek-ai/dsh-goal-round-driver": "
|
|
73
|
-
"@deepseek-ai/dsh-home-paths": "
|
|
74
|
-
"@deepseek-ai/dsh-invariants": "
|
|
75
|
-
"@deepseek-ai/dsh-jobs-local": "
|
|
76
|
-
"@deepseek-ai/dsh-launch-environment": "
|
|
77
|
-
"@deepseek-ai/dsh-llm": "
|
|
78
|
-
"@deepseek-ai/dsh-llm-deepseek": "
|
|
79
|
-
"@deepseek-ai/dsh-llm-retry": "
|
|
80
|
-
"@deepseek-ai/dsh-sandbox": "
|
|
81
|
-
"@deepseek-ai/dsh-sandbox-local": "
|
|
82
|
-
"@deepseek-ai/dsh-sandbox-policy": "
|
|
83
|
-
"@deepseek-ai/dsh-scope": "
|
|
84
|
-
"@deepseek-ai/dsh-session": "
|
|
85
|
-
"@deepseek-ai/dsh-session-checkpoint-policy": "
|
|
86
|
-
"@deepseek-ai/dsh-session-persistence": "
|
|
87
|
-
"@deepseek-ai/dsh-session-persistence-jsonl": "
|
|
88
|
-
"@deepseek-ai/dsh-session-projection": "
|
|
89
|
-
"@deepseek-ai/dsh-session-title": "
|
|
90
|
-
"@deepseek-ai/dsh-settings": "
|
|
91
|
-
"@deepseek-ai/dsh-shell": "
|
|
92
|
-
"@deepseek-ai/dsh-shell-env": "
|
|
93
|
-
"@deepseek-ai/dsh-skill": "
|
|
94
|
-
"@deepseek-ai/dsh-skill-filesystem": "
|
|
95
|
-
"@deepseek-ai/dsh-subprocess": "
|
|
96
|
-
"@deepseek-ai/dsh-subprocess-local": "
|
|
97
|
-
"@deepseek-ai/dsh-system-prompt": "
|
|
98
|
-
"@deepseek-ai/dsh-timeout": "
|
|
99
|
-
"@deepseek-ai/dsh-token-meter": "
|
|
100
|
-
"@deepseek-ai/dsh-tool-bash": "
|
|
101
|
-
"@deepseek-ai/dsh-tool-fs": "
|
|
102
|
-
"@deepseek-ai/dsh-tool-goal": "
|
|
103
|
-
"@deepseek-ai/dsh-tool-jobs": "
|
|
104
|
-
"@deepseek-ai/dsh-tool-skill": "
|
|
105
|
-
"@deepseek-ai/dsh-tool-todo": "
|
|
106
|
-
"@deepseek-ai/dsh-tools": "
|
|
107
|
-
"@deepseek-ai/dsh-user-approval": "
|
|
56
|
+
"@deepseek-ai/dsh": "0.1.1-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-agent": "0.1.1-rc.2",
|
|
58
|
+
"@deepseek-ai/dsh-agent-instructions": "0.1.1-rc.2",
|
|
59
|
+
"@deepseek-ai/dsh-agent-loop": "0.1.1-rc.2",
|
|
60
|
+
"@deepseek-ai/dsh-agent-spine-demo": "0.1.1-rc.2",
|
|
61
|
+
"@deepseek-ai/dsh-anonymous-user-id": "0.1.1-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-attachment": "0.1.1-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-bash-sandbox": "0.1.1-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-brand": "0.1.1-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-commands": "0.1.1-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-compaction": "0.1.1-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-compaction-basic": "0.1.1-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.1-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
|
|
70
|
+
"@deepseek-ai/dsh-credentials-local": "0.1.1-rc.2",
|
|
71
|
+
"@deepseek-ai/dsh-fs": "0.1.1-rc.2",
|
|
72
|
+
"@deepseek-ai/dsh-fs-local": "0.1.1-rc.2",
|
|
73
|
+
"@deepseek-ai/dsh-fs-observation-policy": "0.1.1-rc.2",
|
|
74
|
+
"@deepseek-ai/dsh-fs-sandbox": "0.1.1-rc.2",
|
|
75
|
+
"@deepseek-ai/dsh-goal": "0.1.1-rc.2",
|
|
76
|
+
"@deepseek-ai/dsh-goal-round-driver": "0.1.1-rc.2",
|
|
77
|
+
"@deepseek-ai/dsh-home-paths": "0.1.1-rc.2",
|
|
78
|
+
"@deepseek-ai/dsh-invariants": "0.1.1-rc.2",
|
|
79
|
+
"@deepseek-ai/dsh-jobs-local": "0.1.1-rc.2",
|
|
80
|
+
"@deepseek-ai/dsh-launch-environment": "0.1.1-rc.2",
|
|
81
|
+
"@deepseek-ai/dsh-llm": "0.1.1-rc.2",
|
|
82
|
+
"@deepseek-ai/dsh-llm-deepseek": "0.1.1-rc.2",
|
|
83
|
+
"@deepseek-ai/dsh-llm-retry": "0.1.1-rc.2",
|
|
84
|
+
"@deepseek-ai/dsh-sandbox": "0.1.1-rc.2",
|
|
85
|
+
"@deepseek-ai/dsh-sandbox-local": "0.1.1-rc.2",
|
|
86
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.1.1-rc.2",
|
|
87
|
+
"@deepseek-ai/dsh-scope": "0.1.1-rc.2",
|
|
88
|
+
"@deepseek-ai/dsh-session": "0.1.1-rc.2",
|
|
89
|
+
"@deepseek-ai/dsh-session-checkpoint-policy": "0.1.1-rc.2",
|
|
90
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.1-rc.2",
|
|
91
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "0.1.1-rc.2",
|
|
92
|
+
"@deepseek-ai/dsh-session-projection": "0.1.1-rc.2",
|
|
93
|
+
"@deepseek-ai/dsh-session-title": "0.1.1-rc.2",
|
|
94
|
+
"@deepseek-ai/dsh-settings": "0.1.1-rc.2",
|
|
95
|
+
"@deepseek-ai/dsh-shell": "0.1.1-rc.2",
|
|
96
|
+
"@deepseek-ai/dsh-shell-env": "0.1.1-rc.2",
|
|
97
|
+
"@deepseek-ai/dsh-skill": "0.1.1-rc.2",
|
|
98
|
+
"@deepseek-ai/dsh-skill-filesystem": "0.1.1-rc.2",
|
|
99
|
+
"@deepseek-ai/dsh-subprocess": "0.1.1-rc.2",
|
|
100
|
+
"@deepseek-ai/dsh-subprocess-local": "0.1.1-rc.2",
|
|
101
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.1-rc.2",
|
|
102
|
+
"@deepseek-ai/dsh-timeout": "0.1.1-rc.2",
|
|
103
|
+
"@deepseek-ai/dsh-token-meter": "0.1.1-rc.2",
|
|
104
|
+
"@deepseek-ai/dsh-tool-bash": "0.1.1-rc.2",
|
|
105
|
+
"@deepseek-ai/dsh-tool-fs": "0.1.1-rc.2",
|
|
106
|
+
"@deepseek-ai/dsh-tool-goal": "0.1.1-rc.2",
|
|
107
|
+
"@deepseek-ai/dsh-tool-jobs": "0.1.1-rc.2",
|
|
108
|
+
"@deepseek-ai/dsh-tool-skill": "0.1.1-rc.2",
|
|
109
|
+
"@deepseek-ai/dsh-tool-todo": "0.1.1-rc.2",
|
|
110
|
+
"@deepseek-ai/dsh-tools": "0.1.1-rc.2",
|
|
111
|
+
"@deepseek-ai/dsh-user-approval": "0.1.1-rc.2",
|
|
108
112
|
"@types/node": "^26.1.0",
|
|
109
113
|
"esbuild": "^0.28.1",
|
|
110
114
|
"pnpm": "11.22.0",
|
|
@@ -114,11 +118,17 @@
|
|
|
114
118
|
"yaml": "^2.9.0"
|
|
115
119
|
},
|
|
116
120
|
"dependencies": {
|
|
117
|
-
"@agentclientprotocol/sdk": "
|
|
118
|
-
"
|
|
121
|
+
"@agentclientprotocol/sdk": "1.4.0",
|
|
122
|
+
"tar": "7.4.3",
|
|
123
|
+
"zod": "4.4.3"
|
|
119
124
|
},
|
|
120
125
|
"peerDependencies": {
|
|
121
|
-
"@deepseek-ai/dsh": "
|
|
126
|
+
"@deepseek-ai/dsh": "*"
|
|
127
|
+
},
|
|
128
|
+
"peerDependenciesMeta": {
|
|
129
|
+
"@deepseek-ai/dsh": {
|
|
130
|
+
"optional": true
|
|
131
|
+
}
|
|
122
132
|
},
|
|
123
133
|
"exports": {
|
|
124
134
|
".": "./dist/index.js",
|
|
@@ -133,5 +143,12 @@
|
|
|
133
143
|
"bundle": {
|
|
134
144
|
"patch": "./cordis.patch.yml"
|
|
135
145
|
}
|
|
146
|
+
},
|
|
147
|
+
"dshAcp": {
|
|
148
|
+
"standaloneDsh": "0.1.1-rc.2",
|
|
149
|
+
"hostCompatibility": {
|
|
150
|
+
"cordisProtocol": 0,
|
|
151
|
+
"policy": "capability-negotiated"
|
|
152
|
+
}
|
|
136
153
|
}
|
|
137
154
|
}
|
|
Binary file
|