1.1.80: 修复 bug,修复稳定性(#168 #169 #170 #172 #176)

This commit is contained in:
叫我小杨同学 committed 2026-10-27 23:34:55 +08:00
1 parent bb93c6a2b6
commit d4d1c16252
10 files changed
+178 -40

No files matched your search

+10 -8
View File
@@ -4,7 +4,7 @@
<h1 align="center">⚔️ DeepSeek Harness cybersecurity red-team tool (dsh-purge)</h1>
<p align="center"><strong>Version 1.1.79</strong></p>
<p align="center"><strong>Version 1.1.80</strong></p>
<p align="center">
<em>DeepSeek Harness jailbreak: every model, swap prompts per model. Default prompt for 小码酱. Please star ⭐ If you build on this, see Attribution required.</em>
@@ -57,7 +57,7 @@ The author's personal channel: [t.me/LLM_PoJia](https://t.me/LLM_PoJia). Notes a
## What this is
**dsh-purge** is a cybersecurity red-team plugin for the official [DeepSeek Harness](https://www.deepseek.com/harness/) already installed on your machine. **1.1.79** targets **DSH 0.2.1-rc.2** (0.2.0 still works). Official **Web** (`dsh web`) and the official **desktop EXE** are both supported. Install and Apply them separately.
**dsh-purge** is a cybersecurity red-team plugin for the official [DeepSeek Harness](https://www.deepseek.com/harness/) already installed on your machine. **1.1.80** targets **DSH 0.2.1-rc.2** (0.2.0 still works). **DSH 0.2.1-rc.3 and newer RCs are not supported.** Official **Web** (`dsh web`) and the official **desktop EXE** are both supported. Install and Apply them separately.
Harness does more than forward a prompt. It rewrites prompts, approval gates, sandbox policy, and session migration at runtime. Asking only “will the model answer” treats a host-layer block as a model refusal. This plugin separates those two layers on your own install, for controlled evaluation and for seeing which default policy is too tight.
@@ -131,11 +131,12 @@ This repo is [Apache License 2.0](./LICENSE). Forks and redistributions must kee
## Supported hosts
**1.1.79 targets DSH 0.2.1-rc.2.** 0.2.0 still works. Do not apply it to 0.1.x.
**1.1.80 targets DSH 0.2.1-rc.2.** 0.2.0 still works. Do not apply it to 0.1.x.
- **dsh 0.2.1-rc.2** (official desktop / official `dsh web`): use **1.1.79**. Fixes `{{cwd}}` / `[cwd]` crash, patch #40 match, dropped `toolFilter`, host `dsh-tools` resolve, hostFs fd, desktop helper self-kill, `file:` archive update, Ctrl+Enter steer.
- **dsh 0.2.1-rc.2** (official desktop / official `dsh web`): use **1.1.80**. Fixes `{{cwd}}` / `[cwd]` crash, patch #40 match, dropped `toolFilter`, host `dsh-tools` resolve, hostFs fd, desktop helper self-kill, `file:` archive update, Ctrl+Enter steer.
- **dsh 0.2.0-rc.2**: use **1.1.40** or newer; this line also installs.
- **dsh 0.1.7** (incl. rc.1 / rc.2): use **1.1.39** or older — pick the tag on [Releases](https://github.com/YuJunZhiXue/dsh-purge/releases).
- **dsh 0.2.1-rc.3 / rc.4 and newer are not supported.** Unmatched patches stay pending or skipped; nothing is rewritten blindly. Stay on **0.2.1-rc.2**.
Unmatched patches stay pending or skipped; nothing is rewritten blindly.
@@ -183,9 +184,10 @@ pnpm add https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/mas
`pnpm add` and `dsh plugin add` fetch the package; `postinstall` writes `dsh-purge` into `dsh.profile.bundles` and adds a body `insert` in the profile `cordis.patch.yml`. Without that insert the host never loads the plugin and no button appears. pnpm 11/12 skips install scripts (`ERR_PNPM_IGNORED_BUILDS`) unless you allow the build:
```sh
pnpm add --allow-build=dsh-purge https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master
# If the package is already in node_modules:
pnpm approve-builds dsh-purge
pnpm add --allow-build=dsh-purge --allow-build=dsh-purge@https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master
# Already installed, warning only — the full specifier is required (name-only leaves "set this to true or false"):
pnpm approve-builds dsh-purge@https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master
# If bundles / insert are still missing:
node node_modules/dsh-purge/scripts/ensure-profile-bundle.mjs
```
@@ -194,7 +196,7 @@ Success: `node_modules/dsh-purge/package.json` exists, `"dsh-purge"` is in that
For the desktop client you can also click the button (`dsh://` deep link; it still downloads the same tarball):
<p align="center">
<a href="dsh://plugin/install?id=dsh-purge&name=dsh-purge&version=1.1.79&repo=YuJunZhiXue%2Fdsh-purge&permissions=%E7%B3%BB%E7%BB%9F%E6%8F%90%E7%A4%BA%E8%AF%8D%E6%B3%A8%E5%85%A5%2C%E6%9C%AC%E6%9C%BA%E8%A1%A5%E4%B8%81%2C%E8%AE%BE%E7%BD%AE%E9%A1%B5&downloadUrl=https%3A%2F%2Fcodeload.github.com%2FYuJunZhiXue%2Fdsh-purge%2Ftar.gz%2Frefs%2Fheads%2Fmaster"><strong>Install in desktop client</strong></a>
<a href="dsh://plugin/install?id=dsh-purge&name=dsh-purge&version=1.1.80&repo=YuJunZhiXue%2Fdsh-purge&permissions=%E7%B3%BB%E7%BB%9F%E6%8F%90%E7%A4%BA%E8%AF%8D%E6%B3%A8%E5%85%A5%2C%E6%9C%AC%E6%9C%BA%E8%A1%A5%E4%B8%81%2C%E8%AE%BE%E7%BD%AE%E9%A1%B5&downloadUrl=https%3A%2F%2Fcodeload.github.com%2FYuJunZhiXue%2Fdsh-purge%2Ftar.gz%2Frefs%2Fheads%2Fmaster"><strong>Install in desktop client</strong></a>
</p>
### 3. Three more clicks after the command
+10 -8
View File
@@ -4,7 +4,7 @@
<h1 align="center">⚔️ DeepSeek Harness 网络安全红队工具(dsh-purge)</h1>
<p align="center"><strong>Version 1.1.79</strong></p>
<p align="center"><strong>Version 1.1.80</strong></p>
<p align="center">
<em>DeepSeek Harness 破甲:让所有模型都能破甲,不同模型可换不同提示词;默认提示词面向国模「小码酱」。Jailbreak for every model — swap prompts per model. 求 Star 收藏 ⭐ 如要二开,请查看署名要求部分</em>
@@ -57,7 +57,7 @@
## 介绍
**dsh-purge** 是装在本机官方 [DeepSeek Harness](https://www.deepseek.com/harness/) 上的网络安全红队评测插件。当前 **1.1.79** 已适配 **DSH 0.2.1-rc.2**(0.2.0 仍可用)。官方 **Web**(`dsh web`)和官方 **桌面端**(EXE)都支持,两边分开装、分开应用。
**dsh-purge** 是装在本机官方 [DeepSeek Harness](https://www.deepseek.com/harness/) 上的网络安全红队评测插件。当前 **1.1.80** 已适配 **DSH 0.2.1-rc.2**(0.2.0 仍可用)。**不支持 DSH 0.2.1-rc.3 及更新的 rc。** 官方 **Web**(`dsh web`)和官方 **桌面端**(EXE)都支持,两边分开装、分开应用。
Harness 不只是把问题交给模型。它还会在运行时改提示词、审批门、沙箱和会话格式。只看「模型答不答」,会把宿主拦截误当成模型拒绝。这个插件在你自己的安装里把这两层分开,用来做受控评测,也用来看默认策略该不该收紧。
@@ -133,11 +133,12 @@ Harness 不只是把问题交给模型。它还会在运行时改提示词、审
## 适配范围
**1.1.79 已适配 DSH 0.2.1-rc.2**,0.2.0 仍可用。不要拿它去打 0.1.x。
**1.1.80 已适配 DSH 0.2.1-rc.2**,0.2.0 仍可用。不要拿它去打 0.1.x。
- **dsh 0.2.1-rc.2**(官方桌面 / 官方 `dsh web`):用 **1.1.79**。已修 `{{cwd}}` / `[cwd]` 整轮失败、补丁 #40 命中、`toolFilter` 废弃、`dsh-tools` 解析、hostFs fd、桌面换包自杀、`file:` 归档更新、Ctrl+Enter 插话。
- **dsh 0.2.1-rc.2**(官方桌面 / 官方 `dsh web`):用 **1.1.80**。已修 `{{cwd}}` / `[cwd]` 整轮失败、补丁 #40 命中、`toolFilter` 废弃、`dsh-tools` 解析、hostFs fd、桌面换包自杀、`file:` 归档更新、Ctrl+Enter 插话。
- **dsh 0.2.0-rc.2**:用 **1.1.40** 及以上;本页这档也能装。
- **dsh 0.1.7**(含 rc.1 / rc.2):用 **1.1.39** 及更早 —— 在 [Releases](https://github.com/YuJunZhiXue/dsh-purge/releases) 里选对应标签。
- **不支持 dsh 0.2.1-rc.3 / rc.4 及更新。** 宿主对不上时补丁会显示待应用或跳过,不会乱改文件。请退回 **0.2.1-rc.2** 再用本插件。
对不上的补丁会显示待应用或跳过,不会乱改文件。
@@ -185,9 +186,10 @@ pnpm add https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/mas
`pnpm add` 和 `dsh plugin add` 都会拉包;`postinstall` 再把 `dsh-purge` 写进 `dsh.profile.bundles`,并在用户层 `cordis.patch.yml` 补上本体 `insert`(没有这一行,宿主不加载插件,界面没有按钮)。pnpm 11/12 默认拦安装脚本(`ERR_PNPM_IGNORED_BUILDS`),请带上允许构建,或事后补跑:
```sh
pnpm add --allow-build=dsh-purge https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master
# 已经装上但只有警告时:
pnpm approve-builds dsh-purge
pnpm add --allow-build=dsh-purge --allow-build=dsh-purge@https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master
# 已经装上但只有警告时,必须带完整 specifier(只写 dsh-purge 会留下 set this to true or false):
pnpm approve-builds dsh-purge@https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master
# bundles / insert 还没写上时再补:
node node_modules/dsh-purge/scripts/ensure-profile-bundle.mjs
```
@@ -196,7 +198,7 @@ node node_modules/dsh-purge/scripts/ensure-profile-bundle.mjs
桌面客户端也可以点按钮(`dsh://` 唤起,下的仍是同一份压缩包):
<p align="center">
<a href="dsh://plugin/install?id=dsh-purge&name=dsh-purge&version=1.1.79&repo=YuJunZhiXue%2Fdsh-purge&permissions=%E7%B3%BB%E7%BB%9F%E6%8F%90%E7%A4%BA%E8%AF%8D%E6%B3%A8%E5%85%A5%2C%E6%9C%AC%E6%9C%BA%E8%A1%A5%E4%B8%81%2C%E8%AE%BE%E7%BD%AE%E9%A1%B5&downloadUrl=https%3A%2F%2Fcodeload.github.com%2FYuJunZhiXue%2Fdsh-purge%2Ftar.gz%2Frefs%2Fheads%2Fmaster"><strong>唤起客户端一键安装</strong></a>
<a href="dsh://plugin/install?id=dsh-purge&name=dsh-purge&version=1.1.80&repo=YuJunZhiXue%2Fdsh-purge&permissions=%E7%B3%BB%E7%BB%9F%E6%8F%90%E7%A4%BA%E8%AF%8D%E6%B3%A8%E5%85%A5%2C%E6%9C%AC%E6%9C%BA%E8%A1%A5%E4%B8%81%2C%E8%AE%BE%E7%BD%AE%E9%A1%B5&downloadUrl=https%3A%2F%2Fcodeload.github.com%2FYuJunZhiXue%2Fdsh-purge%2Ftar.gz%2Frefs%2Fheads%2Fmaster"><strong>唤起客户端一键安装</strong></a>
</p>
### 3. 装完还要做这三下
+35 -3
View File
@@ -904,7 +904,7 @@ window.__ModuleLoader__.load({ id: "dsh-purge", factory: (require) => {
.dshp-pill.is-wait{color:var(--dshp-warn);border-color:color-mix(in srgb,var(--dshp-warn) 30%,var(--dshp-line))}
.dshp-pill.is-miss{color:var(--dshp-mute)}
.dshp-pill.is-bad{color:var(--dshp-bad)}
.dshp-btn{appearance:none;font-family:inherit;font-size:16px;line-height:24px;font-weight:600;padding:8px 12px;border-radius:8px;border:1px solid transparent;cursor:pointer;transition:transform 500ms var(--dshp-ease),opacity 300ms var(--dshp-ease)}
.dshp-btn{appearance:none;font-family:system-ui,-apple-system,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans SC",sans-serif;font-size:16px;line-height:24px;font-weight:600;padding:8px 12px;border-radius:8px;border:1px solid transparent;cursor:pointer;transition:transform 500ms var(--dshp-ease),opacity 300ms var(--dshp-ease);-webkit-text-fill-color:currentColor;text-indent:0;overflow:visible}
.dshp-btn:hover:not(:disabled){transform:translateY(-1px)}
.dshp-btn:active:not(:disabled){transform:scale(0.98)}
.dshp-btn:disabled{opacity:.45;cursor:not-allowed}
@@ -1083,6 +1083,38 @@ body:not([data-ds-dark-theme]) .dshp-auth-ops button.primary{background:var(--ds
.dshp-tab-btn:hover{color:var(--dsw-alias-label-primary,currentColor)}
.dshp-tab-btn.on{color:var(--dsw-alias-brand-primary,#6dbf8c)}
.dshp-tab-btn.on:after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;border-radius:2px;background:var(--dsw-alias-brand-primary,#6dbf8c)}
/* 宿主工具条按钮常继承图标字体 / font-size:0 / color:transparent,字在 DOM 里但看不见(#169)。 */
.dshp-hero-chip-btn,.dshp-tab-btn,.dshp-launch,.dshp-icon-btn,.dshp-hbtn,.dshp-btn,.dshp-dock-tab,.dshp-dock-head button,.dshp-auth-ops button,.dshp-switch button{
font-family:system-ui,-apple-system,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans SC",sans-serif!important;
-webkit-text-fill-color:currentColor!important;
text-indent:0!important;
letter-spacing:normal!important;
overflow:visible!important;
text-overflow:clip!important;
width:auto!important;
max-width:none!important;
}
.dshp-hero-chip-btn{
font-size:12.5px!important;
line-height:1!important;
font-weight:600!important;
color:#1a1916!important;
-webkit-text-fill-color:#1a1916!important;
min-width:max-content!important;
height:28px!important;
padding:0 12px!important;
}
.dshp-hero-chip-btn.on{color:#2f6b4f!important;-webkit-text-fill-color:#2f6b4f!important}
body[data-ds-dark-theme] .dshp-hero-chip-btn,.dshp-dock[data-theme="dusk"] .dshp-hero-chip-btn{color:#f4f1ea!important;-webkit-text-fill-color:#f4f1ea!important}
body[data-ds-dark-theme] .dshp-hero-chip-btn.on,.dshp-dock[data-theme="dusk"] .dshp-hero-chip-btn.on{color:#6dbf8c!important;-webkit-text-fill-color:#6dbf8c!important}
.dshp-tab-btn{font-size:13px!important;line-height:16px!important;font-weight:500!important;color:#5c564c!important;-webkit-text-fill-color:#5c564c!important;padding:0 4px 9px!important}
.dshp-tab-btn.on{color:#2f6b4f!important;-webkit-text-fill-color:#2f6b4f!important}
body[data-ds-dark-theme] .dshp-tab-btn{color:#c9c3b8!important;-webkit-text-fill-color:#c9c3b8!important}
body[data-ds-dark-theme] .dshp-tab-btn.on{color:#6dbf8c!important;-webkit-text-fill-color:#6dbf8c!important}
.dshp-launch{font-size:13px!important;line-height:1!important;font-weight:600!important;min-width:max-content!important}
.dshp-btn{font-size:16px!important;line-height:24px!important;font-weight:600!important}
.dshp-btn-primary{color:#fff!important;-webkit-text-fill-color:#fff!important}
.dshp-btn-tiny{font-size:14px!important;line-height:20px!important}
/* Glass follows the host color. Weight and background opacity are kept separate: the shell is translucent, the text sits on a more solid layer. */
.dshp-dock{font-family:inherit;font-size:14px;line-height:1.6;font-weight:500;-webkit-font-smoothing:antialiased;text-shadow:none}
.dshp-dock[data-theme="white"],.dshp-dock[data-theme="dusk"]{backdrop-filter:blur(22px) saturate(1.4)!important;-webkit-backdrop-filter:blur(22px) saturate(1.4)!important;color:var(--dshp-ink)!important;border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary,#6d8f78) 34%,transparent)!important;--dshp-glass:blur(18px) saturate(1.35);--dshp-accent:var(--dsw-alias-brand-primary,#3d8f68);--dshp-fill:color-mix(in srgb,var(--dsw-alias-brand-primary,#6dbf8c) 14%,transparent)}
@@ -3677,9 +3709,9 @@ body[data-ds-dark-theme] .dshp-rewind-item span{color:var(--dsw-alias-label-tert
.rt-dot{width:8px;height:8px;border-radius:50%;background:var(--dsw-alias-brand-primary)}
.rt-spacer{flex:1}
.rt-btn{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:inherit;
border-radius:6px;padding:3px 9px;font-size:12px;cursor:pointer;font-family:inherit;white-space:nowrap}
border-radius:6px;padding:3px 9px;font-size:12px;cursor:pointer;font-family:system-ui,-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;white-space:nowrap;-webkit-text-fill-color:currentColor;overflow:visible}
.rt-btn:hover{border-color:var(--dsw-alias-border-l2)}
.rt-btn-primary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:#fff}
.rt-btn-primary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:#fff;-webkit-text-fill-color:#fff}
.rt-btn-primary:hover{opacity:.9}
.rt-btn:disabled{opacity:.5;cursor:default}
.rt-tabs{display:flex;flex-wrap:wrap;gap:2px;padding:6px 12px 0;border-bottom:1px solid var(--dsw-alias-border-l1)}
+1 -1
View File
@@ -2530,7 +2530,7 @@ const COMPLETE_PROMPT_WATERFALL_INJECT =
"\t\t\t\treturn [...purge, ...tail, base]; // [dsh-purge] complete prompt keeps inject + agent-instructions\n" +
"\t\t\t})(completeSection, dshPurgeSections, dshPurgeRest),\n" +
"\t\t\tcontexts: runtimeContextSuppressed ? [] : transformed.contexts\n" +
"\t\t};";
"\t\t};";
function clearShellNetworkBan(pattern) {
return pattern
+87 -13
View File
@@ -105,24 +105,98 @@ export function ensureProfileBundles(profileDir) {
return { ok: true, wrote: true, path: fp };
}
function readPurgeTarball() {
try {
const pkg = JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"));
return String(pkg?.dsh?.install?.tarball || "").trim();
} catch {
return "https://codeload.github.com/YuJunZhiXue/dsh-purge/tar.gz/refs/heads/master";
}
}
/** pnpm 12 会给 tarball 单独写一行 `dsh-purge@https://...: set this to true or false`。只写包名不够。 */
export function purgePnpmBuildSpecs() {
const specs = ["dsh-purge"];
const tarball = readPurgeTarball();
if (tarball) specs.push(`${PURGE_NAME}@${tarball}`);
return specs;
}
function isPurgeAllowBuildKey(key) {
const name = String(key || "").replace(/^['"]|['"]$/g, "");
return name === PURGE_NAME || name.startsWith(`${PURGE_NAME}@`);
}
function parseAllowBuildLine(line) {
const m = String(line || "").match(/^[ \t]+(?:"([^"]+)"|'([^']+)'|(\S+?))[ \t]*:[ \t]*(.*?)\s*$/);
if (!m) return null;
return { key: m[1] || m[2] || m[3], value: String(m[4] || "").trim() };
}
function formatAllowBuildLine(key) {
return ` ${key}: true`;
}
/** 把 dsh-purge 以及 `dsh-purge@tarball` 都写成 true,避免装别的插件还报 ERR_PNPM_IGNORED_BUILDS(#168)。 */
export function rewritePnpmAllowBuilds(raw) {
const wanted = purgePnpmBuildSpecs();
const text = String(raw || "").replace(/\r\n/g, "\n");
if (!text.trim()) {
return `allowBuilds:\n${wanted.map(formatAllowBuildLine).join("\n")}\n`;
}
const lines = text.split(/\r?\n/);
let start = -1;
for (let i = 0; i < lines.length; i += 1) {
if (/^allowBuilds[ \t]*:/.test(lines[i])) {
start = i;
break;
}
}
if (start < 0) {
const prefix = text.endsWith("\n") ? "" : "\n";
return `${text}${prefix}\nallowBuilds:\n${wanted.map(formatAllowBuildLine).join("\n")}\n`;
}
let end = lines.length;
const kept = [];
const seen = new Set();
for (let i = start + 1; i < lines.length; i += 1) {
const line = lines[i];
if (!line.trim()) {
end = i;
break;
}
if (/^\S/.test(line)) {
end = i;
break;
}
const parsed = parseAllowBuildLine(line);
if (!parsed) {
kept.push(line);
continue;
}
if (isPurgeAllowBuildKey(parsed.key)) {
kept.push(formatAllowBuildLine(parsed.key));
seen.add(parsed.key);
continue;
}
kept.push(line);
}
for (const key of wanted) {
if (!seen.has(key)) kept.push(formatAllowBuildLine(key));
}
const next = [...lines.slice(0, start + 1), ...kept, ...lines.slice(end)].join("\n");
return next.endsWith("\n") ? next : `${next}\n`;
}
/** pnpm 11/12 默认拦 postinstall(ERR_PNPM_IGNORED_BUILDS)。写进 profile 的 allowBuilds,下次 add 能跑脚本。 */
export function ensurePnpmAllowBuild(profileDir) {
const fp = path.join(profileDir, "pnpm-workspace.yaml");
let text = "";
try { text = fs.readFileSync(fp, "utf8"); } catch { text = ""; }
if (/(^|\n)[ \t]*dsh-purge[ \t]*:[ \t]*true\b/.test(text)) return { ok: true, wrote: false, path: fp };
if (!String(text).trim()) {
fs.writeFileSync(fp, "allowBuilds:\n dsh-purge: true\n", "utf8");
return { ok: true, wrote: true, path: fp };
}
if (/(^|\n)allowBuilds[ \t]*:/.test(text)) {
const next = text.replace(/(^|\n)(allowBuilds[ \t]*:[ \t]*\n)/, "$1$2 dsh-purge: true\n");
if (next === text) return { ok: true, wrote: false, path: fp };
fs.writeFileSync(fp, next, "utf8");
return { ok: true, wrote: true, path: fp };
}
const prefix = text.endsWith("\n") ? "" : "\n";
fs.writeFileSync(fp, `${text}${prefix}\nallowBuilds:\n dsh-purge: true\n`, "utf8");
const current = String(text || "").replace(/\r\n/g, "\n");
const next = rewritePnpmAllowBuilds(current);
if (next === current) return { ok: true, wrote: false, path: fp };
fs.writeFileSync(fp, next, "utf8");
return { ok: true, wrote: true, path: fp };
}
+2 -2
View File
@@ -51,9 +51,9 @@ window.__ModuleLoader__.load({
.rt-dot{width:8px;height:8px;border-radius:50%;background:var(--dsw-alias-brand-primary)}
.rt-spacer{flex:1}
.rt-btn{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:inherit;
border-radius:6px;padding:3px 9px;font-size:12px;cursor:pointer;font-family:inherit;white-space:nowrap}
border-radius:6px;padding:3px 9px;font-size:12px;cursor:pointer;font-family:system-ui,-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;white-space:nowrap;-webkit-text-fill-color:currentColor;overflow:visible}
.rt-btn:hover{border-color:var(--dsw-alias-border-l2)}
.rt-btn-primary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:#fff}
.rt-btn-primary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:#fff;-webkit-text-fill-color:#fff}
.rt-btn-primary:hover{opacity:.9}
.rt-btn:disabled{opacity:.5;cursor:default}
.rt-tabs{display:flex;flex-wrap:wrap;gap:2px;padding:6px 12px 0;border-bottom:1px solid var(--dsw-alias-border-l1)}
+1 -1
View File
@@ -1,4 +1,4 @@
import { promises as fsp } from "node:fs";
import fs, { promises as fsp } from "node:fs";
import { spawnSync } from "node:child_process";
import os from "node:os";
import path from "node:path";
+11 -3
View File
@@ -73,12 +73,23 @@ function localDataOffset(buf, localOffset) {
return localOffset + 30 + nameLen + extraLen;
}
function isZipDirectoryEntry(name) {
return /[/\\]$/.test(String(name || ""));
}
export function extractZipBuffer(buf, dest) {
fs.mkdirSync(dest, { recursive: true });
const root = path.resolve(dest);
const prefix = root.endsWith(path.sep) ? root : root + path.sep;
for (const entry of readZipEntries(buf)) {
const rel = safeZipName(entry.name);
if (!rel) continue;
const out = path.resolve(root, rel);
if (out !== root && !out.startsWith(prefix)) throw new Error("Invalid zip path");
if (isZipDirectoryEntry(entry.name)) {
fs.mkdirSync(out, { recursive: true });
continue;
}
if (entry.compSize === 0xffffffff || entry.localOffset === 0xffffffff) {
throw new Error("zip64 is not supported");
}
@@ -90,9 +101,6 @@ export function extractZipBuffer(buf, dest) {
if (end > buf.length) throw new Error("Truncated zip data");
const compressed = buf.subarray(start, end);
const body = entry.method === 0 ? compressed : zlib.inflateRawSync(compressed);
const out = path.resolve(root, rel);
const prefix = root.endsWith(path.sep) ? root : root + path.sep;
if (out !== root && !out.startsWith(prefix)) throw new Error("Invalid zip path");
fs.mkdirSync(path.dirname(out), { recursive: true });
fs.writeFileSync(out, body);
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "dsh-purge",
"version": "1.1.79",
"version": "1.1.80",
"description": "DeepSeek Harness 破甲:让所有模型都能破甲,不同模型可换不同提示词;默认提示词面向国模「小码酱」。Jailbreak for every model — swap prompts per model. 求 Star 收藏 ⭐ 如要二开,请查看署名要求部分",
"type": "module",
"main": "lib/index.js",
+20
View File
@@ -1,3 +1,23 @@
# 1.1.80
## 中文
- 版本 **1.1.80**。修复 bug,修复稳定性。
- **#168**:pnpm 12 的 `allowBuilds` 把 `dsh-purge@codeload...` 也写成 `true`,装别的插件不再留下 `set this to true or false`。
- **#169**:芯片 / 应用按钮强制系统字体和实色字,不再被宿主图标字体吃掉。
- **#170**:纯 Node 解 zip 时目录条目建目录,不再写成同名空文件导致 EEXIST。
- **#172**:`lib/skills.js` 补上 `fs`,#54 软链重叠守卫重新生效。
- **#176**:写清 **不支持 DSH 0.2.1-rc.3 及更新的 rc**,请退回 **0.2.1-rc.2**。对不上的补丁待应用或跳过,不乱改文件。
## English
- **1.1.80**. Bug fixes and stability.
- **#168**: pnpm 12 `allowBuilds` also sets `dsh-purge@codeload...` to `true`, so installing other plugins no longer leaves `set this to true or false`.
- **#169**: chip / Apply buttons force a system font and solid text color so the host icon font cannot hide the label.
- **#170**: Node zip fallback creates directories for directory entries instead of empty files (no more EEXIST).
- **#172**: import `fs` in `lib/skills.js` so the #54 symlink overlap guard works again.
- **#176**: **DSH 0.2.1-rc.3 and newer RCs are not supported.** Stay on **0.2.1-rc.2**. Unmatched patches stay pending or skipped.
# 1.1.79
## 中文