Introduction¶
The philosophy of DSH is “Everything is a plugin,” and profiles are used to divide different plugin environments. The safemode profile is positioned as a “clean environment”: it is the most suitable choice for troubleshooting, serving as a comparison baseline, or when you only want core capabilities.
However, the safemode profile is essentially just a set of ordinary files under $DSH_HOME/profiles/safemode/. One command dsh plugin --profile safemode add ..., one manual edit of package.json, or even a single mistaken edit in a script can make this environment no longer clean, and you might not discover it immediately. Manually verifying files one by one or manually cleaning them up is time-consuming and unreliable.
dsh-safemode-profile automates this: it forces restoration on startup and provides continuous guardianship during runtime, ensuring that dsh --profile safemode contains only the whitelisted core bundle at any moment.
What is it¶
dsh-safemode-profile is a DSH plugin by author jinsiyu, licensed under MIT. It has a single responsibility: to lock the safemode profile to the whitelist template—forcing restoration on startup and automatically detecting and restoring drift during runtime.
Prerequisites: DSH (@deepseek-ai/dsh) and Node.js (≥ 18) must be installed.
Core Features¶
Forced Restore on Startup¶
Every time DSH starts and loads this plugin, it unconditionally writes $DSH_HOME/profiles/safemode/ back to the whitelist template, involving three files:
| File | Forced Content |
|---|---|
package.json |
dsh.profile.bundles is set to the whitelist (default @deepseek-ai/dsh-base + @deepseek-ai/dsh-web-app), dependencies is cleared |
cordis.patch.yml |
Empty user patch layer |
pnpm-workspace.yaml |
pnpm workspace settings |
If consistent with the template, it remains unchanged (to avoid self-triggering). If inconsistent, it is rewritten.
Dual-Channel Guardian during Runtime¶
During the plugin’s lifetime, it monitors whether the profile has been modified using two channels:
fs.watchreal-time listening: Any change to the three files triggers an immediate restore after a 300ms debounce;- 30-second polling fallback:
detectDriftperforms a full comparison, covering cases wherefs.watchis unreliable (such as mount scenarios) or files are externally replaced.
If drift is detected—bundles are added/removed, the patch layer is written, or dependencies are modified—it automatically restores and logs a warning.
No Build Scripts, Install Once¶
There is no postinstall or any build scripts inside the package, so pnpm does not intercept it. dsh plugin add succeeds on the first try (exit code 0), and no configuration of approve-builds / allowBuilds is needed. All the work of restoration and guardianship is handled by the plugin when it loads during DSH startup.
Customizable Whitelist¶
The whitelist is the only entry point for customization, set via the environment variable DSH_SAFEMODE_BUNDLES. Both the guardian and restoration logic read the same whitelist, so changing one takes effect globally.
Installation and Enablement¶
First, confirm the prerequisites: DSH (@deepseek-ai/dsh) and Node.js (≥ 18) are installed. Choose one of the following three methods; the commands are based on the forms given in the official documentation:
Method A (Recommended, npm install):
dsh plugin --profile web add dsh-safemode-profile
Method B (GitHub Direct Install, Explicitly Specify main Branch):
dsh plugin --profile web add github:jinsiyu/dsh-safemode-profile#main
Method C (Local .tgz Pack):
npm pack # Generates dsh-safemode-profile-<version>.tgz
dsh plugin --profile web add .\dsh-safemode-profile-<version>.tgz
After installation, restart DSH. Once the plugin is active, safemode enters the state of “forced restore + resident guardian.”
Typical Usage¶
Start with Zero Third-Party Plugins¶
dsh --profile safemode
Safemode also includes a webServer (default 3080). If running alongside the web profile, it is recommended to stagger the ports using --port:
dsh --profile safemode --port 3081
Customizing Whitelist¶
For example, if you only want to keep the pure CLI (no GUI):
$env:DSH_SAFEMODE_BUNDLES = "@deepseek-ai/dsh-base"
The dsh command will inherit this environment variable and take effect on startup. Note that you should not manually edit the safemode profile files; any changes will be restored by the guardian logic, and customizations should always go through this environment variable.
Manual Forced Restore¶
If you don’t want to restart DSH, or are troubleshooting an issue, you can trigger a restoration immediately:
node scripts/ensure-safemode.mjs
File System Hardening (Optional)¶
Beyond the plugin’s guardianship, you can set the three managed files to read-only to prevent dsh plugin --profile safemode add <package> from succeeding at the filesystem level: pnpm will fail to write these files, the installation will report an error directly, and the plugin will be unable to install; DSH startup remains unaffected. There are three levels:
- Basic Read-only (Recommended for daily use): Use
attrib +Ron Windows,chmod 444on POSIX:
attrib +R "$env:USERPROFILE\.dsh\profiles\safemode\package.json" `
"$env:USERPROFILE\.dsh\profiles\safemode\cordis.patch.yml" `
"$env:USERPROFILE\.dsh\profiles\safemode\pnpm-workspace.yaml"
chmod 444 ~/.dsh/profiles/safemode/package.json \
~/.dsh/profiles/safemode/cordis.patch.yml \
~/.dsh/profiles/safemode/pnpm-workspace.yaml
- Windows ACL (icacls deny): Can be precise down to “write” and “delete,” but still cannot stop Administrators / SYSTEM (who have full control by default) or bypass via taking ownership;
- Linux immutable (
chattr +i): The strongest tier; even root cannot modify it, but it requiressudoand the filesystem must support it (ext4/xfs support it).
Notes on Hardening:
- Only lock these three managed files; do not lock the entire directory. Especially on Windows, do not use
attrib +R <directory> /Sto recursively lock—DSH rewritescordis.ymlon every startup, and a locked directory will cause safemode startup to fail (tested exit code 1). - Let the plugin create/restore the profile first (ensure content matches the whitelist template) before locking. If drift occurs after locking, the guardian restoration will fail due to read-only and log a warn—this is the expected behavior of locking: if locked, there should be no drift.
chattr +iwill also block the plugin’s own self-healing restoration. You must runchattr -ibefore upgrading the plugin or modifying the whitelist. Basic read-only is sufficient for daily scenarios.
Use Cases and Considerations¶
Suitable Scenarios: You need a predictable, clean DSH environment for troubleshooting or comparison; or there are automated scripts or other people touching DSH configurations on the machine, and you want the safemode profile to be safe from accidental (or intentional) changes.
Things to clarify before use:
- Port Conflict: Safemode also includes a webServer with a default port of 3080. Running it alongside the web profile will fail to start due to
EADDRINUSE. Use--portto stagger them (e.g.,--port 3081). - Session and Credential Isolation:
sessions,settings.yaml, and.envare shared at the home level; safemode isolates only the plugins. - Home Patch Stacking:
~/.dsh/cordis.patch.ymltakes effect for every profile. Do not hang plugins there; the guardian logic only watches the safemode directory itself. - Don’t manually edit
cordis.yml: DSH automatically rewrites it on every startup. The safemode’s patch layer will be restored to empty by this plugin; customizations should go throughDSH_SAFEMODE_BUNDLES.
Finally, a reminder as always: the plugin runs with the permissions of the current dsh process. It is recommended to read the source code (see the link at the end for the repository) and the license (MIT) before installing to ensure it meets your security requirements.
Summary¶
dsh-safemode-profile does one thing: keep dsh --profile safemode forever clean. With startup forced restoration, runtime dual-channel guardianship, and the optional file system read-only hardening, safemode will no longer quietly become “dirty.”
- Plugin Directory Page: https://www.skillhub.cn/plugins/jinsiyu/dsh-safemode-profile
- GitHub Repository: https://github.com/jinsiyu/dsh-safemode-profile
Note that the directory page is a community-maintained independent site with no official affiliation to DeepSeek / Huanfang, serving only as a search entry point.