Two very concrete scenarios
First one. You paste a chunk of logs into your agent client to chase down a problem, and the logs carry a line DEEPSEEK_API_KEY=sk-.... Problem solved. That line is still sitting in the session history.
Next time you screenshot the session for a group chat, or export a transcript, the key goes with it.
Second one. A session runs for hours, the context keeps stacking up, and you’re near the window limit. The old workaround was to start a new session, and the cost was losing every conclusion you’d already talked your way to.
Neither hole is new. DeepSeek Harness (dsh from here on) shipped official fixes for both in 0.2.1-alpha.3 on October 14. Their words:
Detects keys and tokens in messages already sent, masks them by default, reveals on demand. Minimal mode supports reading images and auto-compacting long conversations; Web and desktop can compact context manually with the /compact command.
I upgraded the copy on my machine and ran both.
Upgrade: one command, one small trap
I had 0.1.6-alpha.2 installed globally via npm. The upgrade is one line:
npm i -g @deepseek-ai/[email protected]
Spell out the version, because the tags on npm currently look like this:
alpha: 0.2.1-alpha.3
latest: 0.2.0-rc.2
next: 0.2.0-rc.2
latest actually points at the older 0.2.0-rc.2. A plain npm i -g @deepseek-ai/dsh won’t get you the newest build.
During the install, npm 12 blocks install scripts for five packages:
npm warn install-scripts 5 packages had install scripts blocked because they are not covered by allowScripts:
npm warn install-scripts @deepseek-ai/[email protected] (postinstall: node scripts/ensure-spawn-helper.mjs)
npm warn install-scripts [email protected] (install: node ./cnoke.cjs -P . -D src/koffi --prebuild --release)
npm warn install-scripts [email protected] (install: node scripts/prebuild.js || node-gyp rebuild; postinstall: node scripts/post-install.js)
There are native modules in that list. I didn’t allow them this time, and everything ran fine afterwards — terminal and file I/O both normal. To be safe, allow them the way npm suggests and install again:
npm i -g --allow-scripts=@deepseek-ai/dsh-subprocess-local,koffi,node-pty,@google/genai,protobufjs @deepseek-ai/[email protected]
One more tip. I pointed the config directory somewhere else (DSH_HOME=/tmp/dsh-021a3) so I could test the new build without touching the config and sessions I use every day.
Confirm the version after install:
$ dsh --version
0.2.1-alpha.3
Test one: key masking
I sent a message in the input box with two fake credentials: one starting with sk-, one GitHub token starting with ghp_.
After sending, the message shows up in the conversation like this:

sk-12345 followed by a run of asterisks, same for ghp_AbCd, with an eye icon at the end. The first few characters stay, the rest is masked.
Click the eye and the first credential shows in full, while the second stays masked. It doesn’t unlock the whole message, it’s per-item.
The masking holds in session history too. Screenshot it later or export the transcript and no plaintext comes with it.
Test two: /compact
This round I measured with real numbers. The method: drop a large file into the workspace, have the agent read it to inflate the context, then compact by hand.
First round read a 54 KB changelog. When it finished, the indicator at the bottom was at 3%. Running /compact:

