@openma/deepseek-harness-acp 0.4.13 → 0.4.15

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
@@ -31,13 +31,13 @@ touch your editor config — it reuses the key you saved in the dsh Web UI, or
31
31
 
32
32
  ## Two entry points, one embeddable plugin
33
33
 
34
- | | **A · Standalone server** | **B · dsh profile plugin** |
34
+ | | **A · dsh profile plugin (recommended)** | **B · Standalone server** |
35
35
  |---|---|---|
36
- | Best for | Getting started in one command | Living inside your dsh setup |
37
- | Install | `npm i -g @openma/deepseek-harness-acp` | `dsh plugin --profile acp add -w @openma/deepseek-harness-acp` |
38
- | Zed runs | `dsh-acp` | `dsh --profile acp` |
39
- | Harness | Your installed dsh — or the npm-installed peer when none exists | The dsh that owns the profile |
40
- | Composition | dsh-base + this bundle (profile machinery booted in-process) | dsh-base + this bundle + your profile's own patches |
36
+ | Best for | Normal installation and upgrades | Connecting an ACP client without managing a dsh profile |
37
+ | Install | `dsh plugin --profile acp add @openma/deepseek-harness-acp@latest` | `npm i -g @openma/deepseek-harness-acp` |
38
+ | Zed runs | `dsh --profile acp` | `dsh-acp` |
39
+ | Harness | The dsh that owns the profile | Your installed dsh — or the npm-installed peer when none exists |
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,
43
43
  and session logs as `dsh web` — conversations started in the Web UI can be
@@ -54,55 +54,78 @@ plugin used by other dsh applications: one Host composition can expose the
54
54
  same sessions, tools, presets, skills, and persistence through a transport
55
55
  chosen by the surface.
56
56
 
57
- ### A · Standalone server
57
+ ### A · dsh profile plugin (recommended)
58
58
 
59
59
  ```bash
60
- npm install -g @openma/deepseek-harness-acp
61
- dsh-acp login # interactive; or save the key in the dsh Web UI
60
+ npm install -g @deepseek-ai/dsh
61
+ dsh web # save your API key once
62
+ dsh plugin --profile acp add @openma/deepseek-harness-acp@latest
62
63
  ```
63
64
 
64
65
  ```jsonc
65
66
  // Zed settings.json
66
67
  {
67
68
  "agent_servers": {
68
- "DeepSeek Harness": { "command": "dsh-acp" }
69
+ "DeepSeek Harness": { "command": "dsh", "args": ["--profile", "acp"] }
69
70
  }
70
71
  }
71
72
  ```
72
73
 
73
- Self-contained: it finds your DeepSeek Harness via `--dsh-path` / `DSH_PATH`,
74
- its own tree, `./node_modules`, `dsh` on PATH, or `npm root -g` — and ships a
75
- npm-installed harness peer as the **last** candidate, so it works out of the box
76
- and always prefers the dsh you installed. When a real
77
- `$DSH_HOME/profiles/acp` exists, that profile owns the composition.
74
+ The plugin command creates `$DSH_HOME/profiles/acp`, installs or upgrades the
75
+ adapter, and registers its `dsh.bundle` patch. The bridge mounts over
76
+ `@deepseek-ai/dsh-base` — the same product baseline as `dsh web`, with the
77
+ module-reload watcher off. Extend the profile in
78
+ `$DSH_HOME/profiles/acp/cordis.patch.yml` like any other dsh profile. A global
79
+ `dsh-acp` installation is not required for this path.
78
80
 
79
- ### B · dsh profile plugin
81
+ ### B · Standalone server
80
82
 
81
83
  ```bash
82
- npm install -g @deepseek-ai/dsh
83
- dsh web # save your API key once
84
- dsh plugin --profile acp add -w @openma/deepseek-harness-acp
84
+ npm install -g @openma/deepseek-harness-acp
85
+ dsh-acp login # interactive; or save the key in the dsh Web UI
85
86
  ```
86
87
 
87
88
  ```jsonc
88
89
  // Zed settings.json
89
90
  {
90
91
  "agent_servers": {
91
- "DeepSeek Harness": { "command": "dsh", "args": ["--profile", "acp"] }
92
+ "DeepSeek Harness": { "command": "dsh-acp" }
92
93
  }
93
94
  }
94
95
  ```
95
96
 
