@openma/deepseek-harness-acp 0.4.19 → 0.4.21

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/cordis.patch.yml CHANGED
@@ -116,7 +116,7 @@
116
116
  name: '@openma/deepseek-harness-acp/plugin'
117
117
  config:
118
118
  model: !!js process.env.DSH_MODEL
119
- permissionMode: !!js process.env.DSH_PERMISSION_MODE ?? 'workspace-write'
119
+ permissionMode: !!js process.env.DSH_PERMISSION_MODE
120
120
 
121
121
  # The ordinary ACP profile owns stdio. Embedded surfaces replace only this
122
122
  # adapter and reuse the exact same plugin contract above.
package/dist/bridge.js CHANGED
@@ -69,6 +69,7 @@ import {
69
69
  RequestError
70
70
  } from "@agentclientprotocol/sdk";
71
71
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
72
+ import { ReasoningEffortId } from "@deepseek-ai/dsh-llm";
72
73
 
73
74
  // src/version.ts
74
75
  import { createRequire } from "node:module";
@@ -1160,6 +1161,7 @@ ${contextBlock(resource.uri, resource.text)}
1160
1161
  var CORDIS_PROTOCOL = 0;
1161
1162
  var CORDIS_CAPABILITY = Object.freeze({ protocol: CORDIS_PROTOCOL });
