agent-bypass 2.20.0 → 2.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/install.js CHANGED
@@ -5,11 +5,9 @@
5
5
  * agent-bypass installer — 自动安装到 Pi / OpenCode / Claude Code / Grok Build / OpenMinis
6
6
  *
7
7
  * 用法:
8
- * npx agent-bypass 默认安装(检测到的 Pi + OpenCode + DeepSeek Harness,iSH 上加 OpenMinis;其余 harness 须显式指定)
8
+ * npx agent-bypass 默认安装(只装 Pi + OpenCode;其余 harness 须显式指定)
9
9
  * npx agent-bypass --pi 只装 Pi(三层注入:AGENTS.md + APPEND_SYSTEM.md + prompts/ck.md)
10
10
  * npx agent-bypass --opencode 只装 OpenCode(instructions 注入 + commands/ck.md)
11
- * npx agent-bypass --dsh 只装 DeepSeek Harness(技能进 DSH 技能根 + Ck 模式预设写入 DSH profile)
12
- * npx agent-bypass --doctor 环境自检(平台 / 工具链 / harness / DSH 预设 / 技能版本,只读)
13
11
  * npx agent-bypass --claude 只装 Claude Code(skills + commands/ck.md + CLAUDE.md 注入)
14
12
  * npx agent-bypass --grok 只装 Grok Build(skills + ~/.agents/commands/ck.md + AGENTS.md 注入)
15
13
  * npx agent-bypass --ccswitch 只装 CC Switch(同步其技能库中已纳管的 agent-bypass)
@@ -31,7 +29,6 @@
31
29
 
32
30
  const fs = require('fs');
33
31
  const path = require('path');
34
- const { spawnSync } = require('child_process');
35
32
  const os = require('os');
36
33
  const { isUtf8: nativeIsUtf8 } = require('buffer');
37
34
  // Node < 18.14 无 buffer.isUtf8:降级为重编码比对(非法字节会变替换符,可检出)
@@ -43,29 +40,13 @@ const ROOT = path.join(__dirname, '..');
43
40
  const HOME = os.homedir();
44
41
  const args = process.argv.slice(2);
45
42
  const has = (f) => args.includes(f);
46
- const only = ['--pi', '--opencode', '--dsh', '--claude', '--grok', '--minis', '--ccswitch'].filter(has);
43
+ const only = ['--pi', '--opencode', '--claude', '--grok', '--minis', '--ccswitch'].filter(has);
47
44
  const noInject = has('--no-inject');
48
45
  const uninstall = has('--uninstall');
49
46
  const injectGlobal = has('--inject-global');
50
47
 
51
- if (has('--help') || has('-h')) {
52
- let ver = '?';
53
- try { ver = require(path.join(ROOT, 'package.json')).version; } catch (e) { /* ignore */ }
54
- console.log(`agent-bypass installer v${ver}
55
- 用法: npx agent-bypass [目标...] [选项]
56
- 目标(可组合): --pi --opencode --dsh --claude --grok --minis --ccswitch
57
- 默认: 检测到的 Pi + OpenCode + DeepSeek Harness(iSH 上另含 OpenMinis)
58
- 选项: --no-inject 只装技能文件(跳过注入/预设); --inject-global OpenMinis 全局注入; --uninstall 卸载; --doctor 环境自检; -h/--help 帮助`);
59
- process.exit(0);
60
- }
61
-
62
48
  const MARK_B = '<!-- agent-bypass:begin -->';
63
49
  const MARK_E = '<!-- agent-bypass:end -->';
64
- // DeepSeek Harness:Ck 模式预设写入 profile patch 的标记块(YAML 注释,幂等更新)
65
- const DSH_MARK_B = '# >>> agent-bypass:dsh-preset-begin';
66
- const DSH_MARK_E = '# <<< agent-bypass:dsh-preset-end';
67
- const DSH_HOME_DIR = process.env.DSH_HOME || path.join(HOME, '.dsh');
68
- const DSH_AGENTS_DIR = process.env.DSH_AGENTS_HOME || path.join(HOME, '.agents');
69
50
  const SKILL_FILES = ['SKILL.md', 'ck-hunter.md', 'SYSTEM_PROMPT.md', 'config.yaml.example', 'references', 'scripts'];
