@openma/deepseek-harness-acp 0.4.9 → 0.4.10-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.md CHANGED
@@ -36,13 +36,19 @@ touch your editor config — it reuses the key you saved in the dsh Web UI, or
36
36
  | Best for | Getting started in one command | Living inside your dsh setup |
37
37
  | Install | `npm i -g @openma/deepseek-harness-acp` | `dsh plugin --profile acp add -w @openma/deepseek-harness-acp` |
38
38
  | Zed runs | `dsh-acp` | `dsh --profile acp` |
39
- | Harness | Your installed dsh — or the vendored fallback when none exists | The dsh that owns the profile |
39
+ | Harness | Your installed dsh — or the npm-installed peer when none exists | The dsh that owns the profile |
40
40
  | Composition | dsh-base + this bundle (profile machinery booted in-process) | dsh-base + this bundle + your profile's own patches |
41
41
 
42
42
  Both shapes share `$DSH_HOME`: the same credential store, settings, presets,
43
43
  and session logs as `dsh web` — conversations started in the Web UI can be
44
44
  listed and loaded from the editor.
45
45
 
46
+ Other dsh surfaces can mount the transport-independent
47
+ `@openma/deepseek-harness-acp/plugin` on their Base Host tree and own the
48
+ transport adapter. The TUI profile uses this path: it starts a separate TUI
49
+ Client process and connects ACP over that process's standard stdin/stdout; it
50
+ does not start `dsh-acp` or use an in-process Client stream.
51
+
46
52
  ### A · Standalone server
47
53
 