1162
1163
  var CORDIS_METHODS = Object.freeze({
1164
+ pluginsStaticList: "_dsh/plugins/list",
1163
1165
  inspectSync: "_dsh/cordis/inspect/sync",
1164
1166
  inspectResolve: "_dsh/cordis/inspect/resolve",
1165
1167
  inspectQuery: "_dsh/cordis/inspect/query",
@@ -1298,8 +1300,27 @@ __export(tui_client_plugin_exports, {
1298
1300
  });
1299
1301
 
1300
1302
  // src/bridge/tui-client.ts
1303
+ var FIBER_PHASE = ["pending", "loading", "active", "failed", null, "unloading"];
1301
1304
  function installTuiClientPlane(ctx, rpc, opts) {
1302
1305
  const { findAgent, advertisement } = opts;
1306
+ ctx.effect(
1307
+ () => rpc.registerMethod(CORDIS_METHODS.pluginsStaticList, () => {
1308
+ const loader = optionalLoader(ctx);
1309
+ if (loader === void 0) throw new Error("this agent has no plugin Loader");
1310
+ const entries = [];
1311
+ for (const entry of loader.entries()) {
1312
+ if (entry.options.group) continue;
1313
+ entries.push({
1314
+ entryId: entry.id,
1315
+ moduleName: entry.options.name,
1316
+ enabled: !entry.disabled,
1317
+ fiberPhase: entry.fiber === void 0 ? null : FIBER_PHASE[entry.fiber.state] ?? null
1318
+ });
1319
+ }
1320
+ return { entries };
1321
+ }),
1322
+ "acp-bridge: list-static-plugins"
1323
+ );
1303
1324
  ctx.effect(
1304
1325
  () => rpc.registerMethod(CORDIS_METHODS.inspectSync, (params) => {
1305
1326
  const inspect = optionalInspect(ctx);
@@ -1495,6 +1516,14 @@ function optionalInspect(ctx) {
1495
1516
  return void 0;
1496
1517
  }
1497
1518
  }
1519
+ function optionalLoader(ctx) {
1520
+ try {
1521
+ const value = ctx.get("loader");
1522
+ return value !== void 0 && typeof value.entries === "function" ? value : void 0;
1523
+ } catch {
1524
+ return void 0;
1525
+ }
1526
+ }
1498
1527
  function optionalRunner(ctx) {
1499
1528
  try {
1500
1529
  const value = ctx.get("dynamicCordisRunner");
@@ -1841,6 +1870,19 @@ async function apply3(ctx, config = {}) {
1841
1870
  return {};
1842
1871
  }
1843
1872
  };
1873
+ const saveDefaultSelection = async (record) => {
1874
+ const selected = ensureSelection(record)?.current;
1875
+ if (selected === void 0) return;
1876
+ try {
1877
+ await agentDefaultModel.saveSelection({
1878
+ provider: selected.provider,
1879
+ model: selected.model,
1880
+ ...selected.reasoningEffort === void 0 ? {} : { reasoningEffort: ReasoningEffortId(selected.reasoningEffort) }
1881
+ });
1882
+ } catch (error) {
1883
+ logWarn(`model switch applied to the session but was not saved as the default: ${String(error)}`);
1884
+ }
1885
+ };
1844
1886
  const defaultProvider = () => config.provider ?? defaultSelection().provider;
1845
1887
  const encodeChoice = (provider, model) => provider === void 0 || provider === defaultProvider() ? model : `${provider}::${model}`;
1846
1888
  const decodeChoice = (value) => {
@@ -1992,23 +2034,21 @@ async function apply3(ctx, config = {}) {
1992
2034
  delete record.provider;
1993
2035
  }
1994
2036
  delete record.selection;
1995
- ensureSelection(record);
1996
- if (record.effort !== void 0) {
1997
- const route = routeOf(record);
1998
- const catalog = await effortCatalog(route.provider, route.model);
1999
- if (catalog?.efforts.some((effort) => effort.id === record.effort) === true && route.provider !== void 0 && route.model !== void 0) {
2000
- const selection = ensureSelection(record);
2001
- if (selection !== void 0) {
2002
- selection.current = {
2003
- provider: route.provider,
2004
- model: route.model,
2005
- reasoningEffort: record.effort
2006
- };
2007
- }
2008
- } else {
2009
- delete record.effort;
2010
- }
2037
+ const route = routeOf(record);
2038
+ const catalog = await effortCatalog(route.provider, route.model);
2039
+ if (record.effort !== void 0 && catalog?.efforts.some((effort2) => effort2.id === record.effort) !== true) {
2040
+ delete record.effort;
2041
+ }
2042
+ const effort = record.effort ?? catalog?.defaultEffort;
2043
+ const selection = ensureSelection(record);
2044
+ if (selection !== void 0 && route.provider !== void 0 && route.model !== void 0) {
2045
+ selection.current = {
2046
+ provider: route.provider,
2047
+ model: route.model,
2048
+ ...effort !== void 0 ? { reasoningEffort: effort } : {}
2049
+ };
2011
2050
  }
2051
+ await saveDefaultSelection(record);
2012
2052
  setApprovalPolicy(record, record.approvals);
2013
2053
  };
2014
2054
  const mutateSession = (record, mutation) => {
@@ -2860,9 +2900,14 @@ async function apply3(ctx, config = {}) {
2860
2900
  handle.agent,
2861
2901
  () => handle.dispose(),
2862
2902
  config.model,
2863
- config.permissionMode ?? "workspace-write"
2903
+ config.permissionMode ?? permissionService().defaultPreset
2864
2904
  );
2865
2905
  if (presetId !== void 0) record.preset = presetId;
2906
+ if (config.permissionMode !== void 0) {
2907
+ applyMode(record, String(sessionId), config.permissionMode);
2908
+ } else {
2909
+ syncPermissionState(record, String(sessionId));
2910
+ }
2866
2911
  ensureSelection(record);
2867
2912
  queueMicrotask(() => publishCommands(String(sessionId)));
2868
2913
  const options = await configOptions(record);
@@ -3065,6 +3110,7 @@ async function apply3(ctx, config = {}) {
3065
3110
  reasoningEffort: value
3066
3111
  };
3067
3112
  record.effort = value;
3113
+ await saveDefaultSelection(record);
3068
3114
  break;
3069
3115
  }
3070
3116
  case "collaboration_mode": {
package/dist/index.js CHANGED
@@ -297,18 +297,20 @@ async function bootAcpProfile(host, overrides) {
297
297
  if (process.env["DSH_TELEMETRY_DISABLED"] !== void 0 && rows.has("session-telemetry-otel")) {
298
298
  overlays.push({ id: "session-telemetry-otel", disabled: true });
299
299
  }
300
- const bridgeRow = rows.get("acp-bridge");
301
- if (overrides?.serve === false && bridgeRow !== void 0) {
300
+ const transportRow = rows.get("acp-bridge");
301
+ if (overrides?.serve === false && transportRow !== void 0) {
302
302
  overlays.push({ id: "acp-bridge", disabled: true });
303
303
  }
304
- if (overrides !== void 0 && bridgeRow !== void 0) {
304
+ const configRowId = rows.has("acp-plugin") ? "acp-plugin" : "acp-bridge";
305
+ const configRow = rows.get(configRowId);
306
+ if (overrides !== void 0 && configRow !== void 0) {
305
307
  const patch = {};
306
308
  if (overrides.provider !== void 0) patch["provider"] = overrides.provider;
307
309
  if (overrides.model !== void 0) patch["model"] = overrides.model;
308
310
  if (overrides.permissionMode !== void 0) patch["permissionMode"] = overrides.permissionMode;
309
311
  if (overrides.maxTokens !== void 0) patch["maxTokens"] = overrides.maxTokens;
310
312
  if (Object.keys(patch).length > 0) {
311
- overlays.push({ id: "acp-bridge", config: { ...bridgeRow.config ?? {}, ...patch } });
313
+ overlays.push({ id: configRowId, config: { ...configRow.config ?? {}, ...patch } });
312
314
  }
313
315
  }
314
316
  const allPatches = [...bundlePatches, ...profilePatches, ...homePatches, ...overlays];
@@ -518,9 +520,9 @@ function resolveSettings(argv) {
518
520
  const model = stringFlag(parsed, "model") ?? envString("DSH_MODEL");
519
521
  const modelsRaw = stringFlag(parsed, "models") ?? envString("DSH_ACP_MODELS");
520
522
  const models = (modelsRaw !== void 0 ? modelsRaw.split(",") : ["deepseek-v4-flash", "deepseek-v4-pro"]).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
521
- const permissionModeRaw = stringFlag(parsed, "permission-mode") ?? envString("DSH_PERMISSION_MODE") ?? "workspace-write";
522
- const permissionMode = PERMISSION_MODES.find((candidate) => candidate === permissionModeRaw);
523
- if (permissionMode === void 0) {
523
+ const permissionModeRaw = stringFlag(parsed, "permission-mode") ?? envString("DSH_PERMISSION_MODE");
524
+ const permissionMode = permissionModeRaw === void 0 ? void 0 : PERMISSION_MODES.find((candidate) => candidate === permissionModeRaw);
525
+ if (permissionModeRaw !== void 0 && permissionMode === void 0) {
524
526
  throw new SettingsError(
525
527
  `invalid --permission-mode: ${permissionModeRaw} (expected ${PERMISSION_MODES.join(" | ")})`
526
528
  );
@@ -577,7 +579,7 @@ Options:
577
579
  (DSH_ACP_MODELS, default deepseek-v4-flash,deepseek-v4-pro)
578
580
  --max-tokens <n> Per-request output-token cap (DSH_MAX_TOKENS)
579
581
  --permission-mode <mode> read-only | workspace-write | danger-full-access
580
- (DSH_PERMISSION_MODE, default workspace-write)
582
+ (DSH_PERMISSION_MODE; otherwise use the Host default)
581
583
  --session-root <dir> JSONL session store (DSH_SESSION_ROOT, default ~/.dsh-acp/sessions)
582
584
  --persona <text> System-prompt persona (DSH_SYSTEM_PROMPT)
583
585
  --reasoning-effort <level> off | high | max (DSH_REASONING_EFFORT, default high)
package/dist/plugin.js CHANGED
@@ -48,6 +48,7 @@ var init_self_harness = __esm({
48
48
  import { existsSync } from "node:fs";
49
49
  import { createRequire as createRequire2 } from "node:module";
50
50
  import { dirname, join } from "node:path";
51
+ import { pathToFileURL } from "node:url";
51
52
 
52
53
  // src/bridge/index.ts
53
54
  var bridge_exports = {};
@@ -70,6 +71,7 @@ import {
70
71
  RequestError
71
72
  } from "@agentclientprotocol/sdk";
72
73
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
74
+ import { ReasoningEffortId } from "@deepseek-ai/dsh-llm";
73
75
 
74
76
  // src/version.ts
75
77
  import { createRequire } from "node:module";
@@ -1161,6 +1163,7 @@ ${contextBlock(resource.uri, resource.text)}
1161
1163
  var CORDIS_PROTOCOL = 0;
1162
1164
  var CORDIS_CAPABILITY = Object.freeze({ protocol: CORDIS_PROTOCOL });
1163
1165
  var CORDIS_METHODS = Object.freeze({
1166
+ pluginsStaticList: "_dsh/plugins/list",
1164
1167
  inspectSync: "_dsh/cordis/inspect/sync",
1165
1168
  inspectResolve: "_dsh/cordis/inspect/resolve",
1166
1169
  inspectQuery: "_dsh/cordis/inspect/query",
@@ -1299,8 +1302,27 @@ __export(tui_client_plugin_exports, {
1299
1302
  });
1300
1303
 
1301
1304
  // src/bridge/tui-client.ts
1305
+ var FIBER_PHASE = ["pending", "loading", "active", "failed", null, "unloading"];
1302
1306
  function installTuiClientPlane(ctx, rpc, opts) {
1303
1307
  const { findAgent, advertisement } = opts;
1308
+ ctx.effect(
1309
+ () => rpc.registerMethod(CORDIS_METHODS.pluginsStaticList, () => {
1310
+ const loader = optionalLoader(ctx);
1311
+ if (loader === void 0) throw new Error("this agent has no plugin Loader");
1312
+ const entries = [];
1313
+ for (const entry of loader.entries()) {
1314
+ if (entry.options.group) continue;
1315
+ entries.push({
1316
+ entryId: entry.id,
1317
+ moduleName: entry.options.name,
1318
+ enabled: !entry.disabled,
1319
+ fiberPhase: entry.fiber === void 0 ? null : FIBER_PHASE[entry.fiber.state] ?? null
1320
+ });
1321
+ }
1322
+ return { entries };
1323
+ }),
1324
+ "acp-bridge: list-static-plugins"
1325
+ );
1304
1326
  ctx.effect(
1305
1327
  () => rpc.registerMethod(CORDIS_METHODS.inspectSync, (params) => {
1306
1328
  const inspect = optionalInspect(ctx);
@@ -1496,6 +1518,14 @@ function optionalInspect(ctx) {
1496
1518
  return void 0;
1497
1519
  }
1498
1520
  }
1521
+ function optionalLoader(ctx) {
1522
+ try {
1523
+ const value = ctx.get("loader");
1524
+ return value !== void 0 && typeof value.entries === "function" ? value : void 0;
1525
+ } catch {
1526
+ return void 0;
1527
+ }
1528
+ }
1499
1529
  function optionalRunner(ctx) {
1500
1530
  try {
1501
1531
  const value = ctx.get("dynamicCordisRunner");
@@ -1842,6 +1872,19 @@ async function apply3(ctx, config = {}) {
1842
1872
  return {};
1843
1873
  }
1844
1874
  };
1875
+ const saveDefaultSelection = async (record) => {
1876
+ const selected = ensureSelection(record)?.current;
1877
+ if (selected === void 0) return;
1878
+ try {
1879
+ await agentDefaultModel.saveSelection({
1880
+ provider: selected.provider,
1881
+ model: selected.model,
1882
+ ...selected.reasoningEffort === void 0 ? {} : { reasoningEffort: ReasoningEffortId(selected.reasoningEffort) }
1883
+ });
1884
+ } catch (error) {
1885
+ logWarn(`model switch applied to the session but was not saved as the default: ${String(error)}`);
1886
+ }
1887
+ };
1845
1888
  const defaultProvider = () => config.provider ?? defaultSelection().provider;
1846
1889
  const encodeChoice = (provider, model) => provider === void 0 || provider === defaultProvider() ? model : `${provider}::${model}`;
1847
1890
  const decodeChoice = (value) => {
@@ -1993,23 +2036,21 @@ async function apply3(ctx, config = {}) {
1993
2036
  delete record.provider;
1994
2037
  }
1995
2038
  delete record.selection;
1996
- ensureSelection(record);
1997
- if (record.effort !== void 0) {
1998
- const route = routeOf(record);
1999
- const catalog = await effortCatalog(route.provider, route.model);
2000
- if (catalog?.efforts.some((effort) => effort.id === record.effort) === true && route.provider !== void 0 && route.model !== void 0) {
2001
- const selection = ensureSelection(record);
2002
- if (selection !== void 0) {
2003
- selection.current = {
2004
- provider: route.provider,
2005
- model: route.model,
2006
- reasoningEffort: record.effort
2007
- };
2008
- }
2009
- } else {
2010
- delete record.effort;
2011
- }
2039
+ const route = routeOf(record);
2040
+ const catalog = await effortCatalog(route.provider, route.model);
2041
+ if (record.effort !== void 0 && catalog?.efforts.some((effort2) => effort2.id === record.effort) !== true) {
2042
+ delete record.effort;
2043
+ }
2044
+ const effort = record.effort ?? catalog?.defaultEffort;
2045
+ const selection = ensureSelection(record);
2046
+ if (selection !== void 0 && route.provider !== void 0 && route.model !== void 0) {
2047
+ selection.current = {
2048
+ provider: route.provider,
2049
+ model: route.model,
2050
+ ...effort !== void 0 ? { reasoningEffort: effort } : {}
2051
+ };
2012
2052
  }
2053
+ await saveDefaultSelection(record);
2013
2054
  setApprovalPolicy(record, record.approvals);
2014
2055
  };
2015
2056
  const mutateSession = (record, mutation) => {
@@ -2861,9 +2902,14 @@ async function apply3(ctx, config = {}) {
2861
2902
  handle.agent,
2862
2903
  () => handle.dispose(),
2863
2904
  config.model,
2864
- config.permissionMode ?? "workspace-write"
2905
+ config.permissionMode ?? permissionService().defaultPreset
2865
2906
  );
2866
2907
  if (presetId !== void 0) record.preset = presetId;
2908
+ if (config.permissionMode !== void 0) {
2909
+ applyMode(record, String(sessionId), config.permissionMode);
2910
+ } else {
2911
+ syncPermissionState(record, String(sessionId));
2912
+ }
2867
2913
  ensureSelection(record);
2868
2914
  queueMicrotask(() => publishCommands(String(sessionId)));
2869
2915
  const options = await configOptions(record);
@@ -3066,6 +3112,7 @@ async function apply3(ctx, config = {}) {
3066
3112
  reasoningEffort: value
3067
3113
  };
3068
3114
  record.effort = value;
3115
+ await saveDefaultSelection(record);
3069
3116
  break;
3070
3117
  }
3071
3118
  case "collaboration_mode": {
@@ -3283,6 +3330,16 @@ function apply4(ctx, config = {}) {
3283
3330
  // src/plugin.ts
3284
3331
  var name5 = "dsh-acp-plugin";
3285
3332
  var inject5 = [.../* @__PURE__ */ new Set([...inject3.filter((service) => service !== "agentPresets"), "loader"])];
3333
+ function resolvedHostModule(ctx, specifier) {
3334
+ const anchors = [ctx.baseUrl, import.meta.url].filter((value) => typeof value === "string");
3335
+ for (const anchor of anchors) {
3336
+ try {
3337
+ return pathToFileURL(createRequire2(anchor).resolve(specifier)).href;
3338
+ } catch {
3339
+ }
3340
+ }
3341
+ return specifier;
3342
+ }
3286
3343
  function shippedPresetRoot(ctx) {
3287
3344
  const anchors = [ctx.baseUrl, import.meta.url].filter((value) => typeof value === "string");
3288
3345
  for (const anchor of anchors) {
@@ -3297,7 +3354,7 @@ function shippedPresetRoot(ctx) {
3297
3354
  }
3298
3355
  async function mountService(ctx, service, specifier, config) {
3299
3356
  if (ctx.get(service) !== void 0) return;
3300
- const exports = await ctx.loader.import(specifier);
3357
+ const exports = await ctx.loader.import(resolvedHostModule(ctx, specifier));
3301
3358
  const plugin = ctx.loader.unwrapExports(exports);
3302
3359
  await ctx.plugin(plugin, config);
3303
3360
  if (ctx.get(service) === void 0) {
package/dist/server.js CHANGED
@@ -65,6 +65,7 @@ import {
65
65
  RequestError
66
66
  } from "@agentclientprotocol/sdk";
67
67
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
68
+ import { ReasoningEffortId } from "@deepseek-ai/dsh-llm";
68
69
 
69
70
  // src/version.ts
70
71
  import { createRequire } from "node:module";
@@ -1156,6 +1157,7 @@ ${contextBlock(resource.uri, resource.text)}
1156
1157
  var CORDIS_PROTOCOL = 0;
1157
1158
  var CORDIS_CAPABILITY = Object.freeze({ protocol: CORDIS_PROTOCOL });
1158
1159
  var CORDIS_METHODS = Object.freeze({
1160
+ pluginsStaticList: "_dsh/plugins/list",
1159
1161
  inspectSync: "_dsh/cordis/inspect/sync",
1160
1162
  inspectResolve: "_dsh/cordis/inspect/resolve",
1161
1163
  inspectQuery: "_dsh/cordis/inspect/query",
@@ -1294,8 +1296,27 @@ __export(tui_client_plugin_exports, {
1294
1296
  });
1295
1297
 
1296
1298
  // src/bridge/tui-client.ts
1299
+ var FIBER_PHASE = ["pending", "loading", "active", "failed", null, "unloading"];
1297
1300
  function installTuiClientPlane(ctx, rpc, opts) {
1298
1301
  const { findAgent, advertisement } = opts;
1302
+ ctx.effect(
1303
+ () => rpc.registerMethod(CORDIS_METHODS.pluginsStaticList, () => {
1304
+ const loader = optionalLoader(ctx);
1305
+ if (loader === void 0) throw new Error("this agent has no plugin Loader");
1306
+ const entries = [];
1307
+ for (const entry of loader.entries()) {
1308
+ if (entry.options.group) continue;
1309
+ entries.push({
1310
+ entryId: entry.id,
1311
+ moduleName: entry.options.name,
1312
+ enabled: !entry.disabled,
1313
+ fiberPhase: entry.fiber === void 0 ? null : FIBER_PHASE[entry.fiber.state] ?? null
1314
+ });
1315
+ }
1316
+ return { entries };
1317
+ }),
1318
+ "acp-bridge: list-static-plugins"
1319
+ );
1299
1320
  ctx.effect(
1300
1321
  () => rpc.registerMethod(CORDIS_METHODS.inspectSync, (params) => {
1301
1322
  const inspect = optionalInspect(ctx);
@@ -1491,6 +1512,14 @@ function optionalInspect(ctx) {
1491
1512
  return void 0;
1492
1513
  }
1493
1514
  }
1515
+ function optionalLoader(ctx) {
1516
+ try {
1517
+ const value = ctx.get("loader");
1518
+ return value !== void 0 && typeof value.entries === "function" ? value : void 0;
1519
+ } catch {
1520
+ return void 0;
1521
+ }
1522
+ }
1494
1523
  function optionalRunner(ctx) {
1495
1524
  try {
1496
1525
  const value = ctx.get("dynamicCordisRunner");
@@ -1837,6 +1866,19 @@ async function apply3(ctx, config = {}) {
1837
1866
  return {};
1838
1867
  }
1839
1868
  };
1869
+ const saveDefaultSelection = async (record) => {
1870
+ const selected = ensureSelection(record)?.current;
1871
+ if (selected === void 0) return;
1872
+ try {
1873
+ await agentDefaultModel.saveSelection({
1874
+ provider: selected.provider,
1875
+ model: selected.model,
1876
+ ...selected.reasoningEffort === void 0 ? {} : { reasoningEffort: ReasoningEffortId(selected.reasoningEffort) }
1877
+ });
1878
+ } catch (error) {
1879
+ logWarn(`model switch applied to the session but was not saved as the default: ${String(error)}`);
1880
+ }
1881
+ };
1840
1882
  const defaultProvider = () => config.provider ?? defaultSelection().provider;
1841
1883
  const encodeChoice = (provider, model) => provider === void 0 || provider === defaultProvider() ? model : `${provider}::${model}`;
1842
1884
  const decodeChoice = (value) => {
@@ -1988,23 +2030,21 @@ async function apply3(ctx, config = {}) {
1988
2030
  delete record.provider;
1989
2031
  }
1990
2032
  delete record.selection;
1991
- ensureSelection(record);
1992
- if (record.effort !== void 0) {
1993
- const route = routeOf(record);
1994
- const catalog = await effortCatalog(route.provider, route.model);
1995
- if (catalog?.efforts.some((effort) => effort.id === record.effort) === true && route.provider !== void 0 && route.model !== void 0) {
1996
- const selection = ensureSelection(record);
1997
- if (selection !== void 0) {
1998
- selection.current = {
1999
- provider: route.provider,
2000
- model: route.model,
2001
- reasoningEffort: record.effort
2002
- };
2003
- }
2004
- } else {
2005
- delete record.effort;
2006
- }
2033
+ const route = routeOf(record);
2034
+ const catalog = await effortCatalog(route.provider, route.model);
2035
+ if (record.effort !== void 0 && catalog?.efforts.some((effort2) => effort2.id === record.effort) !== true) {
2036
+ delete record.effort;
2037
+ }
2038
+ const effort = record.effort ?? catalog?.defaultEffort;
2039
+ const selection = ensureSelection(record);
2040
+ if (selection !== void 0 && route.provider !== void 0 && route.model !== void 0) {
2041
+ selection.current = {
2042
+ provider: route.provider,
2043
+ model: route.model,
2044
+ ...effort !== void 0 ? { reasoningEffort: effort } : {}
2045
+ };
2007
2046
  }
2047
+ await saveDefaultSelection(record);
2008
2048
  setApprovalPolicy(record, record.approvals);
2009
2049
  };
2010
2050
  const mutateSession = (record, mutation) => {
@@ -2856,9 +2896,14 @@ async function apply3(ctx, config = {}) {
2856
2896
  handle.agent,
2857
2897
  () => handle.dispose(),
2858
2898
  config.model,
2859
- config.permissionMode ?? "workspace-write"
2899
+ config.permissionMode ?? permissionService().defaultPreset
2860
2900
  );
2861
2901
  if (presetId !== void 0) record.preset = presetId;
2902
+ if (config.permissionMode !== void 0) {
2903
+ applyMode(record, String(sessionId), config.permissionMode);
2904
+ } else {
2905
+ syncPermissionState(record, String(sessionId));
2906
+ }
2862
2907
  ensureSelection(record);
2863
2908
  queueMicrotask(() => publishCommands(String(sessionId)));
2864
2909
  const options = await configOptions(record);
@@ -3061,6 +3106,7 @@ async function apply3(ctx, config = {}) {
3061
3106
  reasoningEffort: value
3062
3107
  };
3063
3108
  record.effort = value;
3109
+ await saveDefaultSelection(record);
3064
3110
  break;
3065
3111
  }
3066
3112
  case "collaboration_mode": {
package/dist/stdio.js CHANGED
@@ -33,6 +33,7 @@ import {
33
33
  RequestError
34
34
  } from "@agentclientprotocol/sdk";
35
35
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
36
+ import { ReasoningEffortId } from "@deepseek-ai/dsh-llm";
36
37
 
37
38
  // src/version.ts
38
39
  import { createRequire } from "node:module";
@@ -42,6 +43,7 @@ var VERSION = createRequire(import.meta.url)("../package.json").version;
42
43
  var CORDIS_PROTOCOL = 0;
43
44
  var CORDIS_CAPABILITY = Object.freeze({ protocol: CORDIS_PROTOCOL });
44
45
  var CORDIS_METHODS = Object.freeze({
46
+ pluginsStaticList: "_dsh/plugins/list",
45
47
  inspectSync: "_dsh/cordis/inspect/sync",
46
48
  inspectResolve: "_dsh/cordis/inspect/resolve",
47
49
  inspectQuery: "_dsh/cordis/inspect/query",
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.4.19",
6
+ "version": "0.4.21",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/openma-ai/deepseek-harness-acp.git"
@@ -35,9 +35,8 @@
35
35
  "build": "node build.mjs",
36
36
  "start": "node --import tsx src/index.ts",
37
37
  "pretest": "npm run build",
38
- "test": "vitest run --exclude test/profile-install.test.ts",
38
+ "test": "vitest run",
39
39
  "test:host": "vitest run test/e2e.test.ts -t \"serves session controls through the host tree\"",
40
- "test:install": "vitest run test/profile-install.test.ts",
41
40
  "test:watch": "vitest",
42
41
  "typecheck": "tsc --noEmit",
43
42
  "pack:local": "npm run build && npm pack"
@@ -50,62 +49,62 @@
50
49
  "devDependencies": {
51
50
  "@deepseek-ai/cordis": "^4.0.1",
52
51
  "@deepseek-ai/cordis-plugin-timer": "^1.1.3",
53
- "@deepseek-ai/dsh": "^0.1.0-rc.6",
54
- "@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
55
- "@deepseek-ai/dsh-agent-instructions": "^0.1.0-rc.6",
56
- "@deepseek-ai/dsh-agent-loop": "^0.1.0-rc.6",
57
- "@deepseek-ai/dsh-agent-spine-demo": "^0.1.0-rc.6",
58
- "@deepseek-ai/dsh-anonymous-user-id": "^0.1.0-rc.6",
59
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6",
60
- "@deepseek-ai/dsh-bash-sandbox": "^0.1.0-rc.6",
61
- "@deepseek-ai/dsh-brand": "^0.1.0-rc.6",
62
- "@deepseek-ai/dsh-commands": "^0.1.0-rc.6",
63
- "@deepseek-ai/dsh-compaction": "^0.1.0-rc.6",
64
- "@deepseek-ai/dsh-compaction-basic": "^0.1.0-rc.6",
65
- "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.0-rc.6",
66
- "@deepseek-ai/dsh-credentials": "^0.1.0-rc.6",
67
- "@deepseek-ai/dsh-credentials-local": "^0.1.0-rc.6",
68
- "@deepseek-ai/dsh-fs": "^0.1.0-rc.6",
69
- "@deepseek-ai/dsh-fs-local": "^0.1.0-rc.6",
70
- "@deepseek-ai/dsh-fs-observation-policy": "^0.1.0-rc.6",
71
- "@deepseek-ai/dsh-fs-sandbox": "^0.1.0-rc.6",
72
- "@deepseek-ai/dsh-goal": "^0.1.0-rc.6",
73
- "@deepseek-ai/dsh-goal-round-driver": "^0.1.0-rc.6",
74
- "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6",
75
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
76
- "@deepseek-ai/dsh-jobs-local": "^0.1.0-rc.6",
77
- "@deepseek-ai/dsh-launch-environment": "^0.1.0-rc.6",
78
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
79
- "@deepseek-ai/dsh-llm-deepseek": "^0.1.0-rc.6",
80
- "@deepseek-ai/dsh-llm-retry": "^0.1.0-rc.6",
81
- "@deepseek-ai/dsh-sandbox": "^0.1.0-rc.6",
82
- "@deepseek-ai/dsh-sandbox-local": "^0.1.0-rc.6",
83
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.0-rc.6",
84
- "@deepseek-ai/dsh-scope": "^0.1.0-rc.6",
85
- "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
86
- "@deepseek-ai/dsh-session-checkpoint-policy": "^0.1.0-rc.6",
87
- "@deepseek-ai/dsh-session-persistence": "^0.1.0-rc.6",
88
- "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.0-rc.6",
89
- "@deepseek-ai/dsh-session-projection": "^0.1.0-rc.6",
90
- "@deepseek-ai/dsh-session-title": "^0.1.0-rc.6",
91
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.6",
92
- "@deepseek-ai/dsh-shell": "^0.1.0-rc.6",
93
- "@deepseek-ai/dsh-shell-env": "^0.1.0-rc.6",
94
- "@deepseek-ai/dsh-skill": "^0.1.0-rc.6",
95
- "@deepseek-ai/dsh-skill-filesystem": "^0.1.0-rc.6",
96
- "@deepseek-ai/dsh-subprocess": "^0.1.0-rc.6",
97
- "@deepseek-ai/dsh-subprocess-local": "^0.1.0-rc.6",
98
- "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
99
- "@deepseek-ai/dsh-timeout": "^0.1.0-rc.6",
100
- "@deepseek-ai/dsh-token-meter": "^0.1.0-rc.6",
101
- "@deepseek-ai/dsh-tool-bash": "^0.1.0-rc.6",
102
- "@deepseek-ai/dsh-tool-fs": "^0.1.0-rc.6",
103
- "@deepseek-ai/dsh-tool-goal": "^0.1.0-rc.6",
104
- "@deepseek-ai/dsh-tool-jobs": "^0.1.0-rc.6",
105
- "@deepseek-ai/dsh-tool-skill": "^0.1.0-rc.6",
106
- "@deepseek-ai/dsh-tool-todo": "^0.1.0-rc.6",
107
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
108
- "@deepseek-ai/dsh-user-approval": "^0.1.0-rc.6",
52
+ "@deepseek-ai/dsh": "^0.1.1-rc.1",
53
+ "@deepseek-ai/dsh-agent": "^0.1.1-rc.1",
54
+ "@deepseek-ai/dsh-agent-instructions": "^0.1.1-rc.1",
55
+ "@deepseek-ai/dsh-agent-loop": "^0.1.1-rc.1",
56
+ "@deepseek-ai/dsh-agent-spine-demo": "^0.1.1-rc.1",
57
+ "@deepseek-ai/dsh-anonymous-user-id": "^0.1.1-rc.1",
58
+ "@deepseek-ai/dsh-attachment": "^0.1.1-rc.1",
59
+ "@deepseek-ai/dsh-bash-sandbox": "^0.1.1-rc.1",
60
+ "@deepseek-ai/dsh-brand": "^0.1.1-rc.1",
61
+ "@deepseek-ai/dsh-commands": "^0.1.1-rc.1",
62
+ "@deepseek-ai/dsh-compaction": "^0.1.1-rc.1",
63
+ "@deepseek-ai/dsh-compaction-basic": "^0.1.1-rc.1",
64
+ "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.1-rc.1",
65
+ "@deepseek-ai/dsh-credentials": "^0.1.1-rc.1",
66
+ "@deepseek-ai/dsh-credentials-local": "^0.1.1-rc.1",
67
+ "@deepseek-ai/dsh-fs": "^0.1.1-rc.1",
68
+ "@deepseek-ai/dsh-fs-local": "^0.1.1-rc.1",
69
+ "@deepseek-ai/dsh-fs-observation-policy": "^0.1.1-rc.1",
70
+ "@deepseek-ai/dsh-fs-sandbox": "^0.1.1-rc.1",
71
+ "@deepseek-ai/dsh-goal": "^0.1.1-rc.1",
72
+ "@deepseek-ai/dsh-goal-round-driver": "^0.1.1-rc.1",
73
+ "@deepseek-ai/dsh-home-paths": "^0.1.1-rc.1",
74
+ "@deepseek-ai/dsh-invariants": "^0.1.1-rc.1",
75
+ "@deepseek-ai/dsh-jobs-local": "^0.1.1-rc.1",
76
+ "@deepseek-ai/dsh-launch-environment": "^0.1.1-rc.1",
77
+ "@deepseek-ai/dsh-llm": "^0.1.1-rc.1",
78
+ "@deepseek-ai/dsh-llm-deepseek": "^0.1.1-rc.1",
79
+ "@deepseek-ai/dsh-llm-retry": "^0.1.1-rc.1",
80
+ "@deepseek-ai/dsh-sandbox": "^0.1.1-rc.1",
81
+ "@deepseek-ai/dsh-sandbox-local": "^0.1.1-rc.1",
82
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.1-rc.1",
83
+ "@deepseek-ai/dsh-scope": "^0.1.1-rc.1",
84
+ "@deepseek-ai/dsh-session": "^0.1.1-rc.1",
85
+ "@deepseek-ai/dsh-session-checkpoint-policy": "^0.1.1-rc.1",
86
+ "@deepseek-ai/dsh-session-persistence": "^0.1.1-rc.1",
87
+ "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.1-rc.1",
88
+ "@deepseek-ai/dsh-session-projection": "^0.1.1-rc.1",
89
+ "@deepseek-ai/dsh-session-title": "^0.1.1-rc.1",
90
+ "@deepseek-ai/dsh-settings": "^0.1.1-rc.1",
91
+ "@deepseek-ai/dsh-shell": "^0.1.1-rc.1",
92
+ "@deepseek-ai/dsh-shell-env": "^0.1.1-rc.1",
93
+ "@deepseek-ai/dsh-skill": "^0.1.1-rc.1",
94
+ "@deepseek-ai/dsh-skill-filesystem": "^0.1.1-rc.1",
95
+ "@deepseek-ai/dsh-subprocess": "^0.1.1-rc.1",
96
+ "@deepseek-ai/dsh-subprocess-local": "^0.1.1-rc.1",
97
+ "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.1",
98
+ "@deepseek-ai/dsh-timeout": "^0.1.1-rc.1",
99
+ "@deepseek-ai/dsh-token-meter": "^0.1.1-rc.1",
100
+ "@deepseek-ai/dsh-tool-bash": "^0.1.1-rc.1",
101
+ "@deepseek-ai/dsh-tool-fs": "^0.1.1-rc.1",
102
+ "@deepseek-ai/dsh-tool-goal": "^0.1.1-rc.1",
103
+ "@deepseek-ai/dsh-tool-jobs": "^0.1.1-rc.1",
104
+ "@deepseek-ai/dsh-tool-skill": "^0.1.1-rc.1",
105
+ "@deepseek-ai/dsh-tool-todo": "^0.1.1-rc.1",
106
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.1",
107
+ "@deepseek-ai/dsh-user-approval": "^0.1.1-rc.1",
109
108
  "@types/node": "^26.1.0",
110
109
  "esbuild": "^0.28.1",
111
110
  "pnpm": "11.22.0",