Repository navigation
Releases: grunmin/dsh-acp-enhanced
Release list
v0.11.0 — dsh 0.2.1 support, and the {{cwd}} turn fix
dsh 0.2.1 support, and the {{cwd}} turn fix
dsh-acp-enhanced@0.11.0 names the 0.2.1 line in its declared range, boots it in CI, drops
@deepseek-ai/dsh-invariants, and fixes the defect that made every turn fail on that line.
No lib/ code changed: the range already contained 0.2.1, so this release is a declaration change
plus the evidence behind it — and one preset fix that was not optional.
Migration record: docs/plans/2026-10-18-dsh-0.2.1-support.md.
Fixed: {{cwd}} killed every turn on 0.2.1
The inlined standard / ptc / cordis presets carried persona.config.suffix: … {{cwd}}.
On 0.2.1 dsh-agent-loop registers only provider and model as prompt variables (cwd was
registered through 0.1.7), and dsh-system-prompt interpolates strictly — so every session
composed from those presets failed prompt assembly with unknown prompt variable "{{cwd}}" before
the first model request. Boot was fine, the mount was fine, every turn failed.
The three persona rows and the reference profile/cordis.yml now carry the model prefix only, as
upstream 0.2.1's own preset files do.
This matters right now, not eventually. latest moved to 0.2.1-rc.2 on 2026-10-19, and
0.10.0 both admits that line through ^0.2.0-rc.2 and still ships the suffix — so on a default
npm i -g @deepseek-ai/dsh, 0.10.0 fails its first turn. If you are on that line with 0.10.0,
upgrade to 0.11.0.
One cost, stated rather than hidden: dsh-agent-loop still registers cwd on 0.1.6-alpha.2 /
0.1.7-rc.2 / 0.2.0-rc.2, and none of those lines' dsh-base bundles has a working-directory row,
so a single-root session there no longer learns its directory from the prompt. Multi-root
sessions keep it through the bridge's own acp:workspace-roots context; 0.2.1 supplies it
host-side (Current working directory: …). Version-gating the sentence was rejected — three
!!js probes on the boot path for one sentence, when the model can still read its directory with
pwd. Per-line table: §2.3 of the migration record.
Added: dsh 0.2.1
0.2.1 is a host-side and UI release; nothing this bridge consumes was removed. Two user-visible
changes, neither of which needs anything from this bridge:
- DeepSeek search and fetch.
dsh-baseregisters aweb-deepseek-apirow serving
web_search/web_fetchthrough DeepSeek's dedicated Search and Fetch endpoints instead of a
full auxiliary model request. Credential:DEEPSEEK_API_KEY. Selected in the harness's own
web-search settings; no row, peer or import of this bridge's is involved. - A model-picker label, wired into the web/desktop bundle layer an ACP profile never loads.
Changed: supported lines
| Before | ^0.1.6-alpha.1 || ^0.1.7-alpha.1 || ^0.2.0-rc.2 |
| Now | ^0.1.6-alpha.1 || ^0.1.7-alpha.1 || ^0.2.0-rc.2 || ^0.2.1-rc.2 |
The new alternative narrows nothing — the caret ceiling for ^0.2.0-rc.2 is <0.3.0-0, which
already contains 0.2.1-rc.2. It is declared because the range doubles as the list of lines the
guards check, and every alternative needs a boot in CI and a link-check generation beside it.
@deepseek-ai/dsh-invariants left peerDependencies and devDependencies: upstream stopped
publishing it at 0.2.0-rc.2, so the 0.2.1 closure does not carry it.
Documented, not adopted: 0.2.1-rc.2 rewrote all four upstream preset files (added time-context,
tool-schedule, tool-plugin-market, a compaction group, tool-fs; reworded plan mode). This
bridge still inlines its own copy, so a 0.2.1 session composes the 0.2.0 set. Adopting the rest
needs per-line declarations, because two added rows name packages that exist on 0.2.1 only while
the install path resolves every row name on every declared line.
Install / upgrade
npm install -g @deepseek-ai/dsh@0.2.1-rc.2 # or any version in the range
dsh plugin --profile acp-enhanced add dsh-acp-enhanced@0.11.0The profile's dependency is a caret on 0.x, so dsh plugin update will not move you across a
minor — upgrade the bridge explicitly.
Verified
CI, on all four declared lines × Node 22 and 24, all green — and on 0.2.1-rc.2 the model-backed
legs ran a real turn: prompt settled with end_turn, one bash tool call, telemetry emitted.
That is the path that used to throw, and the keyless smoke structurally cannot reach it. The same
job runs api-surface, boot-classify, support-claim, docs-claim, the launcher contract,
pack-check, the codec suites, the four-generation link check, the install path and the keyless
boot smoke. Locally the same tier passes on a clean git archive HEAD copy with a frozen offline
install.
Not covered: a real Zed session, and any profile that carries third-party bundles beyond the
matrix.
v0.10.0 — dsh 0.2.0 support, floor moves to 0.1.6-alpha.1
dsh 0.2.0 support, and the floor moves to 0.1.6-alpha.1
dsh-acp-enhanced@0.10.0 adds the 0.2.0 line to the declared range and drops the
0.1.5-rc.2 line, which could never be verified in CI.
Added: dsh 0.2.0
0.2.0 is a client/UI release: nothing this bridge consumes was removed (0 services, 0 events), and
@deepseek-ai/dsh-session adds ToolCallRecovery. The change that matters is host-side —
dsh-app-boot's peer gate now rejects any bundle whose declared @deepseek-ai/dsh* ranges do not
match the running CLI, and on the boot path it does that by silently dropping the bundle's whole
patch layer. The peer range therefore widens to ^0.2.0-rc.2, and the shipped helper's caret
ceiling now matches npm's own semantics (<0.2.0-0): before this, the bridge's own gate called
0.2.0 supported while the host gate refused it, and nothing warned.
The <= 0.1.6 agent-preset roster is no longer declared as a peer: the install path evaluates
every patch row's resolved package, so a line-gated declaration made dsh plugin add fail outright
on 0.2.0 (incompatible-version). The row itself stays, generation-gated, and keeps resolving from
the running CLI.
Changed: supported lines
| Before | ^0.1.5-rc.2 || ^0.1.6-alpha.1 || ^0.1.7-alpha.1 |
| Now | ^0.1.6-alpha.1 || ^0.1.7-alpha.1 || ^0.2.0-rc.2 |
If you are on dsh 0.1.5-rc.2, stay on bridge 0.9.1 (or upgrade the CLI). 0.1.5-rc.2 is no
longer claimed because its boot smoke fails on GitHub's runners — @deepseek-ai/dsh-sandbox-local
cannot be resolved, and session/new times out — while the same smoke passes locally. An
unverifiable line does not belong in a support claim. Every <= 0.1.6 code path is unchanged
(0.1.6 is still declared). The floor moves with a bridge minor release, as the policy states,
and the launcher warns before booting a CLI outside the range (acp-doctor.mjs stops with
RESULT FAIL).
Fixed
- A Stop can no longer kill the thread. Bridge ≤ 0.9.1 passed
new Error(...)as the harness
cancel cause, butAgentCancelCauseis a closed union: the harness's own turn close-out threw on
assertNeverand persistedturn/end {reason: null}, after which every projection read of that
session (the next prompt, a config switch,session/load) threw. Cancels now pass
{kind:'user'}. - A skipped bundle is a capability, not a boot failure. A working boot that lost a third-party
bundle to the host's peer gate now reportsBOOT OK+DEGRADED <n> inactive itemsinstead of
BOOT FAILED, the skip line no longer outranks a real crash signature, and the launcher's skip
hint no longer consumes its single fatal-hint slot.
Install / upgrade
npm install -g @deepseek-ai/dsh@0.2.0-rc.2 # or any version in the new range
dsh plugin --profile acp-enhanced add dsh-acp-enhanced@0.10.0The profile's dependency is a caret on 0.x, so dsh plugin update will not move you across a
minor — upgrade the bridge explicitly.
Verified
api-surface, boot-classify, support-claim (3 declared lines / 3 matrix versions / 3 link
generations), the launcher contract, pack-check, the 8 offline codec suites, compat-check (3
generations link clean), and the keyless boot smoke on dsh 0.1.6-alpha.2 / 0.1.7-rc.2 / 0.2.0-rc.2
(26 PASS each, no skipped bundle). CI runs the same tier per line on Node 22 and 24, plus the
model-backed e2e legs.
v0.9.1 — dsh 0.1.7 support (additive)
0.9.1 — dsh 0.1.7 support (additive)
Adds the dsh 0.1.7 line without dropping 0.1.5 or 0.1.6: the floor stays at
0.1.5-rc.2 and the peer range becomes
^0.1.5-rc.2 || ^0.1.6-alpha.1 || ^0.1.7-alpha.1. Still a patch release — 0.1.7
repackaged the agent-preset roster rather than declaring a new API line.
Compatibility — dsh 0.1.7
- The agent-preset roster moved from
@deepseek-ai/dsh-agent-presets(bundled
shipped presets, read-onlysystemroot) to@deepseek-ai/dsh-agent-preset-registry
plus one@deepseek-ai/dsh-agent-presetdeclaration row per preset. Both rows
now ship, each behind a generation gate that reads the booting installation's
own manifest version, so exactly one activates and neither path can fail a boot. - The four shipped preset declarations (
standard/ptc/minimal/cordis)
are inlined from the 0.1.7 web-app bundle (MIT), carrying the display metadata
the old roster's per-presetpreset.ymlprovided — 0.1.7 publishes noname
for a shipped id. - Mountable resolution goes through a member probe:
presets.resolveMountable(id)
where it exists (≤ 0.1.6), otherwisepresets.resolve(id)plus the row's own
brokenreason (0.1.7 returns a broken row on purpose and refuses it later). - A configured preset this roster no longer has no longer closes the panel: a
blank session opens under an offered default and the substitution is reported
on stderr. Resuming a thread that already ran the missing preset still fails
until the row exists. - User-authored presets under
$DSH_HOME/.agent-presetsare not discovered from
0.1.7 on; declare them as@deepseek-ai/dsh-agent-presetrows in the profile.
Fixes
session/listno longer decodes every stored log. On a large 0.1.7 store that
was ~217 ms per log, past the 30 s wire timeout. The list now takes size and
revision from a single store pass, decorates the recency head within a budget
(DSH_ACP_LIST_BUDGET_MS, strictly parsed — aNaN/empty value falls back to
2500 ms and is logged instead of silently disabling the guard), caches by
id@revision, and streams the remaining titles assession_info_update.
A live session's own title stays authoritative and is never overwritten by a
stored one.- A resumed session's context window is folded from its log, so the ring keeps
its denominator when the harness does not re-emitrequest/context. - The resumed-ring guard can no longer pass vacuously.
- A tool result's name is taken from its call table; the tool-result id and body
are read across both dsh shapes, so cards stop sticking at "running" with no
output on 0.1.7. - An editor-run command is titled with the command instead of "bash".
acp-doctorreports a degraded boot (DEGRADED <n> loader entries never activated) instead ofREADY.
Release and CI hardening
- The promised cross-generation link check runs (
scripts/compat-check.mjs);
the CI matrix covers Node 22/24 × dsh 0.1.5-rc.2 / 0.1.6-alpha.2 / 0.1.7-rc.2. scripts/dsh-acp-zed.shandscripts/init-acp-home.shhonourDSH_PATH
directories, and the launcher contract test covers the cases.- New offline suites:
stored-titles-test(the list stall regression guard,
source-level check that the list handler never re-probes withstat()),
session-facts-test,context-window-test,tool-result-test. - The 0.1.7 migration is recorded in
docs/plans/2026-09-24-dsh-0.1.7-support.md.
Notes
- npm
latestmoves 0.9.0 → 0.9.1. - Upgrade:
dsh plugin --profile acp-enhanced add dsh-acp-enhanced@0.9.1. - Known CI caveat: the
dsh 0.1.5-rc.2matrix legs fail in a GitHub runner
before any bridge code runs — the runner's global dsh installation is missing
@deepseek-ai/dsh-sandbox-local, which the CLI's owndsh-basepatch loads
while declaring it only as a devDependency. The same CLI version boots this
checkout green on a normal install; 0.1.6-alpha.2 and 0.1.7-rc.2 legs pass.
v0.9.0 — declared-surface-only bridge
0.9.0 — declared-surface-only bridge
Breaking
- Consumes only the harness's declared surface: services in
docs/capability-seams.md, events in docs/event-producer-consumer.md, published
package exports. No runtime generation probing is left. - Floor raised to dsh >= 0.1.5-rc.2 (peer range ^0.1.5-rc.2 || ^0.1.6-alpha.1);
older hosts fail at mount time with a named error rather than degrading. session/deleteis no longer advertised: the harness declares no public
persistence delete.session/closeremains implemented.- The launcher no longer rewrites DSH_HOME. The profile boots in the home the
launcher was started with, sharing credentials, settings, sessions and presets
withdsh web. - Live streaming is
agent/assistant-streamonly;assistant/chunkis gone.
Fixes
- A committed message is delivered once and in generation order: the
assistant/messagefallback re-sent the image placeholder the message handler
had already sent, and it emitted reasoning against its reply. Replay and the
fallback now shareassistantContentChunks, and the per-kind delivery decision
is the pure functionfallbackDelivery. - Streamed usage samples report
_meta.turn/.stepagain (they were read off
thechunkframe, which does not carry them). - History replay keeps reasoning before the reply it belongs to.
Release and CI hardening
scripts/pack-check.mjsasserts the tarball (entry points, dev-only leakage,
shipped-file references, modes) instead of printing it.- The model-backed e2e legs are reachable again and now run: reply delivery,
assistant/messagefallback (reply exactly once) and replay order, on Node
22/24 x dsh 0.1.5-rc.2 / 0.1.6-alpha.2. - The surface guard sees regex literals, double-quoted ids and the dynamic
serviceForAgent(…, 'planMode')lookup;isSupportedchecks the caret ceiling. init-acp-home.shresolves any dsh CLI and stops printing unshipped paths.
Notes
- 0.8.0 was never published: npm
latestmoves 0.7.0 -> 0.9.0. - Upgrade:
npm install -g @deepseek-ai/dsh@0.1.5-rc.2, then
dsh plugin --profile acp-enhanced add dsh-acp-enhanced@0.9.0.
dsh-acp-enhanced v0.7.0
What's Changed
- fix(acp): readable user-interrupt tool errors, optional JSONL trace (ACP_LOG / logFile config)
- feat(acp): tolerate both harness API generations (0.1.0-rc.6 → 0.1.2-rc.1)
- fix(acp): registry slash commands — probe the execute signature per generation (/goal and friends)
- fix(acp): userQuestions — probe the registration seam per generation
- fix(acp): support dsh 0.1.2-rc.1 — session.events became snapshotEvents()
- chore(deps): repo-pinned @deepseek-ai/dsh CLI + family-range devDeps, pinned at 0.1.2-rc.1
- feat(launcher): repo-pinned CLI resolution + isolated DSH_HOME
- feat(scripts): isolated-home bootstrap (init-acp-home.sh) + cross-generation link check (compat-check.mjs)
- test(e2e): optional model preselect via DSH_ACP_E2E_MODEL
- docs(readme): compatibility matrix, isolated home, migration notes
- refactor(search): drop the openrouter sub-package; search is a profile concern
Full changelog: v0.6.0...v0.7.0
dsh-acp-enhanced v0.6.0
What's Changed
- feat(acp): custom answers + titled options in ask_user_question forms
- docs(readme): document profile plugin management
- fix(acp): broadcast available_commands strictly after the session response
- fix(acp): readable user-interrupt tool errors, optional JSONL trace (present in the published npm tarball; this tag points at the exact published tree)
Full changelog: v0.5.3...v0.6.0
npm: dsh-acp-enhanced@0.6.0
dsh-acp-enhanced v0.5.0
feat(acp): agent presets, bash/pwsh terminal cards, skill slash commands
- Agent presets: sessions compose their model-facing tool/prompt surface from the dsh agent-presets roster (standard/code/minimal/cordis + user presets). agent_preset config option, /preset command, DSH_ACP_PRESET env override; cordis.patch.yml mirrors the official dsh-web-app/tui host-row disable list.
- bash/pwsh terminal cards: codex-acp wire shape (kind execute, terminal content, _meta.terminal_info/terminal_output(_delta)/terminal_exit) folded into toolCallUpdateFor/toolResultUpdateFor; pure helpers in lib/terminal-codec.js with unit tests.
- Skill slash commands: user-invocable skills advertised as available_commands; unresolved slashes load the skill body into the message.
Based on PR #1 by @sunstrikes (listed in contributors).