零依赖原子文件写入库,通过独占创建临时文件+rename确保写入原子性,防止部分写入、符号链接劫持和权限错误,适用于需要安全更新配置文件和凭证存储的开发者
ⓘ 此插件是大仓库 deepseek-ai/deepseek-harness 的子包,星数与活跃度统计的是整个仓库。
- 语言
- TypeScript
- License
- MIT
- 分支
- master
安装
$ dsh plugin --profile web add npm:@deepseek-ai/dsh-atomic-write在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 deepseek-ai/deepseek-harness/packages/util/atomic-write:先查看仓库 https://github.com/deepseek-ai/deepseek-harness 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
English | 中文
Zero-dependency atomic file replacement shared by file-backed stores that must never leave partial, symlink-hijacked, or wider-than-intended content on disk — the user-settings document (dsh-settings-file) and the credentials store (dsh-credentials-local).
Surface
import { withFileLock, writeFileAtomic } from '@deepseek-ai/dsh-atomic-write'
declare const text: string
declare const render: (previous: string) => string
await writeFileAtomic('/home/u/.dsh/settings.yaml', text, { mode: 0o600 })
// Read-modify-write against the same file from several processes.
await withFileLock('/home/u/.dsh/settings.yaml', async () => {
await writeFileAtomic('/home/u/.dsh/settings.yaml', render(text), { mode: 0o600 })
})
writeFileAtomic commits one already-rendered string. The contract, in the order failures would exploit it:
- Exclusive-create temp (
wx, random suffix): the open refuses to follow a symlink planted at a guessable temp path. - The fresh inode carries
modethrough the rename: replacing a wider-permission file narrows it without a chmod race.modeis required so the permission decision stays visible at every call site (subject to the process umask, like every fresh inode). renamereplaces a symlinked target itself, never writing through to its referent.- Same-directory sibling keeps the rename on one filesystem, so the swap stays atomic.
- Parent directories are created; on any failure the temp is removed and the failure rethrown; readers observe either the old or the new complete content.
withFileLock serializes the writers of one file across processes, for the read-render-commit cycles a bare atomic commit cannot make safe on its own. The lock is a wx-created <filename>.lock sibling, so readers never contend; waiters back off exponentially and fail with a timeout rather than block forever. EEXIST identifies contention directly; EPERM does so only when a fresh lstat confirms that the lock path exists, covering Windows exclusive-create behavior without hiding an unrelated permission failure. A contender never removes the existing lock: age cannot distinguish a crashed owner from a paused live writer.
Model Experience
None, as this is a pure filesystem primitive; nothing here reaches a model request.
KV Cache effect
None; nothing here enters a request prefix.
Known Limitations and Deferred Work
- Atomic, not durable — no
fsyncof the file or its directory, so after a crash the rename may be observed unwound. The file-backed stores here re-read and republish on boot, keeping durability the caller's policy. - String content only — no
Bufferor stream form until a consumer needs one. - Orphaned locks require operator recovery — a process that exits while holding the lock can leave the sibling behind. Later writers time out without deleting it; an operator removes it only after verifying that no writer still owns it. File age alone is not safe evidence of abandonment.
收录徽章
[](https://deepseek-plugin.org/plugins/deepseek-ai/deepseek-harness/packages/util/atomic-write)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。