70
51
  // 本安装器管理的全部文件/目录(含历史遗留)——重装时先清再拷,保证干净覆盖;用户自有文件(config.yaml)不在其中
71
52
  const MANAGED = ['SKILL.md', 'ck-hunter.md', 'SYSTEM_PROMPT.md', 'config.yaml.example', 'references', 'scripts', 'PLAYBOOK.md', 'eval'];
@@ -221,13 +202,6 @@ function removeSkills(dir) {
221
202
  }
222
203
  const mp = manifestPath(target);
223
204
  if (exists(mp)) { try { fs.rmSync(mp, { force: true }); } catch (e) {} }
224
- // 清理空的受管子目录(references/scripts),卸载后不留空壳
225
- for (const sub of ['references', 'scripts']) {
226
- const p = path.join(target, sub);
227
- try {
228
- if (exists(p) && fs.statSync(p).isDirectory() && !fs.readdirSync(p).length) fs.rmdirSync(p);
229
- } catch (e) { /* 非空或权限问题则保留 */ }
230
- }
231
205
  ok(`已清除本技能文件 ${n} 项(${target})`);
232
206
  try {
233
207
  if (!fs.readdirSync(target).length) { fs.rmdirSync(target); ok(`已删除空目录 ${target}`); }
@@ -519,323 +493,30 @@ function uninstallMinis() {
519
493
  stripMarked('/var/minis/memory/GLOBAL.md', 'OpenMinis GLOBAL.md');
520
494
  }
521
495
 
522
- // ============ DeepSeek Harness ============
523
- // 技能: ~/.agents/skills/agent-bypass/(DSH user-agents 技能根,自动发现并加载;与开放标准/CC Switch 同路径)
524
- // Ck 模式: <DSH_HOME>/profiles/<profile>/cordis.patch.yml 内写入 @deepseek-ai/dsh-agent-preset 声明
525
- // —— 标记块幂等;安装后 新会话 → Agent 预设 → 「Ck 万能执行员」,可在设置里设为新任务默认
526
- // 预设声明: dsh/preset.template.yml(官方 standard 预设插件行 + __PERSONA__ 占位)由 dsh/build-template.js 维护
527
- function dshProfileDir() {
528
- const base = path.join(DSH_HOME_DIR, 'profiles');
529
- const order = [];
530
- if (process.env.DSH_PROFILE) order.push(process.env.DSH_PROFILE);
531
- if (!order.includes('desktop')) order.push('desktop');
532
- let dirs = [];
533
- try {
534
- dirs = fs.readdirSync(base, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
535
- } catch (e) { /* profiles 尚未创建 */ }
536
- for (const d of dirs) if (!order.includes(d)) order.push(d);
537
- for (const name of order) {
538
- const dir = path.join(base, name);
539
- if (exists(path.join(dir, 'cordis.patch.yml'))) return { dir, name };
540
- }
541
- return { dir: path.join(base, process.env.DSH_PROFILE || 'desktop'), name: process.env.DSH_PROFILE || 'desktop' };
542
- }
543
-
544
- // 读取 dsh/preset.template.yml,把 __PERSONA__ 替换成 dsh/persona.md(16 空格缩进的 YAML 块标量内容)
545
- function dshPresetBlock() {
546
- const tplFile = path.join(ROOT, 'dsh', 'preset.template.yml');
547
- const perFile = path.join(ROOT, 'dsh', 'persona.md');
548
- if (!exists(tplFile)) throw new Error('dsh/preset.template.yml 缺失(用 node dsh/build-template.js 生成)');
549
- if (!exists(perFile)) throw new Error('dsh/persona.md 缺失');
550
- const tpl = fs.readFileSync(tplFile, 'utf8').replace(/\r\n/g, '\n').trimEnd();
551
- const persona = fs.readFileSync(perFile, 'utf8').replace(/\r\n/g, '\n').trimEnd();
552
- if (!persona) throw new Error('dsh/persona.md 内容为空');
553
- const PH = ' __PERSONA__';
554
- if (!tpl.includes(PH)) throw new Error('dsh/preset.template.yml 缺少 __PERSONA__ 占位符(用 node dsh/build-template.js 重新生成)');
555
- const indented = persona.split('\n').map((l) => (l.trim() ? ' ' + l : '')).join('\n');
556
- // 注意:必须用函数替换——替换字符串会解释 $$/$&/$`/$' 等模式,会吃掉 persona 里的 $$(如 PHP 变量变量)
557
- return tpl.replace(PH, () => indented);
558
- }
559
-
560
- function injectDshPreset(profileDir) {
561
- const file = path.join(profileDir, 'cordis.patch.yml');
562
- const buf = fs.readFileSync(file);
563
- if (!isUtf8(buf)) {
564
- warn(`DSH profile patch 非 UTF-8,跳过注入(防乱码)\u2192 ${file}`);
565
- manual('DSH Ck 模式:profile patch 非 UTF-8,未注入');
566
- return false;
567
- }
568
- let cur = buf.toString('utf8');
569
- const bom = cur.startsWith('\uFEFF') ? '\uFEFF' : '';
570
- if (bom) cur = cur.slice(1);
571
- const eol = cur.includes('\r\n') ? '\r\n' : '\n';
572
- // 已通过 DSH bundle 方式安装过 Ck 预设 → 不再写 patch(避免 preset-ck 行 id 冲突)
573
- let bundleInstalled = false;
574
- try {
575
- const pkg = JSON.parse(fs.readFileSync(path.join(profileDir, 'package.json'), 'utf8'));
576
- const names = [...Object.keys(pkg.dependencies || {}), ...(((pkg.dsh || {}).profile || {}).bundles || [])];
577
- bundleInstalled = names.some((n) => /ck-preset/.test(String(n)));
578
- } catch (e) { /* 无 package.json 视为未安装 bundle */ }
579
- if (bundleInstalled) {
580
- warn('检测到已通过 bundle 安装的 Ck 预设(plugin_manager install_bundle),跳过 profile patch 注入');
581
- info('统一由 npx 管理:先在 DeepSeek Harness 里执行 plugin_manager remove_bundle @local/dsh-ck-preset,再重跑本命令');
582
- manual('DSH Ck 模式:存在 bundle 安装,patch 注入被跳过');
583
- return false;
584
- }
585
- const block = dshPresetBlock().split('\n').join(eol); // 跟随目标文件换行风格(Windows CRLF)
586
- const sec = [DSH_MARK_B, block, DSH_MARK_E].join(eol);
587
- const bi = cur.indexOf(DSH_MARK_B), ei = cur.indexOf(DSH_MARK_E);
588
- let out;
589
- if (bi !== -1 && ei > bi) {
590
- out = cur.slice(0, bi) + sec + cur.slice(ei + DSH_MARK_E.length);
591
- ok('DSH Ck 模式预设块已更新(cordis.patch.yml)');
592
- } else {
593
- if (cur.includes('preset-ck')) {
594
- warn('cordis.patch.yml 已含 preset-ck 声明(非本安装器标记块),跳过注入以免行 id 冲突');
595
- manual('DSH Ck 模式:已存在 preset-ck 声明,未自动覆盖');
596
- return false;
597
- }
598
- const stripped = cur.split(eol).filter((l) => !/^\s*#/.test(l)).join('').trim();
599
- if (stripped === '' || stripped === '[]') {
600
- const kept = cur.split(eol).filter((l) => /^\s*#/.test(l)).join(eol);
601
- out = (kept.trim() ? kept + eol : '') + sec + eol;
602
- ok('DSH Ck 模式预设块已写入(新建 patch 内容)');
603
- } else {
604
- out = cur.replace(/\s+$/, '') + eol + sec + eol;
605
- ok('DSH Ck 模式预设块已追加(cordis.patch.yml)');
606
- }
607
- }
608
- fs.writeFileSync(file, bom + out, 'utf8');
609
- return true;
610
- }
611
-
612
- function removeDshPreset(profileDir) {
613
- const file = path.join(profileDir, 'cordis.patch.yml');
614
- if (!exists(file)) return;
615
- const buf = fs.readFileSync(file);
616
- if (!isUtf8(buf)) { warn('DSH profile patch 非 UTF-8,跳过'); return; }
617
- let cur = buf.toString('utf8');
618
- const bom = cur.startsWith('\uFEFF') ? '\uFEFF' : '';
619
- if (bom) cur = cur.slice(1);
620
- const eol = cur.includes('\r\n') ? '\r\n' : '\n';
621
- const bi = cur.indexOf(DSH_MARK_B), ei = cur.indexOf(DSH_MARK_E);
622
- if (bi === -1 || ei < bi) { info('DSH Ck 模式预设块不存在,跳过'); return; }
623
- let out = (cur.slice(0, bi) + cur.slice(ei + DSH_MARK_E.length))
624
- .replace(/[ \t]+$/gm, '')
625
- .replace(/\n{3,}/g, '\n\n')
626
- .replace(/\s+$/, '');
627
- // 只留注释/空白时补回空列表,保证 YAML 仍是合法数组(loader 期望数组)
628
- const stripped = out.split(eol).filter((l) => !/^\s*#/.test(l)).join('').trim();
629
- if (!stripped) out = (out.trim() ? out + eol : '') + '[]';
630
- fs.writeFileSync(file, bom + out + eol, 'utf8');
631
- ok('DSH Ck 模式预设块已移除(cordis.patch.yml)');
632
- }
633
-
634
- // DSH 卸载技能:共享根可能是软链(指向 Pi/CC Switch 真身)→ 只解链、不删真身
635
- function removeDshSkills(dir) {
636
- if (!/(^|[\\/])agent-bypass$/.test(dir)) {
637
- warn(`跳过 DSH 技能卸载:目标不是 agent-bypass 专属目录 \u2192 ${dir}`);
638
- return;
639
- }
640
- try {
641
- if (fs.lstatSync(dir).isSymbolicLink()) {
642
- fs.rmSync(dir, { force: true });
643
- ok(`已删除技能软链 ${dir}(真身保留,可能属于其他 harness)`);
644
- return;
645
- }
646
- } catch (e) { return; /* 不存在 */ }
647
- removeSkills(dir);
648
- }
649
-
650
- // DSH 安装目录探测:只用于决定默认 targets 是否包含 dsh(完整探测在 dsh/build-template.js)
651
- function dshAppInstalled() {
652
- if (process.env.DSH_APP_PATH || process.env.DSH_ASAR_PATH) return true;
653
- const dirs = [];
654
- if (process.platform === 'darwin') {
655
- dirs.push('/Applications/DeepSeek Harness.app', path.join(HOME, 'Applications', 'DeepSeek Harness.app'));
656
- } else if (process.platform === 'win32') {
657
- const local = process.env.LOCALAPPDATA || path.join(HOME, 'AppData', 'Local');
658
- const pf = process.env.ProgramFiles || 'C:\\Program Files';
659
- const pf86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)';
660
- dirs.push(
661
- path.join(local, 'Programs', 'DeepSeek Harness'),
662
- path.join(local, 'DeepSeek Harness'),
663
- path.join(pf, 'DeepSeek Harness'),
664
- path.join(pf86, 'DeepSeek Harness'),
665
- );
666
- } else {
667
- dirs.push('/opt/DeepSeek Harness', '/opt/deepseek-harness', '/usr/lib/deepseek-harness', '/usr/share/deepseek-harness');
668
- }
669
- const asarRels = [path.join('Contents', 'Resources', 'app.asar'), path.join('resources', 'app.asar'), 'app.asar'];
670
- for (const d of dirs) for (const rel of asarRels) if (exists(path.join(d, rel))) return true;
671
- if (process.platform === 'darwin') {
672
- try {
673
- const r = spawnSync('mdfind', ['kMDItemCFBundleIdentifier == "com.deepseek.dsh"'], { encoding: 'utf8', timeout: 8000 });
674
- if (String(r.stdout || '').trim()) return true;
675
- } catch (e) { /* Spotlight 不可用时忽略 */ }
676
- }
677
- return false;
678
- }
679
-
680
- function installDsh() {
681
- console.log('\n[DeepSeek Harness]');
682
- installSkills(path.join(DSH_AGENTS_DIR, 'skills', 'agent-bypass'));
683
- if (noInject) { info('--no-inject:只装技能,跳过 Ck 模式预设注入'); return; }
684
- const { dir, name } = dshProfileDir();
685
- if (!exists(path.join(dir, 'cordis.patch.yml'))) {
686
- warn(`未检测到 DSH profile(${dir} 缺 cordis.patch.yml)——技能已装,Ck 模式预设跳过`);
687
- info('先启动一次 DeepSeek Harness 生成 profile,再重跑 npx agent-bypass --dsh');
688
- manual('DSH Ck 模式:profile 未初始化,未注入预设');
689
- return;
690
- }
691
- if (injectDshPreset(dir)) {
692
- info(`Ck 模式已注入 profile「${name}」:新会话 \u2192 Agent 预设 \u2192 「Ck 万能执行员」(可在设置里设为新任务默认)`);
693
- info('若预设列表未立即出现,重启一次 DeepSeek Harness');
694
- if (process.platform === 'darwin') info('macOS 启动: open -a "DeepSeek Harness"');
695
- else if (process.platform === 'win32') info('Windows 启动: 开始菜单搜索 DeepSeek Harness');
696
- }
697
- }
698
-
699
- function uninstallDsh() {
700
- console.log('\n[DeepSeek Harness]');
701
- removeDshSkills(path.join(DSH_AGENTS_DIR, 'skills', 'agent-bypass'));
702
- const { dir } = dshProfileDir();
703
- if (exists(path.join(dir, 'cordis.patch.yml'))) removeDshPreset(dir);
704
- }
705
-
706
- // ============ 环境自检(--doctor,只读) ============
707
- function which(cmd) {
708
- const finder = process.platform === 'win32' ? 'where' : 'which';
709
- try {
710
- const r = spawnSync(finder, [cmd], { encoding: 'utf8', timeout: 5000 });
711
- const line = String(r.stdout || '').split(/\r?\n/).map((s) => s.trim()).find(Boolean);
712
- return r.status === 0 && line ? line : null;
713
- } catch (e) { return null; }
714
- }
715
- function manifestVersion(dir) {
716
- try {
717
- const m = JSON.parse(fs.readFileSync(path.join(dir, '.agent-bypass-manifest.json'), 'utf8'));
718
- return m.version || null;
719
- } catch (e) { return null; }
720
- }
721
- function systemDnsIpv4(name) {
722
- const code = `require('dns').lookup(${JSON.stringify(name)},{family:4},(e,a)=>{process.stdout.write(a||'')})`;
723
- try {
724
- const r = spawnSync(process.execPath, ['-e', code], { encoding: 'utf8', timeout: 8000 });
725
- const ip = String(r.stdout || '').trim();
726
- return /^\d{1,3}(?:\.\d{1,3}){3}$/.test(ip) ? ip : null;
727
- } catch (e) { return null; }
728
- }
729
- function isFakeIp(ip) {
730
- return /^(198\.18\.|198\.19\.|240\.|198\.51\.100\.|203\.0\.113\.)/.test(String(ip));
731
- }
732
- function harnessSkillDirs() {
733
- return [
734
- ['Pi', path.join(HOME, '.pi', 'agent', 'skills', 'agent-bypass')],
735
- ['OpenCode', path.join(HOME, '.config', 'opencode', 'skills', 'agent-bypass')],
736
- ['DeepSeek Harness', path.join(DSH_AGENTS_DIR, 'skills', 'agent-bypass')],
737
- ['Claude Code', path.join(HOME, '.claude', 'skills', 'agent-bypass')],
738
- ['Grok Build', path.join(HOME, '.grok', 'skills', 'agent-bypass')],
739
- ['OpenMinis', '/var/minis/skills/agent-bypass'],
740
- ];
741
- }
742
- function harnessDetected(name) {
743
- const map = { Pi: detectPi, OpenCode: detectOc, 'DeepSeek Harness': detectDsh, 'Claude Code': detectClaude, 'Grok Build': detectGrok, CC: detectCc, OpenMinis: detectMinis };
744
- return !!map[name];
745
- }
746
- function runDoctor() {
747
- const mark = (v) => (v ? '\u2713' : '\u2717');
748
- console.log('\nagent-bypass 环境自检(--doctor,只读)');
749
- console.log('\u2500'.repeat(40));
750
- console.log(`平台 : ${process.platform} / ${process.arch}${detectMinis ? '(iSH / OpenMinis)' : ''}`);
751
- console.log(`Node : ${process.version}`);
752
- let npmV = '未安装';
753
- try { npmV = String(spawnSync('npm', ['-v'], { encoding: 'utf8', timeout: 8000 }).stdout || '').trim() || '未安装'; } catch (e) { /* ignore */ }
754
- console.log(`npm : ${npmV}`);
755
- for (const cmd of ['python3', 'pip3', 'curl', 'git', 'rg']) {
756
- const p = which(cmd);
757
- console.log(`${mark(p)} ${cmd.padEnd(8)}: ${p || '未安装'}`);
758
- }
759
- const pm = [['brew', 'brew'], ['apk', 'apk'], ['apt', 'apt'], ['dnf', 'dnf'], ['pacman', 'pacman'], ['choco', 'choco'], ['winget', 'winget']]
760
- .filter(([, c]) => which(c)).map(([n]) => n);
761
- console.log(`包管理器 : ${pm.length ? pm.join(' / ') : '未检测到'}`);
762
- const dnsIp = systemDnsIpv4('example.com');
763
- let dnsHint = null;
764
- if (!dnsIp) {
765
- console.log('\u00b7 DNS : 解析探测失败(离线/无 DNS)');
766
- } else if (isFakeIp(dnsIp)) {
767
- console.log(`\u26a0 DNS : example.com \u2192 ${dnsIp}(fake-IP/TUN 劫持,扫描/溯源先走 DoH)`);
768
- dnsHint = 'fake-IP 环境:sh scripts/doh_resolve.sh <域名> 或 python3 scripts/netdns.py <域名> --doh 拿真 IP 后再扫;细节见 references/fake-ip-tun.md';
769
- } else {
770
- console.log(`\u2713 DNS : example.com \u2192 ${dnsIp}`);
771
- }
772
-
773
- const labs = ['Pi', 'OpenCode', 'DeepSeek Harness', 'Claude Code', 'Grok Build', 'OpenMinis'];
774
- const det = labs.filter(harnessDetected);
775
- console.log(`检测 harness: ${det.length ? det.join(' / ') : '无'}`);
776
- for (const [label, dir] of harnessSkillDirs()) {
777
- if (!det.includes(label) && !exists(dir)) continue;
778
- const v = manifestVersion(dir);
779
- console.log(`${mark(v)} ${label} 技能: ${dir}${v ? `(v${v})` : '(未安装)'}`);
780
- }
781
-
782
- if (detectDsh) {
783
- const { dir, name } = dshProfileDir();
784
- const patch = path.join(dir, 'cordis.patch.yml');
785
- const injected = exists(patch) && fs.readFileSync(patch, 'utf8').includes(DSH_MARK_B);
786
- console.log(`${mark(injected)} DSH profile「${name}」Ck 模式: ${injected ? '已注入' : '未注入(npx agent-bypass --dsh)'}`);
787
- console.log(` DSH 安装目录: ${dshAppInstalled() ? '已探测到' : '未探测到(可设 DSH_APP_PATH / DSH_ASAR_PATH)'}`);
788
- if (process.platform === 'darwin') console.log(' 启动: open -a "DeepSeek Harness"');
789
- else if (process.platform === 'win32') console.log(' 启动: 开始菜单搜索 DeepSeek Harness');
790
- }
791
-
792
- const hints = [];
793
- if (dnsHint) hints.push(dnsHint);
794
- if (!which('rg')) {
795
- if (process.platform === 'darwin') hints.push('brew install ripgrep');
796
- else if (process.platform === 'win32') hints.push('winget install BurntSushi.ripgrep.MSVC(或 choco install ripgrep)');
797
- else if (detectMinis) hints.push('apk add ripgrep');
798
- else hints.push('apt install ripgrep(或 dnf/pacman 对应包)');
799
- }
800
- if (!which('python3')) hints.push(detectMinis ? 'apk add python3 py3-pip' : process.platform === 'darwin' ? 'xcode-select --install 或 brew install python' : '安装 python3');
801
- if (!which('git')) hints.push(detectMinis ? 'apk add git' : '安装 git');
802
- if (detectMinis) hints.push('iSH 首次: apk update && apk add --no-cache nodejs npm bash ripgrep python3 py3-pip curl git; 之后 npx agent-bypass --minis');
803
- if (process.platform === 'darwin' && !which('brew')) hints.push('推荐 Homebrew: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"');
804
- if (process.platform === 'darwin' && !which('python3') && !which('brew')) hints.push('macOS 也可先装 Xcode Command Line Tools 获得 python3/git');
805
- if (hints.length) { console.log('\n建议:'); for (const h of hints) console.log(` \u00b7 ${h}`); } else console.log('\n环境完备,无需处理。');
806
- }
807
-
808
496
  // ============ 主流程 ============
809
497
  console.log('\nagent-bypass installer' + (uninstall ? '(卸载模式)' : ''));
810
498
  console.log('\u2500'.repeat(40));
811
499
 
812
500
  const detectPi = exists(path.join(HOME, '.pi'));
813
501
  const detectOc = exists(path.join(HOME, '.config', 'opencode'));
814
- const detectDsh = exists(DSH_HOME_DIR) || dshAppInstalled();
815
502
  const detectClaude = exists(path.join(HOME, '.claude'));
816
503
  const detectGrok = exists(path.join(HOME, '.grok'));
817
504
  const detectCc = exists(path.join(HOME, '.cc-switch'));
818
505
  const detectMinis = exists('/var/minis');
819
506
 
820
- if (has('--doctor')) { runDoctor(); process.exit(0); }
821
-
822
507
  let targets;
823
508
  if (only.length) {
824
509
  targets = only.map((f) => f.slice(2));
825
510
  } else {
826
- // 默认装检测到的 Pi + OpenCode + DeepSeek Harness;其余 harness 一律显式指定
511
+ // 默认只装 Pi + OpenCode;其余 harness 一律显式指定(--claude / --grok / --minis / --ccswitch)
827
512
  targets = [];
828
513
  if (detectPi) targets.push('pi');
829
514
  if (detectOc) targets.push('opencode');
830
- if (detectDsh) targets.push('dsh');
831
- if (detectMinis) targets.push('minis');
832
515
  if (!targets.length) {
833
- warn('未检测到默认目标(Pi / OpenCode / DeepSeek Harness / OpenMinis):');
516
+ warn('未检测到默认目标(Pi / OpenCode):');
834
517
  info('Pi: ~/.pi 不存在');
835
518
  info('OpenCode: ~/.config/opencode 不存在');
836
- info('DeepSeek Harness: ~/.dsh 不存在,且未探测到安装目录(macOS /Applications、Windows %LOCALAPPDATA%\\Programs)');
837
- info('OpenMinis/iSH: /var/minis 不存在');
838
- info('其他 harness 需显式指定: npx agent-bypass --claude | --grok | --ccswitch');
519
+ info('其他 harness 需显式指定: npx agent-bypass --claude | --grok | --minis | --ccswitch');
839
520
  process.exit(1);
840
521
  }
841
522
  console.log(`检测到: ${targets.join(' / ')}`);
@@ -844,7 +525,6 @@ if (only.length) {
844
525
  const map = {
845
526
  pi: [installPi, uninstallPi],
846
527
  opencode: [installOpenCode, uninstallOpenCode],
847
- dsh: [installDsh, uninstallDsh],
848
528
  claude: [installClaude, uninstallClaude],
849
529
  grok: [installGrok, uninstallGrok],
850
530
  ccswitch: [installCcswitch, uninstallCcswitch],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-bypass",
3
- "version": "2.20.0",
4
- "description": "Cknb 全能技术操作员 — Agent Skills 技能包(默认安装 Pi / OpenCode / DeepSeek Harness;Claude Code / Grok / OpenMinis 显式指定)",
3
+ "version": "2.20.1",
4
+ "description": "Cknb 全能技术操作员 — Agent Skills 技能包(默认安装 Pi / OpenCode;Claude Code / Grok / OpenMinis 显式指定)",
5
5
  "bin": {
6
6
  "agent-bypass": "bin/install.js"
7
7
  },
@@ -15,7 +15,6 @@
15
15
  "opencode/",
16
16
  "claude/",
17
17
  "grok/",
18
- "dsh/",
19
18
  "references/",
20
19
  "scripts/*.py",
21
20
  "scripts/*.sh",
@@ -33,9 +32,7 @@
33
32
  "grok",
34
33
  "openminis",
35
34
  "security",
36
- "pentest",
37
- "deepseek-harness",
38
- "dsh"
35
+ "pentest"
39
36
  ],
40
37
  "scripts": {
41
38
  "prepack": "node -e \"const fs=require('fs');for(const d of ['scripts/__pycache__','tests/__pycache__']){try{fs.rmSync(d,{recursive:true,force:true})}catch(e){}}\""