96
- This creates `$DSH_HOME/profiles/acp` and registers the package's
97
- `dsh.bundle` patch: the bridge mounts over `@deepseek-ai/dsh-base` — the same
98
- product baseline as `dsh web`, with the module-reload watcher off. Extend the
99
- profile in `$DSH_HOME/profiles/acp/cordis.patch.yml` like any other dsh
100
- profile.
97
+ The standalone binary finds DeepSeek Harness via `--dsh-path` / `DSH_PATH`,
98
+ its own tree, `./node_modules`, `dsh` on PATH, or `npm root -g`. It ships an
99
+ npm-installed harness peer as the **last** candidate, so it still prefers the
100
+ dsh you installed. When a real `$DSH_HOME/profiles/acp` exists, that profile
101
+ owns the composition.
101
102
 
102
103
  ## Plugin and extension model
103
104
 
104
105
  There are two independent ways to extend an ACP-backed surface.
105
106
 
107
+ To use portable Agent Plugins, Codex plugins, Claude Code plugins, or Pi
108
+ packages through an ACP client, add the
109
+ [Agent Plugins Bridge](https://github.com/openma-ai/dsh-agents-plugins-bridge) to the
110
+ same profile:
111
+
112
+ ```sh
113
+ dsh plugin --profile acp add @openma/dsh-agents-plugins-bridge@latest
114
+ ```
115
+
116
+ The Bridge contributes ordinary Host rows. Imported commands, skills, tools,
117
+ hooks, MCP connections, agents, and Pi extensions therefore reach ACP through
118
+ this adapter's existing projections; there is no ACP-specific plugin import
119
+ runtime. The Bridge's Web management panel and MCP Apps HTML renderer remain
120
+ Web surfaces and are not sent over ACP.
121
+
122
+ For extensions that need a session-owned background lifecycle without an open
123
+ terminal UI, use
124
+ [Martty owner](https://github.com/openma-ai/deepseek-harness-tui/blob/main/README.en.md#martty-owner-long-lived-headless-acp--pi-rpc).
125
+ It is a generic ACP `rpc` client: this package remains the server/transport,
126
+ while Martty owns the long-lived Session and explicit startup/shutdown slash
127
+ commands.
128
+
106
129
  ### Extend the Host composition
107
130
 
108
131
  The ACP adapter rides the Cordis tree that the profile already owns. Add dsh
package/dist/bridge.js CHANGED
@@ -961,6 +961,35 @@ function buildReplay(events) {
961
961
  return { updates, title, contextWindow: projection.contextWindow };
962
962
  }
963
963
 
964
+ // src/bridge/latest-publication.ts
965
+ var LatestPublication = class {
966
+ revisions = /* @__PURE__ */ new Map();
967
+ async run(key, produce, publish) {
968
+ const revision = (this.revisions.get(key) ?? 0) + 1;
969
+ this.revisions.set(key, revision);
970
+ const value = await produce();
971
+ if (this.revisions.get(key) !== revision) return;
972
+ publish(value);
973
+ }
974
+ invalidate(key) {
975
+ this.revisions.set(key, (this.revisions.get(key) ?? 0) + 1);
976
+ }
977
+ };
978
+
979
+ // src/bridge/interaction-mode.ts
980
+ function interactionModeFromClientMeta(meta) {
981
+ if (meta === null || typeof meta !== "object") return void 0;
982
+ const dsh = meta["dsh"];
983
+ if (dsh === null || typeof dsh !== "object") return void 0;
984
+ const interaction = dsh["interaction"];
985
+ if (interaction === null || typeof interaction !== "object") return void 0;
986
+ const mode = interaction["mode"];
987
+ return mode === "interactive" || mode === "rpc" ? mode : void 0;
988
+ }
989
+ function withInteractionMode(options, mode) {
990
+ return mode === void 0 ? options : { ...options, interactionMode: mode };
991
+ }
992
+
964
993
  // src/bridge/prompt.ts
965
994
  function deliverPrompt(target, message, running) {
966
995
  if (running) {
@@ -1767,6 +1796,7 @@ async function apply3(ctx, config = {}) {
1767
1796
  const { createUserMessage: createUserMessage2, errorChain: errorChain2, sessionId: SessionId2, foldSessionTitle: foldSessionTitle2, setSandboxMode: setSandboxMode2 } = harness;
1768
1797
  const SANDBOX_MODES2 = harness.sandboxModes;
1769
1798
  const sessions = /* @__PURE__ */ new Map();
1799
+ const commandPublications = new LatestPublication();
1770
1800
  const subagentByChild = /* @__PURE__ */ new Map();
1771
1801
  const subagentByRun = /* @__PURE__ */ new Map();
1772
1802
  const watchedSubagentParents = /* @__PURE__ */ new WeakSet();
@@ -1775,6 +1805,7 @@ async function apply3(ctx, config = {}) {
1775
1805
  let clientTerminalOutput = false;
1776
1806
  let clientSubagentTranscript = false;
1777
1807
  let clientElicitationForm = false;
1808
+ let clientInteractionMode;
1778
1809
  const tuiClient = { advertised: false };
1779
1810
  const rpc = new AcpRpc();
1780
1811
  const findAgent = (agentId) => {
@@ -2003,11 +2034,11 @@ async function apply3(ctx, config = {}) {
2003
2034
  'no credential found for this provider: call authenticate with `_meta["api-key"].apiKey` or `_meta.gateway`, use the browser method, run `dsh-acp login`, or save a key in the dsh Web UI (Settings \u2192 Models)'
2004
2035
  );
2005
2036
  };
2006
- const agentOptionsFor = (model, provider) => ({
2037
+ const agentOptionsFor = (model, provider) => withInteractionMode({
2007
2038
  ...provider !== void 0 ? { provider } : config.provider !== void 0 ? { provider: config.provider } : {},
2008
2039
  ...model !== void 0 ? { model } : {},
2009
2040
  ...config.maxTokens !== void 0 ? { maxTokens: config.maxTokens } : {}
2010
- });
2041
+ }, clientInteractionMode);
2011
2042
  const ownedRecord = (agent) => {
2012
2043
  const record = sessions.get(String(agent.session.id));
2013
2044
  return record?.agent === agent ? record : void 0;
@@ -2481,12 +2512,20 @@ async function apply3(ctx, config = {}) {
2481
2512
  const publishCommands = (sessionId, record) => {
2482
2513
  const target = record ?? sessions.get(sessionId);
2483
2514
  if (target === void 0) return;
2484
- void availableCommandsFor(target).then((availableCommands) => {
2515
+ void commandPublications.run(sessionId, () => availableCommandsFor(target), (availableCommands) => {
2516
+ if (sessions.get(sessionId) !== target) return;
2517
+ logDebug(
2518
+ `available commands ${sessionId}: ${availableCommands.map((command) => command.name).join(", ")}`
2519
+ );
2485
2520
  notify(sessionId, { sessionUpdate: "available_commands_update", availableCommands });
2486
2521
  }).catch((error) => {
2487
2522
  logWarn(`publishing commands failed: ${String(error)}`);
2488
2523
  });
2489
2524
  };
2525
+ ctx.on("commands/change", () => {
2526
+ logDebug(`commands/change: ${sessions.size} live ACP session(s)`);
2527
+ for (const [sessionId, record] of sessions) publishCommands(sessionId, record);
2528
+ });
2490
2529
  const publishConfigOptions = (sessionId, record) => {
2491
2530
  void configOptions(record).then((options) => {
2492
2531
  notify(sessionId, {
@@ -2699,6 +2738,7 @@ async function apply3(ctx, config = {}) {
2699
2738
  const capsMeta = params.clientCapabilities?.["_meta"];
2700
2739
  clientTerminalOutput = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["terminal_output"] === true : false;
2701
2740
  clientSubagentTranscript = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["subagent-transcript"] === true : false;
2741
+ clientInteractionMode = interactionModeFromClientMeta(capsMeta);
2702
2742
  clientElicitationForm = params.clientCapabilities?.elicitation?.form !== void 0 && params.clientCapabilities.elicitation.form !== null;
2703
2743
  tuiClient.advertised = advertisesCordis(capsMeta);
2704
2744
  const providers = await listProviderRoutes();
package/dist/index.js CHANGED
@@ -44,6 +44,7 @@ ${probed.map((p) => ` ${p}`).join("\n")}` : ""
44
44
  }
45
45
  };
46
46
  var ANCHOR = "@deepseek-ai/dsh-agent";
47
+ var PROFILE_LAUNCHER = "@deepseek-ai/dsh";
47
48
  function packageDirFrom(base, name) {
48
49
  let dir = resolve(base);
49
50
  for (; ; ) {
@@ -66,7 +67,8 @@ function versionOf(packageDir) {
66
67
  }
67
68
  function hostAt(base, source) {
68
69
  const anchor = packageDirFrom(base, ANCHOR);
69
- if (anchor === void 0) return void 0;
70
+ const launcher = packageDirFrom(base, PROFILE_LAUNCHER);
71
+ if (anchor === void 0 || launcher === void 0) return void 0;
70
72
  return { base: resolve(base), version: versionOf(anchor), source };
71
73
  }
72
74
  function hostFromExplicit(explicit) {
package/dist/plugin.js CHANGED
@@ -962,6 +962,35 @@ function buildReplay(events) {
962
962
  return { updates, title, contextWindow: projection.contextWindow };
963
963
  }
964
964
 
965
+ // src/bridge/latest-publication.ts
966
+ var LatestPublication = class {
967
+ revisions = /* @__PURE__ */ new Map();
968
+ async run(key, produce, publish) {
969
+ const revision = (this.revisions.get(key) ?? 0) + 1;
970
+ this.revisions.set(key, revision);
971
+ const value = await produce();
972
+ if (this.revisions.get(key) !== revision) return;
973
+ publish(value);
974
+ }
975
+ invalidate(key) {
976
+ this.revisions.set(key, (this.revisions.get(key) ?? 0) + 1);
977
+ }
978
+ };
979
+
980
+ // src/bridge/interaction-mode.ts
981
+ function interactionModeFromClientMeta(meta) {
982
+ if (meta === null || typeof meta !== "object") return void 0;
983
+ const dsh = meta["dsh"];
984
+ if (dsh === null || typeof dsh !== "object") return void 0;
985
+ const interaction = dsh["interaction"];
986
+ if (interaction === null || typeof interaction !== "object") return void 0;
987
+ const mode = interaction["mode"];
988
+ return mode === "interactive" || mode === "rpc" ? mode : void 0;
989
+ }
990
+ function withInteractionMode(options, mode) {
991
+ return mode === void 0 ? options : { ...options, interactionMode: mode };
992
+ }
993
+
965
994
  // src/bridge/prompt.ts
966
995
  function deliverPrompt(target, message, running) {
967
996
  if (running) {
@@ -1768,6 +1797,7 @@ async function apply3(ctx, config = {}) {
1768
1797
  const { createUserMessage: createUserMessage2, errorChain: errorChain2, sessionId: SessionId2, foldSessionTitle: foldSessionTitle2, setSandboxMode: setSandboxMode2 } = harness;
1769
1798
  const SANDBOX_MODES2 = harness.sandboxModes;
1770
1799
  const sessions = /* @__PURE__ */ new Map();
1800
+ const commandPublications = new LatestPublication();
1771
1801
  const subagentByChild = /* @__PURE__ */ new Map();
1772
1802
  const subagentByRun = /* @__PURE__ */ new Map();
1773
1803
  const watchedSubagentParents = /* @__PURE__ */ new WeakSet();
@@ -1776,6 +1806,7 @@ async function apply3(ctx, config = {}) {
1776
1806
  let clientTerminalOutput = false;
1777
1807
  let clientSubagentTranscript = false;
1778
1808
  let clientElicitationForm = false;
1809
+ let clientInteractionMode;
1779
1810
  const tuiClient = { advertised: false };
1780
1811
  const rpc = new AcpRpc();
1781
1812
  const findAgent = (agentId) => {
@@ -2004,11 +2035,11 @@ async function apply3(ctx, config = {}) {
2004
2035
  'no credential found for this provider: call authenticate with `_meta["api-key"].apiKey` or `_meta.gateway`, use the browser method, run `dsh-acp login`, or save a key in the dsh Web UI (Settings \u2192 Models)'
2005
2036
  );
2006
2037
  };
2007
- const agentOptionsFor = (model, provider) => ({
2038
+ const agentOptionsFor = (model, provider) => withInteractionMode({
2008
2039
  ...provider !== void 0 ? { provider } : config.provider !== void 0 ? { provider: config.provider } : {},
2009
2040
  ...model !== void 0 ? { model } : {},
2010
2041
  ...config.maxTokens !== void 0 ? { maxTokens: config.maxTokens } : {}
2011
- });
2042
+ }, clientInteractionMode);
2012
2043
  const ownedRecord = (agent) => {
2013
2044
  const record = sessions.get(String(agent.session.id));
2014
2045
  return record?.agent === agent ? record : void 0;
@@ -2482,12 +2513,20 @@ async function apply3(ctx, config = {}) {
2482
2513
  const publishCommands = (sessionId, record) => {
2483
2514
  const target = record ?? sessions.get(sessionId);
2484
2515
  if (target === void 0) return;
2485
- void availableCommandsFor(target).then((availableCommands) => {
2516
+ void commandPublications.run(sessionId, () => availableCommandsFor(target), (availableCommands) => {
2517
+ if (sessions.get(sessionId) !== target) return;
2518
+ logDebug(
2519
+ `available commands ${sessionId}: ${availableCommands.map((command) => command.name).join(", ")}`
2520
+ );
2486
2521
  notify(sessionId, { sessionUpdate: "available_commands_update", availableCommands });
2487
2522
  }).catch((error) => {
2488
2523
  logWarn(`publishing commands failed: ${String(error)}`);
2489
2524
  });
2490
2525
  };
2526
+ ctx.on("commands/change", () => {
2527
+ logDebug(`commands/change: ${sessions.size} live ACP session(s)`);
2528
+ for (const [sessionId, record] of sessions) publishCommands(sessionId, record);
2529
+ });
2491
2530
  const publishConfigOptions = (sessionId, record) => {
2492
2531
  void configOptions(record).then((options) => {
2493
2532
  notify(sessionId, {
@@ -2700,6 +2739,7 @@ async function apply3(ctx, config = {}) {
2700
2739
  const capsMeta = params.clientCapabilities?.["_meta"];
2701
2740
  clientTerminalOutput = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["terminal_output"] === true : false;
2702
2741
  clientSubagentTranscript = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["subagent-transcript"] === true : false;
2742
+ clientInteractionMode = interactionModeFromClientMeta(capsMeta);
2703
2743
  clientElicitationForm = params.clientCapabilities?.elicitation?.form !== void 0 && params.clientCapabilities.elicitation.form !== null;
2704
2744
  tuiClient.advertised = advertisesCordis(capsMeta);
2705
2745
  const providers = await listProviderRoutes();
package/dist/server.js CHANGED
@@ -957,6 +957,35 @@ function buildReplay(events) {
957
957
  return { updates, title, contextWindow: projection.contextWindow };
958
958
  }
959
959
 
960
+ // src/bridge/latest-publication.ts
961
+ var LatestPublication = class {
962
+ revisions = /* @__PURE__ */ new Map();
963
+ async run(key, produce, publish) {
964
+ const revision = (this.revisions.get(key) ?? 0) + 1;
965
+ this.revisions.set(key, revision);
966
+ const value = await produce();
967
+ if (this.revisions.get(key) !== revision) return;
968
+ publish(value);
969
+ }
970
+ invalidate(key) {
971
+ this.revisions.set(key, (this.revisions.get(key) ?? 0) + 1);
972
+ }
973
+ };
974
+
975
+ // src/bridge/interaction-mode.ts
976
+ function interactionModeFromClientMeta(meta) {
977
+ if (meta === null || typeof meta !== "object") return void 0;
978
+ const dsh = meta["dsh"];
979
+ if (dsh === null || typeof dsh !== "object") return void 0;
980
+ const interaction = dsh["interaction"];
981
+ if (interaction === null || typeof interaction !== "object") return void 0;
982
+ const mode = interaction["mode"];
983
+ return mode === "interactive" || mode === "rpc" ? mode : void 0;
984
+ }
985
+ function withInteractionMode(options, mode) {
986
+ return mode === void 0 ? options : { ...options, interactionMode: mode };
987
+ }
988
+
960
989
  // src/bridge/prompt.ts
961
990
  function deliverPrompt(target, message, running) {
962
991
  if (running) {
@@ -1763,6 +1792,7 @@ async function apply3(ctx, config = {}) {
1763
1792
  const { createUserMessage: createUserMessage2, errorChain: errorChain2, sessionId: SessionId2, foldSessionTitle: foldSessionTitle2, setSandboxMode: setSandboxMode2 } = harness;
1764
1793
  const SANDBOX_MODES2 = harness.sandboxModes;
1765
1794
  const sessions = /* @__PURE__ */ new Map();
1795
+ const commandPublications = new LatestPublication();
1766
1796
  const subagentByChild = /* @__PURE__ */ new Map();
1767
1797
  const subagentByRun = /* @__PURE__ */ new Map();
1768
1798
  const watchedSubagentParents = /* @__PURE__ */ new WeakSet();
@@ -1771,6 +1801,7 @@ async function apply3(ctx, config = {}) {
1771
1801
  let clientTerminalOutput = false;
1772
1802
  let clientSubagentTranscript = false;
1773
1803
  let clientElicitationForm = false;
1804
+ let clientInteractionMode;
1774
1805
  const tuiClient = { advertised: false };
1775
1806
  const rpc = new AcpRpc();
1776
1807
  const findAgent = (agentId) => {
@@ -1999,11 +2030,11 @@ async function apply3(ctx, config = {}) {
1999
2030
  'no credential found for this provider: call authenticate with `_meta["api-key"].apiKey` or `_meta.gateway`, use the browser method, run `dsh-acp login`, or save a key in the dsh Web UI (Settings \u2192 Models)'
2000
2031
  );
2001
2032
  };
2002
- const agentOptionsFor = (model, provider) => ({
2033
+ const agentOptionsFor = (model, provider) => withInteractionMode({
2003
2034
  ...provider !== void 0 ? { provider } : config.provider !== void 0 ? { provider: config.provider } : {},
2004
2035
  ...model !== void 0 ? { model } : {},
2005
2036
  ...config.maxTokens !== void 0 ? { maxTokens: config.maxTokens } : {}
2006
- });
2037
+ }, clientInteractionMode);
2007
2038
  const ownedRecord = (agent) => {
2008
2039
  const record = sessions.get(String(agent.session.id));
2009
2040
  return record?.agent === agent ? record : void 0;
@@ -2477,12 +2508,20 @@ async function apply3(ctx, config = {}) {
2477
2508
  const publishCommands = (sessionId, record) => {
2478
2509
  const target = record ?? sessions.get(sessionId);
2479
2510
  if (target === void 0) return;
2480
- void availableCommandsFor(target).then((availableCommands) => {
2511
+ void commandPublications.run(sessionId, () => availableCommandsFor(target), (availableCommands) => {
2512
+ if (sessions.get(sessionId) !== target) return;
2513
+ logDebug(
2514
+ `available commands ${sessionId}: ${availableCommands.map((command) => command.name).join(", ")}`
2515
+ );
2481
2516
  notify(sessionId, { sessionUpdate: "available_commands_update", availableCommands });
2482
2517
  }).catch((error) => {
2483
2518
  logWarn(`publishing commands failed: ${String(error)}`);
2484
2519
  });
2485
2520
  };
2521
+ ctx.on("commands/change", () => {
2522
+ logDebug(`commands/change: ${sessions.size} live ACP session(s)`);
2523
+ for (const [sessionId, record] of sessions) publishCommands(sessionId, record);
2524
+ });
2486
2525
  const publishConfigOptions = (sessionId, record) => {
2487
2526
  void configOptions(record).then((options) => {
2488
2527
  notify(sessionId, {
@@ -2695,6 +2734,7 @@ async function apply3(ctx, config = {}) {
2695
2734
  const capsMeta = params.clientCapabilities?.["_meta"];
2696
2735
  clientTerminalOutput = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["terminal_output"] === true : false;
2697
2736
  clientSubagentTranscript = capsMeta !== null && typeof capsMeta === "object" ? capsMeta["subagent-transcript"] === true : false;
2737
+ clientInteractionMode = interactionModeFromClientMeta(capsMeta);
2698
2738
  clientElicitationForm = params.clientCapabilities?.elicitation?.form !== void 0 && params.clientCapabilities.elicitation.form !== null;
2699
2739
  tuiClient.advertised = advertisesCordis(capsMeta);
2700
2740
  const providers = await listProviderRoutes();
package/package.json CHANGED
@@ -3,12 +3,12 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.4.13",
6
+ "version": "0.4.15",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/openma-ai/deepseek-harness-acp.git"
10
10
  },
11
- "homepage": "https://github.com/openma-ai/deepseek-harness-acp#readme",
11
+ "homepage": "https://dshsuite.dev/#other-products",
12
12
  "bugs": {
13
13
  "url": "https://github.com/openma-ai/deepseek-harness-acp/issues"
14
14
  },
@@ -110,7 +110,8 @@
110
110
  "pnpm": "11.22.0",
111
111
  "tsx": "^4.23.1",
112
112
  "typescript": "^7.0.2",
113
- "vitest": "^4.1.10"
113
+ "vitest": "^4.1.10",
114
+ "yaml": "^2.9.0"
114
115
  },
115
116
  "dependencies": {
116
117
  "@agentclientprotocol/sdk": "^1.3.0",