A line appears in the conversation — compact · Compacted 12 history items (~18538 tokens) — and usage drops back to 2%.
Second round used a 224 KB document. Usage shot to 9%, compacted again, and this time it cut 16 history items and about 60,107 tokens, dropping usage back to 3%.
One action saves 18k to 60k tokens. What gets compacted is history messages; conclusions and state stay, so you can keep talking.
The official notes add that in minimal mode long conversations compact automatically, so you don’t have to think about it. Manual /compact is for actively freeing space during a long session.
Also found: where headless gets its key has changed
Anyone writing scripts or running CI should pay attention to this one. Same new build, headless mode with no key:
$ dsh headless "只回答两个字:收到"
dsh: MISSING_CREDENTIAL: llm-deepseek: no API key for provider route "deepseek-official";
store DEEPSEEK_API_KEY through the credentials service (the web Models page writes it),
or export DEEPSEEK_API_KEY in the launching environment
Put DEEPSEEK_API_KEY in the environment and run again, and it answers normally.
The official notes list this under other changes: Web and desktop prefer saved credentials, while headless now defaults to environment variables and .env and no longer reads saved keys. Scripts that used to run headless off the credentials service will hit that error above after upgrading.
From 0.2 to now, what changed across five releases
Let me straighten out the version line first:
0.1.6-alpha.2 (what I had) → 0.1.7-rc.2 → 0.2.0-rc.1 (09-28) → 0.2.0-rc.2 (09-29)
→ 0.2.1-alpha.1 (10-03) → 0.2.1-alpha.2 (10-09) → 0.2.1-alpha.3 (10-14)
Start from 0.2.
0.2.0-rc.1 is the first release candidate of the 0.2 series and rolls up the main changes since 0.1.7-rc.2. Automation tasks moved to an optional plugin package instead of being built in.
Sessions using a DeepSeek account model get web search without configuring a key separately. After a tool scheduling error the conversation can continue, but operations that already ran with unknown results prompt you to verify side effects first instead of blindly retrying.
Images that go stale get re-uploaded automatically to continue the request. Untitled history sessions now all display as “Untitled”. On Windows there’s a new sandbox permission diagnostic skill that can do permission repairs with a backup.
0.2.0-rc.2 stuffed the CLI into the desktop app’s menu bar. Installing the dsh command and managing plugins no longer needs a separate Node or pnpm.
The model picker supports search when there are many models. The third-party model catalog went up to pi-ai 0.87.1, some old model IDs were removed, and saved selections may need picking again.
Launching from the graphical entry point now inherits the login shell environment, so tool paths and proxy config are readable in the session. An experimental async Q&A mode was added; you have to turn it on yourself.
0.2.1-alpha.1 adds an experimental Claude Code Mods compatibility layer. The official word is blunt: at this stage the point is mainly to confirm that the Mods API’s capabilities are roughly a subset of dsh plugins, full compatibility isn’t the goal.
The plugin management page gained a “let the Agent create a plugin” entry that holds the draft in creation mode and only starts working once you send the requirement. Web supports --public-url, so it can sit under a subpath behind a reverse proxy. A new developer tooling bundle can show raw session logs and do two-way navigation between chat groups and the body text.
This release also has breaking changes: the runtime invariant plugin and each package’s ./invariant export were removed, the input-area stats extension split into two registration IDs, activity and usage, and extensions that depend on those have to follow.
0.2.1-alpha.2 adds two experimental plugins. One is machine translation of the thinking process, with Bing, Google or paid DeepSeek Flash as options; the other is Git Worktrees, letting the Agent create and enter its own separate checkout.
Plugins now have an interface for recording their own session state. Global instructions can read AGENTS.md from a shared agents directory, set with DSH_AGENTS_HOME. A new working_directory tool lets both the TypeScript and Python SDKs read and switch the session’s working directory.
The Official plugin list gained on-demand install entries for the Claude Code and Codex bundles. One fix matters a fair bit to Chinese users: local SenseVoice speech recognition was cutting off the start of recordings and dropping the first character when VAD was on. That’s fixed.
0.2.1-alpha.3 is the build I tested above. Besides key masking and context compaction, it adds logging into a DeepSeek account when the Web version is reached over local HTTP, image reading in minimal mode, an independent Agent Preset per sub-agent, and an optional in-memory mode for PTC’s Node execution environment.
Model settings hints got clearer and now show credential source and detection status, and the API Key can be revealed on demand. On the fix side, a few annoying ones are gone: some sessions couldn’t continue after a restart, switching to DeepSeek failed on historical message compatibility, plugins kept running old code after an update, and tasks left incomplete after an unexpected app exit were mistaken for completed.
Strung together, the main line through 0.2 is pretty clear. The plugin system is heading toward everything-is-a-plugin, with compatibility layers, bundles and plugin-owned state all filling in. Credentials and context — the two security and cost issues easiest to overlook — got put on the table. And the Agent’s scheduling, delegation and recovery keep getting thicker.
One last thing
Key masking isn’t hard to build. What’s hard is someone admitting that users really do paste keys into chat boxes. Same for context compaction: long sessions are the norm, not the exception.
The agent client you use every day — how many plaintext keys are sitting in its session history right now? Comments are open.