48
54
  ```bash
@@ -61,7 +67,7 @@ dsh-acp login # interactive; or save the key in the dsh Web UI
61
67
 
62
68
  Self-contained: it finds your DeepSeek Harness via `--dsh-path` / `DSH_PATH`,
63
69
  its own tree, `./node_modules`, `dsh` on PATH, or `npm root -g` — and ships a
64
- vendored harness runtime as the **last** candidate, so it works out of the box
70
+ npm-installed harness peer as the **last** candidate, so it works out of the box
65
71
  and always prefers the dsh you installed. When a real
66
72
  `$DSH_HOME/profiles/acp` exists, that profile owns the composition.
67
73
 
@@ -169,7 +175,7 @@ ACP client (Zed, …)
169
175
  dsh-acp
170
176
  ├─ src/profile-boot.ts boots the harness's own profile machinery
171
177
  │ (dsh-base + this bundle + $DSH_HOME layers)
172
- ├─ src/harness.ts host discovery (DSH_PATH → cwd → PATH → npm -g → vendored)
178
+ ├─ src/harness.ts host discovery (DSH_PATH → cwd → PATH → npm -g → npm peer)
173
179
  └─ src/bridge/ the ACP bridge (a cordis plugin)
174
180
  ├─ index.ts sessions, prompts, cancel, modes, options,
175
181
  │ commands, credentials, MCP mounts
package/cordis.patch.yml CHANGED
@@ -97,22 +97,15 @@
97
97
  disabled: true
98
98
 
99
99
  - insert:
100
- # Agent presets: per-session model-facing compositions (persona, tools,
101
- # compaction). The dsh CLI injects its shipped root into any row with this
102
- # id, so standard/code/minimal/creator are available and ACP session modes
103
- # surface them (~/.dsh/agent-presets adds user-authored ones).
104
- - id: agent-presets
105
- name: '@deepseek-ai/dsh-agent-presets'
106
- config:
107
- default: standard
108
-
109
- # Same host row the web-app bundle mounts. Without it, preset "cordis"
110
- # never activates: tool-cordis waits for dynamicCordisRunner, cordisInspect.
111
- - id: cordis-host-runner
112
- name: '@deepseek-ai/dsh-cordis-host-runner'
113
-
114
- - id: acp-bridge
115
- name: '@openma/deepseek-harness-acp/bridge'
100
+ # The same complete Cordis plugin embedded by other surfaces. It owns the
101
+ # preset plane and transport-independent ACP server, but no transport.
102
+ - id: acp-plugin
103
+ name: '@openma/deepseek-harness-acp/plugin'
116
104
  config:
117
105
  model: !!js process.env.DSH_MODEL
118
106
  permissionMode: !!js process.env.DSH_PERMISSION_MODE ?? 'workspace-write'
107
+
108
+ # The ordinary ACP profile owns stdio. Embedded surfaces replace only this
109
+ # adapter and reuse the exact same plugin contract above.
110
+ - id: acp-bridge
111
+ name: '@openma/deepseek-harness-acp/stdio'
package/dist/bridge.js CHANGED
@@ -44,7 +44,21 @@ var init_self_harness = __esm({
44
44
  }
45
45
  });
46
46
 
47
+ // src/bundle.ts
48
+ import { ndJsonStream as ndJsonStream2 } from "@agentclientprotocol/sdk";
49
+ import { Readable as Readable2, Writable as Writable2 } from "node:stream";
50
+
47
51
  // src/bridge/index.ts
52
+ var bridge_exports = {};
53
+ __export(bridge_exports, {
54
+ answerFromElicitation: () => answerFromElicitation,
55
+ apply: () => apply,
56
+ askUserQuestionsOverAcp: () => askUserQuestionsOverAcp,
57
+ inject: () => inject,
58
+ installAcpUserQuestionProvider: () => installAcpUserQuestionProvider,
59
+ name: () => name,
60
+ questionsToElicitation: () => questionsToElicitation
61
+ });
48
62
  import { randomUUID } from "node:crypto";
49
63
  import { isAbsolute } from "node:path";
50
64
  import { Readable, Writable } from "node:stream";
@@ -1113,6 +1127,36 @@ ${contextBlock(resource.uri, resource.text)}
1113
1127
  };
1114
1128
  }
1115
1129
 
1130
+ // src/bridge/cordis-protocol.ts
1131
+ var CORDIS_PROTOCOL = 0;
1132
+ var CORDIS_CAPABILITY = Object.freeze({ protocol: CORDIS_PROTOCOL });
1133
+ var CORDIS_METHODS = Object.freeze({
1134
+ inspectSync: "_dsh/cordis/inspect/sync",
1135
+ inspectResolve: "_dsh/cordis/inspect/resolve",
1136
+ inspectQuery: "_dsh/cordis/inspect/query",
1137
+ inspectQueryResolved: "_dsh/cordis/inspect/query-resolved",
1138
+ runHost: "_dsh/cordis/run/host",
1139
+ getClientCode: "_dsh/cordis/run/client-code",
1140
+ resolveRequestRun: "_dsh/cordis/run/resolve",
1141
+ requestRun: "_dsh/cordis/run/request",
1142
+ requestRunResolved: "_dsh/cordis/run/request-resolved",
1143
+ userRun: "_dsh/cordis/run/user",
1144
+ settleUserRun: "_dsh/cordis/run/settle",
1145
+ pluginInvoke: "_dsh/cordis/plugin/invoke",
1146
+ pluginsList: "_dsh/cordis/plugins/list",
1147
+ pluginStart: "_dsh/cordis/plugins/start",
1148
+ pluginStop: "_dsh/cordis/plugins/stop",
1149
+ pluginRetract: "_dsh/cordis/plugins/retract"
1150
+ });
1151
+ function advertisesCordis(meta) {
1152
+ if (meta === null || typeof meta !== "object" || Array.isArray(meta)) return false;
1153
+ const dsh = meta["dsh"];
1154
+ if (dsh === null || typeof dsh !== "object" || Array.isArray(dsh)) return false;
1155
+ const cordis = dsh["cordis"];
1156
+ if (cordis === null || typeof cordis !== "object" || Array.isArray(cordis)) return false;
1157
+ return cordis["protocol"] === CORDIS_PROTOCOL;
1158
+ }
1159
+
1116
1160
  // src/bridge/rpc.ts
1117
1161
  var AcpRpc = class {
1118
1162
  handlers = /* @__PURE__ */ new Map();
@@ -1126,11 +1170,14 @@ var AcpRpc = class {
1126
1170
  }
1127
1171
  /**
1128
1172
  * Register a bridge-owned request method intercepted before the ACP SDK.
1129
- * @param method - JSON-RPC method name (e.g. `tui/refresh`).
1173
+ * @param method - JSON-RPC extension method (e.g. `_dsh/cordis/inspect/sync`).
1130
1174
  * @param handler - implementation.
1131
1175
  * @returns disposer.
1132
1176
  */
1133
1177
  registerMethod(method, handler) {
1178
+ if (!method.startsWith("_")) {
1179
+ throw new Error(`acpRpc: extension method ${JSON.stringify(method)} must start with "_"`);
1180
+ }
1134
1181
  if (this.handlers.has(method)) {
1135
1182
  throw new Error(`acpRpc: method ${JSON.stringify(method)} is already registered`);
1136
1183
  }
@@ -1165,11 +1212,14 @@ var AcpRpc = class {
1165
1212
  }
1166
1213
  }
1167
1214
  /**
1168
- * Send a JSON-RPC notification on the ACP stream (e.g. `tui/snapshot`).
1215
+ * Send a JSON-RPC extension notification on the ACP stream.
1169
1216
  * @param method - notification method.
1170
1217
  * @param params - payload.
1171
1218
  */
1172
1219
  notify(method, params) {
1220
+ if (!method.startsWith("_")) {
1221
+ throw new Error(`acpRpc: extension notification ${JSON.stringify(method)} must start with "_"`);
1222
+ }
1173
1223
  const write = this.writeJson;
1174
1224
  if (write === void 0) return;
1175
1225
  write(params === void 0 ? { jsonrpc: "2.0", method } : { jsonrpc: "2.0", method, params });
@@ -1214,20 +1264,19 @@ function muxAcpStream(stream, rpc) {
1214
1264
  function installTuiClientPlane(ctx, rpc, opts) {
1215
1265
  const { findAgent, advertisement } = opts;
1216
1266
  ctx.effect(
1217
- () => rpc.registerMethod("tui/inspect-sync", (params) => {
1267
+ () => rpc.registerMethod(CORDIS_METHODS.inspectSync, (params) => {
1218
1268
  const inspect = optionalInspect(ctx);
1219
1269
  if (inspect === void 0) {
1220
1270
  throw new Error("this agent has no Cordis inspect registry");
1221
1271
  }
1222
1272
  const providers = readProviders(params);
1223
1273
  inspect.syncClientManifest(providers);
1224
- advertisement.advertised = true;
1225
1274
  return { ok: true };
1226
1275
  }),
1227
- "acp-bridge: tui/inspect-sync"
1276
+ "acp-bridge: cordis/inspect-sync"
1228
1277
  );
1229
1278
  ctx.effect(
1230
- () => rpc.registerMethod("tui/inspect-resolve", (params) => {
1279
+ () => rpc.registerMethod(CORDIS_METHODS.inspectResolve, (params) => {
1231
1280
  const inspect = optionalInspect(ctx);
1232
1281
  if (inspect === void 0) {
1233
1282
  throw new Error("this agent has no Cordis inspect registry");
@@ -1237,10 +1286,10 @@ function installTuiClientPlane(ctx, rpc, opts) {
1237
1286
  const requestId = readString(body, "requestId");
1238
1287
  return inspect.resolveClientQuery(agent, requestId, body["resolution"]);
1239
1288
  }),
1240
- "acp-bridge: tui/inspect-resolve"
1289
+ "acp-bridge: cordis/inspect-resolve"
1241
1290
  );
1242
1291
  ctx.effect(
1243
- () => rpc.registerMethod("tui/run-host-half", async (params) => {
1292
+ () => rpc.registerMethod(CORDIS_METHODS.runHost, async (params) => {
1244
1293
  const runner = optionalRunner(ctx);
1245
1294
  if (runner === void 0) {
1246
1295
  throw new Error("this agent has no dynamic Cordis runner");
@@ -1257,10 +1306,10 @@ function installTuiClientPlane(ctx, rpc, opts) {
1257
1306
  body["approveFutureVersions"] === true
1258
1307
  );
1259
1308
  }),
1260
- "acp-bridge: tui/run-host-half"
1309
+ "acp-bridge: cordis/run-host-half"
1261
1310
  );
1262
1311
  ctx.effect(
1263
- () => rpc.registerMethod("tui/get-client-code", (params) => {
1312
+ () => rpc.registerMethod(CORDIS_METHODS.getClientCode, (params) => {
1264
1313
  const runner = optionalRunner(ctx);
1265
1314
  if (runner === void 0) {
1266
1315
  throw new Error("this agent has no dynamic Cordis runner");
@@ -1273,10 +1322,10 @@ function installTuiClientPlane(ctx, rpc, opts) {
1273
1322
  readString(body, "pluginRunId")
1274
1323
  );
1275
1324
  }),
1276
- "acp-bridge: tui/get-client-code"
1325
+ "acp-bridge: cordis/get-client-code"
1277
1326
  );
1278
1327
  ctx.effect(
1279
- () => rpc.registerMethod("tui/resolve-request-run", async (params) => {
1328
+ () => rpc.registerMethod(CORDIS_METHODS.resolveRequestRun, async (params) => {
1280
1329
  const runner = optionalRunner(ctx);
1281
1330
  if (runner === void 0) {
1282
1331
  throw new Error("this agent has no dynamic Cordis runner");
@@ -1287,10 +1336,10 @@ function installTuiClientPlane(ctx, rpc, opts) {
1287
1336
  body["resolution"]
1288
1337
  );
1289
1338
  }),
1290
- "acp-bridge: tui/resolve-request-run"
1339
+ "acp-bridge: cordis/resolve-request-run"
1291
1340
  );
1292
1341
  ctx.effect(
1293
- () => rpc.registerMethod("tui/invoke", async (params) => {
1342
+ () => rpc.registerMethod(CORDIS_METHODS.pluginInvoke, async (params) => {
1294
1343
  const runner = optionalRunner(ctx);
1295
1344
  if (runner === void 0) {
1296
1345
  throw new Error("this agent has no dynamic Cordis runner");
@@ -1304,28 +1353,28 @@ function installTuiClientPlane(ctx, rpc, opts) {
1304
1353
  body["args"] ?? null
1305
1354
  );
1306
1355
  }),
1307
- "acp-bridge: tui/invoke"
1356
+ "acp-bridge: cordis/invoke"
1308
1357
  );
1309
1358
  ctx.effect(
1310
- () => rpc.registerMethod("tui/list-plugins", (params) => {
1359
+ () => rpc.registerMethod(CORDIS_METHODS.pluginsList, (params) => {
1311
1360
  const runner = requireRunnerMethod(ctx, "listPlugins");
1312
1361
  const body = asObject(params);
1313
1362
  const agent = requireAgent(findAgent, readString(body, "agentId"));
1314
1363
  return runner.listPlugins(agent);
1315
1364
  }),
1316
- "acp-bridge: tui/list-plugins"
1365
+ "acp-bridge: cordis/list-plugins"
1317
1366
  );
1318
1367
  ctx.effect(
1319
- () => rpc.registerMethod("tui/stop-plugin", async (params) => {
1368
+ () => rpc.registerMethod(CORDIS_METHODS.pluginStop, async (params) => {
1320
1369
  const runner = requireRunnerMethod(ctx, "stopFromPanel");
1321
1370
  const body = asObject(params);
1322
1371
  const agent = requireAgent(findAgent, readString(body, "agentId"));
1323
1372
  return await runner.stopFromPanel(agent, readString(body, "pluginId"));
1324
1373
  }),
1325
- "acp-bridge: tui/stop-plugin"
1374
+ "acp-bridge: cordis/stop-plugin"
1326
1375
  );
1327
1376
  ctx.effect(
1328
- () => rpc.registerMethod("tui/start-plugin", async (params) => {
1377
+ () => rpc.registerMethod(CORDIS_METHODS.pluginStart, async (params) => {
1329
1378
  const runner = requireRunnerMethod(ctx, "listPlugins");
1330
1379
  const body = asObject(params);
1331
1380
  const agentId = readString(body, "agentId");
@@ -1353,7 +1402,7 @@ function installTuiClientPlane(ctx, rpc, opts) {
1353
1402
  const pluginRunId = readString(started, "pluginRunId");
1354
1403
  const startedHere = started["startedHere"] !== false;
1355
1404
  if (pkg.hasClientHalf) {
1356
- rpc.notify("tui/user-run", {
1405
+ rpc.notify(CORDIS_METHODS.userRun, {
1357
1406
  agentId,
1358
1407
  pluginId,
1359
1408
  packageId,
@@ -1365,10 +1414,10 @@ function installTuiClientPlane(ctx, rpc, opts) {
1365
1414
  }
1366
1415
  return { ok: true, status: "starting", pluginId, packageId, pluginRunId };
1367
1416
  }),
1368
- "acp-bridge: tui/start-plugin"
1417
+ "acp-bridge: cordis/start-plugin"
1369
1418
  );
1370
1419
  ctx.effect(
1371
- () => rpc.registerMethod("tui/settle-user-run", async (params) => {
1420
+ () => rpc.registerMethod(CORDIS_METHODS.settleUserRun, async (params) => {
1372
1421
  const runner = requireRunnerMethod(ctx, "settleUserRun");
1373
1422
  const body = asObject(params);
1374
1423
  const agent = requireAgent(findAgent, readString(body, "agentId"));
@@ -1378,27 +1427,27 @@ function installTuiClientPlane(ctx, rpc, opts) {
1378
1427
  body["resolution"]
1379
1428
  );
1380
1429
  }),
1381
- "acp-bridge: tui/settle-user-run"
1430
+ "acp-bridge: cordis/settle-user-run"
1382
1431
  );
1383
1432
  ctx.on("cordis/inspect-query", (request) => {
1384
1433
  if (!advertisement.advertised) return;
1385
- rpc.notify("tui/inspect-query", request);
1434
+ rpc.notify(CORDIS_METHODS.inspectQuery, request);
1386
1435
  });
1387
1436
  ctx.on("cordis/inspect-query-resolved", (resolved) => {
1388
1437
  if (!advertisement.advertised) return;
1389
- rpc.notify("tui/inspect-query-resolved", resolved);
1438
+ rpc.notify(CORDIS_METHODS.inspectQueryResolved, resolved);
1390
1439
  });
1391
1440
  ctx.on("cordis/request-run", (request) => {
1392
1441
  if (!advertisement.advertised) return;
1393
- rpc.notify("tui/request-run", request);
1442
+ rpc.notify(CORDIS_METHODS.requestRun, request);
1394
1443
  });
1395
1444
  ctx.on("cordis/request-run-resolved", (resolved) => {
1396
1445
  if (!advertisement.advertised) return;
1397
- rpc.notify("tui/request-run-resolved", resolved);
1446
+ rpc.notify(CORDIS_METHODS.requestRunResolved, resolved);
1398
1447
  });
1399
1448
  ctx.on("cordis/dynamic-retract", (retracted) => {
1400
1449
  if (!advertisement.advertised) return;
1401
- rpc.notify("tui/dynamic-retract", retracted);
1450
+ rpc.notify(CORDIS_METHODS.pluginRetract, retracted);
1402
1451
  });
1403
1452
  }
1404
1453
  function optionalInspect(ctx) {
@@ -1465,6 +1514,7 @@ function readProviders(params) {
1465
1514
  }
1466
1515
 
1467
1516
  // src/bridge/user-questions.ts
1517
+ import { Service } from "@deepseek-ai/cordis";
1468
1518
  import {
1469
1519
  UserQuestionError
1470
1520
  } from "@deepseek-ai/dsh-user-questions";
@@ -1591,25 +1641,48 @@ async function askUserQuestionsOverAcp(request, sessionId, create) {
1591
1641
  }
1592
1642
  return answer;
1593
1643
  }
1644
+ var ROUTERS_KEY = /* @__PURE__ */ Symbol.for("@openma/deepseek-harness-acp/user-question-routers");
1645
+ var routers = globalThis[ROUTERS_KEY] ??= /* @__PURE__ */ new WeakMap();
1594
1646
  function installAcpUserQuestionProvider(service, options) {
1595
- return service.registerProvider({
1596
- async ask(request) {
1597
- if (!options.formSupported()) {
1598
- throw new UserQuestionError(
1599
- "the ACP client does not support form elicitation",
1600
- "CLIENT_UNSUPPORTED"
1601
- );
1602
- }
1603
- const sessionId = options.sessionIdForRequest(request);
1604
- if (sessionId === void 0) {
1647
+ const tracked = service[Service.tracker];
1648
+ const owner = typeof tracked === "object" && tracked !== null ? tracked : service;
1649
+ let router = routers.get(owner);
1650
+ if (router === void 0) {
1651
+ const routes = [];
1652
+ const disposeProvider = service.registerProvider({
1653
+ async ask(request) {
1654
+ for (let index = routes.length - 1; index >= 0; index -= 1) {
1655
+ const route = routes[index];
1656
+ const sessionId = route?.sessionIdForRequest(request);
1657
+ if (route === void 0 || sessionId === void 0) continue;
1658
+ if (!route.formSupported()) {
1659
+ throw new UserQuestionError(
1660
+ "the ACP client does not support form elicitation",
1661
+ "CLIENT_UNSUPPORTED"
1662
+ );
1663
+ }
1664
+ return askUserQuestionsOverAcp(request, sessionId, route.create);
1665
+ }
1605
1666
  throw new UserQuestionError(
1606
1667
  "ACP user interaction requires a live root session",
1607
1668
  "ASK_MISSING_AGENT"
1608
1669
  );
1609
1670
  }
1610
- return askUserQuestionsOverAcp(request, sessionId, options.create);
1611
- }
1612
- });
1671
+ });
1672
+ router = { routes, disposeProvider };
1673
+ routers.set(owner, router);
1674
+ }
1675
+ router.routes.push(options);
1676
+ let active = true;
1677
+ return () => {
1678
+ if (!active) return;
1679
+ active = false;
1680
+ const index = router.routes.indexOf(options);
1681
+ if (index >= 0) router.routes.splice(index, 1);
1682
+ if (router.routes.length !== 0) return;
1683
+ routers.delete(owner);
1684
+ router.disposeProvider();
1685
+ };
1613
1686
  }
1614
1687
 
1615
1688
  // src/bridge/presets.ts
@@ -2581,14 +2654,13 @@ async function apply(ctx, config = {}) {
2581
2654
  clientTerminalOutput = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["terminal_output"] === true : false;
2582
2655
  clientSubagentTranscript = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["subagent-transcript"] === true : false;
2583
2656
  clientElicitationForm = params.clientCapabilities?.elicitation?.form !== void 0 && params.clientCapabilities.elicitation.form !== null;
2584
- if (capsMeta !== null && typeof capsMeta === "object" && capsMeta["tuiInspect"] === true) {
2585
- tuiClient.advertised = true;
2586
- }
2657
+ tuiClient.advertised = advertisesCordis(capsMeta);
2587
2658
  const providers = await listProviderRoutes();
2588
2659
  return {
2589
2660
  protocolVersion: typeof requested === "number" && requested >= 1 && requested < PROTOCOL_VERSION ? requested : PROTOCOL_VERSION,
2590
2661
  agentInfo: { name: "dsh-acp", title: "DeepSeek Harness", version: VERSION },
2591
2662
  agentCapabilities: {
2663
+ _meta: { dsh: { cordis: { ...CORDIS_CAPABILITY } } },
2592
2664
  loadSession: true,
2593
2665
  promptCapabilities: {
2594
2666
  image: attachmentIngestOf(ctx.get("attachments")) !== void 0,
@@ -3082,20 +3154,23 @@ async function apply(ctx, config = {}) {
3082
3154
 
3083
3155
  // src/bundle.ts
3084
3156
  init_self_harness();
3085
- var name2 = name;
3157
+ var name2 = "acp-bridge";
3086
3158
  var inject2 = inject;
3087
- function apply2(ctx, config) {
3088
- apply(ctx, {
3089
- ...config.provider !== void 0 ? { provider: config.provider } : {},
3090
- ...config.model !== void 0 ? { model: config.model } : {},
3091
- ...config.models !== void 0 ? { models: config.models } : {},
3092
- ...config.maxTokens !== void 0 ? { maxTokens: config.maxTokens } : {},
3093
- ...config.permissionMode !== void 0 ? { permissionMode: config.permissionMode } : {},
3094
- harness: selfHarness()
3095
- });
3159
+ function nodeAcpStream(input, output) {
3160
+ return ndJsonStream2(
3161
+ Writable2.toWeb(output),
3162
+ Readable2.toWeb(input)
3163
+ );
3164
+ }
3165
+ function apply2(ctx, config = {}) {
3166
+ const stream = nodeAcpStream(process.stdin, process.stdout);
3167
+ const server = ctx.get("acpServer");
3168
+ if (server !== void 0) return server.connect(stream);
3169
+ return ctx.plugin(bridge_exports, { ...config, stream, harness: selfHarness() });
3096
3170
  }
3097
3171
  export {
3098
3172
  apply2 as apply,
3099
3173
  inject2 as inject,
3100
- name2 as name
3174
+ name2 as name,
3175
+ nodeAcpStream
3101
3176
  };
package/dist/index.js CHANGED
@@ -135,9 +135,9 @@ function resolveHost(explicit) {
135
135
  const globalNpm = hostFromGlobalNpm();
136
136
  if (globalNpm !== void 0) return globalNpm;
137
137
  probed.push("npm root -g");
138
- const own = hostAt(dirname(fileURLToPath(import.meta.url)), "dsh-acp package tree (vendored)");
138
+ const own = hostAt(dirname(fileURLToPath(import.meta.url)), "dsh-acp package tree (npm peer)");
139
139
  if (own !== void 0) return own;
140
- probed.push("dsh-acp package tree (vendored)");
140
+ probed.push("dsh-acp package tree (npm peer)");
141
141
  throw new HarnessNotFoundError(probed);
142
142
  }
143
143
 
@@ -151,13 +151,19 @@ function ownRoot() {
151
151
  return dirname2(createRequire(import.meta.url).resolve("../package.json"));
152
152
  }
153
153
  var OWN_BRIDGE_SPECIFIER = "@openma/deepseek-harness-acp/bridge";
154
- function rewriteBridgeRows(row, absoluteEntry) {
155
- if (row["name"] === OWN_BRIDGE_SPECIFIER) row["name"] = absoluteEntry;
154
+ var OWN_SERVER_SPECIFIER = "@openma/deepseek-harness-acp/server";
155
+ var OWN_PLUGIN_SPECIFIER = "@openma/deepseek-harness-acp/plugin";
156
+ var OWN_STDIO_SPECIFIER = "@openma/deepseek-harness-acp/stdio";
157
+ function rewriteOwnRows(row, entries) {
158
+ if (row["name"] === OWN_BRIDGE_SPECIFIER) row["name"] = entries.bridge;
159
+ if (row["name"] === OWN_SERVER_SPECIFIER) row["name"] = entries.server;
160
+ if (row["name"] === OWN_PLUGIN_SPECIFIER) row["name"] = entries.plugin;
161
+ if (row["name"] === OWN_STDIO_SPECIFIER) row["name"] = entries.stdio;
156
162
  const insert = row["insert"];
157
163
  if (Array.isArray(insert)) {
158
164
  for (const nested of insert) {
159
165
  if (nested !== null && typeof nested === "object") {
160
- rewriteBridgeRows(nested, absoluteEntry);
166
+ rewriteOwnRows(nested, entries);
161
167
  }
162
168
  }
163
169
  }
@@ -231,6 +237,12 @@ async function bootAcpProfile(host, overrides) {
231
237
  let bareModuleBaseUrl = pathToFileURL2(dshDir + sep2).href;
232
238
  const distBridge = join2(ownRoot(), "dist", "bridge.js");
233
239
  const bridgeEntry = import.meta.url.endsWith(".ts") || !existsSync2(distBridge) ? join2(ownRoot(), "src", "bundle.ts") : distBridge;
240
+ const distServer = join2(ownRoot(), "dist", "server.js");
241
+ const serverEntry = import.meta.url.endsWith(".ts") || !existsSync2(distServer) ? join2(ownRoot(), "src", "server.ts") : distServer;
242
+ const distPlugin = join2(ownRoot(), "dist", "plugin.js");
243
+ const pluginEntry = import.meta.url.endsWith(".ts") || !existsSync2(distPlugin) ? join2(ownRoot(), "src", "plugin.ts") : distPlugin;
244
+ const distStdio = join2(ownRoot(), "dist", "stdio.js");
245
+ const stdioEntry = import.meta.url.endsWith(".ts") || !existsSync2(distStdio) ? join2(ownRoot(), "src", "stdio.ts") : distStdio;
234
246
  const realProfileDir = join2(home, "profiles", "acp");
235
247
  if (existsSync2(join2(realProfileDir, "package.json"))) {
236
248
  appBoot.healProfilesModuleFallback(dshPkgPath);
@@ -255,7 +267,14 @@ async function bootAcpProfile(host, overrides) {
255
267
  bundlePatches.push(...loadBundleLayer(appBoot, bundle));
256
268
  logDebug(`profile: added bundle ${bundle}`);
257
269
  }
258
- for (const row of bundlePatches) rewriteBridgeRows(row, bridgeEntry);
270
+ for (const row of bundlePatches) {
271
+ rewriteOwnRows(row, {
272
+ bridge: bridgeEntry,
273
+ server: serverEntry,
274
+ plugin: pluginEntry,
275
+ stdio: stdioEntry
276
+ });
277
+ }
259
278
  const homePatchPath = join2(home, "cordis.patch.yml");
260
279
  const homePatches = appBoot.loadOptionalPatches(BIN, homePatchPath) ?? [];
261
280
  const rows = /* @__PURE__ */ new Map();