{"_id":"@dshworks/dsh-ego-browser","_rev":"5-eeea1f1ceb3ed89ffdcea54d979130a1","name":"@dshworks/dsh-ego-browser","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.0":{"name":"@dshworks/dsh-ego-browser","version":"0.1.0","keywords":["deepseek","deepseek-harness","dsh","dsh-plugin","ego","ego-lite","ego-browser","browser-automation","site-skills","agent-memory"],"license":"MIT","_id":"@dshworks/dsh-ego-browser@0.1.0","maintainers":[{"name":"lroolle","email":"reason-source6s@icloud.com"}],"homepage":"https://github.com/dshworks/dsh-ego-browser#readme","bugs":{"url":"https://github.com/dshworks/dsh-ego-browser/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"98c20b6549d4f4e6f1f36c3b60612318d7369a3c","tarball":"https://registry.npmjs.org/@dshworks/dsh-ego-browser/-/dsh-ego-browser-0.1.0.tgz","fileCount":13,"integrity":"sha512-hVGVAO8zCubemAZtDgtJ4oMGaYjYfiv2Ba1QxsUHgbnQ3xm4Bsd/dB6IUARL8FQZr+PjS4yIK4yedSTpbfQX4g==","signatures":[{"sig":"MEQCIBhvXe7O1LlYkAofku39aRHi1Nvi41krTcJ0FBVGUSLZAiBnIqRQ3S/8xabhcwMKRFCrjd/FyyN6ogdrLRswollP6A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":121665},"main":"lib/index.js","type":"module","engines":{"node":">=20"},"exports":{".":"./lib/index.js","./package.json":"./package.json"},"gitHead":"9cb195a19938b00976e64291a006eee3c3077756","scripts":{"test":"vitest run","typecheck":"echo 'no types to check'"},"_npmUser":{"name":"lroolle","email":"reason-source6s@icloud.com"},"repository":{"url":"git+https://github.com/dshworks/dsh-ego-browser.git","type":"git"},"_npmVersion":"10.9.8","description":"ego lite for DeepSeek Harness, with a memory it keeps: the agent recalls what it learned about a site before it acts, promotes a script that worked into a reusable site tool, and hands you the keyboard through a real dsh prompt when a page needs a human.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@deepseek-ai/schemastery":"^3.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.0-rc.6","@deepseek-ai/dsh-subprocess":"^0.1.0-rc.6"},"_npmOperationalInternal":{"tmp":"tmp/dsh-ego-browser_0.1.0_1787579902182_0.4105721938008755","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@dshworks/dsh-ego-browser","version":"0.1.1","keywords":["deepseek","deepseek-harness","dsh","dsh-plugin","ego","ego-lite","ego-browser","browser-automation","site-skills","agent-memory"],"license":"MIT","_id":"@dshworks/dsh-ego-browser@0.1.1","maintainers":[{"name":"lroolle","email":"reason-source6s@icloud.com"}],"homepage":"https://github.com/dshworks/dsh-ego-browser#readme","bugs":{"url":"https://github.com/dshworks/dsh-ego-browser/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"39c053609c2b93d3b139ae015ab365c8e9d96e23","tarball":"https://registry.npmjs.org/@dshworks/dsh-ego-browser/-/dsh-ego-browser-0.1.1.tgz","fileCount":13,"integrity":"sha512-KESipjGiP+vdr2pIUUlcse1rViVQjLka69S+KSKloaFj5H6m2efWHo7Y/tNoM3L8nj/EZKUMZVgFGDW5yrFZXw==","signatures":[{"sig":"MEQCIFpuoID6c5TT2Lbvm2prb/cIJLGU+li/f2q+p+7DmGK8AiAjwWrCl9ZMegRIu1WjKanWcJ8STegRkyPUjluvjwF9Gg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":122224},"main":"lib/index.js","type":"module","engines":{"node":">=20"},"exports":{".":"./lib/index.js","./package.json":"./package.json"},"gitHead":"bbe24e8e5561285584e7c771e9773efd2ffa44f7","scripts":{"test":"vitest run","typecheck":"echo 'no types to check'"},"_npmUser":{"name":"lroolle","email":"reason-source6s@icloud.com"},"repository":{"url":"git+https://github.com/dshworks/dsh-ego-browser.git","type":"git"},"_npmVersion":"10.9.8","description":"ego lite for DeepSeek Harness, with a memory it keeps: the agent recalls what it learned about a site before it acts, promotes a script that worked into a reusable site tool, and hands you the keyboard through a real dsh prompt when a page needs a human.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@deepseek-ai/schemastery":"^3.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-rc.1","@deepseek-ai/dsh-subprocess":"^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-rc.1"},"_npmOperationalInternal":{"tmp":"tmp/dsh-ego-browser_0.1.1_1788501367293_0.2395063990499411","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@dshworks/dsh-ego-browser","version":"0.1.2","keywords":["deepseek","deepseek-harness","dsh","dsh-plugin","ego","ego-lite","ego-browser","browser-automation","site-skills","agent-memory"],"license":"MIT","_id":"@dshworks/dsh-ego-browser@0.1.2","maintainers":[{"name":"lroolle","email":"reason-source6s@icloud.com"}],"homepage":"https://github.com/dshworks/dsh-ego-browser#readme","bugs":{"url":"https://github.com/dshworks/dsh-ego-browser/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"925a04e7511a7bd918020ccd31383cf3ee41da7a","tarball":"https://registry.npmjs.org/@dshworks/dsh-ego-browser/-/dsh-ego-browser-0.1.2.tgz","fileCount":13,"integrity":"sha512-QFL9K+o3erfnSEwx9DUB79SRW0nVQL5pURP652v4e7lsFg4l9XUtdsgwnc/78jorbtzsSLaD/X43fpV1Juf9oQ==","signatures":[{"sig":"MEQCIBk3Gigl5oU9fLxUlLh3njFfe7YU19dd70LWJMTA5BXsAiA3g24Xt7DFh6S4oFu//rTuOo9Vk7YHt6kBg6JjuNtMtQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIHkrXFa22QPvqdVVxUOIHm/XvjEKvggaXxHVn0m2MdTVAiEAy/whas/N0tXpgkP9ZSehLh2PFvmUKLcmi3jgq0omhB4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":122254},"main":"lib/index.js","type":"module","engines":{"node":">=20"},"exports":{".":"./lib/index.js","./package.json":"./package.json"},"gitHead":"a51f05e1f78959a3405150c65c0570d988287406","scripts":{"test":"vitest run","typecheck":"echo 'no types to check'"},"_npmUser":{"name":"lroolle","email":"reason-source6s@icloud.com"},"repository":{"url":"git+https://github.com/dshworks/dsh-ego-browser.git","type":"git"},"_npmVersion":"10.9.8","description":"ego lite for DeepSeek Harness, with a memory it keeps: the agent recalls what it learned about a site before it acts, promotes a script that worked into a reusable site tool, and hands you the keyboard through a real dsh prompt when a page needs a human.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@deepseek-ai/schemastery":"^3.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-rc.1 || ^0.1.5-rc.1","@deepseek-ai/dsh-subprocess":"^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-rc.1 || ^0.1.5-rc.1"},"_npmOperationalInternal":{"tmp":"tmp/dsh-ego-browser_0.1.2_1789707873164_0.09848718918597221","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@dshworks/dsh-ego-browser","version":"0.1.3","keywords":["deepseek","deepseek-harness","dsh","dsh-plugin","ego","ego-lite","ego-browser","browser-automation","site-skills","agent-memory"],"license":"MIT","_id":"@dshworks/dsh-ego-browser@0.1.3","maintainers":[{"name":"lroolle","email":"reason-source6s@icloud.com"}],"homepage":"https://github.com/dshworks/dsh-ego-browser#readme","bugs":{"url":"https://github.com/dshworks/dsh-ego-browser/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"4900c400acd625c71da53971fcdb9a9a89589267","tarball":"https://registry.npmjs.org/@dshworks/dsh-ego-browser/-/dsh-ego-browser-0.1.3.tgz","fileCount":13,"integrity":"sha512-AY+mdk4iK8h5Aqyg6fyqLNe5cJ/oHzSoel7WS1eKFvC/pxEYhWY9KYTrC/4ev+y7NWkCO+XZeq0b1GAN+bXjNA==","signatures":[{"sig":"MEUCIQCBaToxPT1+VOJwS1HVX4LjgMKwU0yxxOo+EIm+ezkkYAIgUyP0WhixC8JvzTHTJouvkn9ZZ9cpsaWvgVS4bNNXB3U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIEKiz5dYNvYB2gN6ubjmP68rx7TTsEUQHnhHDChzNufmAiEAv9S/6O3TvmBj+NcQj4moRmWwy0ZDBCmLAVbUmpo9kgY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":127609},"main":"lib/index.js","type":"module","engines":{"node":">=20"},"exports":{".":"./lib/index.js","./package.json":"./package.json"},"scripts":{"test":"vitest run","typecheck":"echo 'no types to check'"},"_npmUser":{"name":"lroolle","email":"reason-source6s@icloud.com"},"repository":{"url":"git+https://github.com/dshworks/dsh-ego-browser.git","type":"git"},"_npmVersion":"10.9.8","description":"ego lite for DeepSeek Harness, with a memory it keeps: the agent recalls what it learned about a site before it acts, promotes a script that worked into a reusable site tool, and hands you the keyboard through a real dsh prompt when a page needs a human.","directories":{},"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","@deepseek-ai/dsh-tools":"0.1.7-rc.2","@deepseek-ai/schemastery":"~3.18.4","@deepseek-ai/dsh-subprocess":"0.1.7-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-rc.1 || ^0.1.5-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1","@deepseek-ai/schemastery":"^3.18.1","@deepseek-ai/dsh-subprocess":"^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-rc.1 || ^0.1.5-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1"},"_npmOperationalInternal":{"tmp":"tmp/dsh-ego-browser_0.1.3_1790669889874_0.9509580631352934","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"_id":"@dshworks/dsh-ego-browser@0.1.4","dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"bugs":{"url":"https://github.com/dshworks/dsh-ego-browser/issues"},"dist":{"shasum":"1dac8eb4a6eb2c54ef54a53b6069642bed252002","tarball":"https://registry.npmjs.org/@dshworks/dsh-ego-browser/-/dsh-ego-browser-0.1.4.tgz","fileCount":13,"integrity":"sha512-kZf9nwdRqChn4s9Ep4iTMt4p3l09apoGg8t8LGuCHYlb3AFmdY6fjxte6ZXYaaCkmifQeMZkXoWBbm1+WSMd4w==","signatures":[{"sig":"MEUCIQDnRrh8IuhQwiBd7A+c14kfkVXhj9VtjDzWB/yVfvFqyQIgFaw2z9UpbaPU7KmcVdmhol9K35/mCFtK/dVBTCtPKdU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDgVwDmElvViFmWouFa4hcbGR/eRiywiFKBr+jJO+03WAIgSrf3XbTrBPteLmZiVPE3R/bF7P+QiS/2qQiRjIlRuIc="}],"unpackedSize":128490},"main":"lib/index.js","name":"@dshworks/dsh-ego-browser","type":"module","engines":{"node":">=20"},"exports":{".":"./lib/index.js","./package.json":"./package.json"},"gitHead":"10c9fd08050aa0e79c795f53eda78598e5ec79a3","license":"MIT","scripts":{"test":"vitest run","typecheck":"echo 'no types to check'"},"version":"0.1.4","_npmUser":{"name":"lroolle","email":"reason-source6s@icloud.com"},"homepage":"https://github.com/dshworks/dsh-ego-browser#readme","keywords":["deepseek","deepseek-harness","dsh","dsh-plugin","ego","ego-lite","ego-browser","browser-automation","site-skills","agent-memory"],"repository":{"url":"git+https://github.com/dshworks/dsh-ego-browser.git","type":"git"},"_npmVersion":"10.9.8","description":"ego lite for DeepSeek Harness, with a memory it keeps: the agent recalls what it learned about a site before it acts, promotes a script that worked into a reusable site tool, and hands you the keyboard through a real dsh prompt when a page needs a human.","directories":{},"maintainers":[{"name":"lroolle","email":"reason-source6s@icloud.com"}],"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","@deepseek-ai/dsh-tools":"0.1.7-rc.2","@deepseek-ai/schemastery":"~3.18.4","@deepseek-ai/dsh-subprocess":"0.1.7-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-rc.1 || ^0.1.5-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1","@deepseek-ai/schemastery":"^3.18.1","@deepseek-ai/dsh-subprocess":"^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-rc.1 || ^0.1.5-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-ego-browser_0.1.4_1790759071422_0.8034604463370674"}}},"time":{"created":"2026-08-24T13:58:21.989Z","modified":"2026-09-30T09:04:31.668Z","0.1.0":"2026-08-24T13:58:22.389Z","0.1.1":"2026-09-04T05:56:07.436Z","0.1.2":"2026-09-18T05:04:33.248Z","0.1.3":"2026-09-29T08:18:09.956Z","0.1.4":"2026-09-30T09:04:31.503Z"},"bugs":{"url":"https://github.com/dshworks/dsh-ego-browser/issues"},"license":"MIT","homepage":"https://github.com/dshworks/dsh-ego-browser#readme","keywords":["deepseek","deepseek-harness","dsh","dsh-plugin","ego","ego-lite","ego-browser","browser-automation","site-skills","agent-memory"],"repository":{"url":"git+https://github.com/dshworks/dsh-ego-browser.git","type":"git"},"description":"ego lite for DeepSeek Harness, with a memory it keeps: the agent recalls what it learned about a site before it acts, promotes a script that worked into a reusable site tool, and hands you the keyboard through a real dsh prompt when a page needs a human.","maintainers":[{"name":"lroolle","email":"reason-source6s@icloud.com"}],"readme":"<div align=\"center\">\n\n```\n    ___  __ _  ___\n   / _ \\/ _` |/ _ \\    dsh-ego-browser\n  |  __/ (_| | (_) |\n   \\___|\\__, |\\___/    ego lite for DeepSeek Harness,\n        |___/          with a memory it keeps\n```\n\n**给 dsh 浏览器 agent 的站点技能记忆。**\n\n</div>\n\n<p align=\"center\"><strong>\n7 个工具 · 用 ego lite 自己的 <code>learnings/</code> 格式存 · 在 dsh 0.1.7-rc.2 上验证过 · 81 个测试，不需要浏览器 · 纯 host 插件 · MIT\n</strong></p>\n\n<p align=\"center\">\n<a href=\"https://github.com/dshworks/dsh-ego-browser/actions/workflows/ci.yml\"><img src=\"https://github.com/dshworks/dsh-ego-browser/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n<a href=\"https://www.npmjs.com/package/@dshworks/dsh-ego-browser\"><img src=\"https://img.shields.io/npm/v/@dshworks/dsh-ego-browser?color=CB3837&logo=npm&logoColor=white\" alt=\"npm\"></a>\n<a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-3DA639\" alt=\"MIT\"></a>\n<img src=\"https://img.shields.io/badge/node-%E2%89%A520-5FA04E\" alt=\"Node >= 20\">\n<img src=\"https://img.shields.io/badge/dsh-0.1.7--rc.2%20verified-1E90FF\" alt=\"verified against dsh 0.1.7-rc.2\">\n</p>\n\n<p align=\"center\">\n<a href=\"#它做什么\">它做什么</a> ·\n<a href=\"#上手60-秒\">60 秒上手</a> ·\n<a href=\"#凭据\">凭据</a> ·\n<a href=\"#什么时候用什么时候别用\">什么时候别用</a> ·\n<a href=\"#相关工作\">相关工作</a> ·\n<a href=\"llms.txt\">llms.txt</a> ·\n<a href=\"README.md\">English</a>\n</p>\n\n---\n\nego lite 是一个人和 agent 共用的浏览器：agent 在自己的 Space 里干活，复用你真实的登录态，你的标签页还是你的。这个插件把它接进 dsh —— 并补上 ego 自己 README 里仍标着「即将推出」的那一半。\n\n> *「Experience accumulation that makes your agent faster the more you use it **(coming soon)**」* —— [ego lite README](https://github.com/citrolabs/ego-lite)\n\n读的那半边其实已经发布了：`site.learnContext`、`site.runTool`、`site.runBrowserTool` 会从 `EGO_BROWSER_AGENT_WORKSPACE` 指向的目录里加载 `learnings/`。缺的是**写**的那半边。\n\n```\n  ego_recall  ──▶  ego_run  ──▶  ego_learn  ──▶  ego_site_run\n   这个 agent      一次浏览器      把跑通的那       下次一次调用，\n   已经学到的      任务写一段      一步固化         而不是重新摸\n   关于该站点      脚本                             一遍页面\n   的东西\n                        │\n                        └──▶  ego_handoff —— 页面需要真人时，\n                              真的去问，然后再把控制权拿回来\n```\n\n闭环就成立了。第二次抓同一个后台时，agent 调的是它上周自己写的工具，而不是重新摸一遍页面。\n\n## 它做什么\n\n- **动手前先回忆** —— `ego_recall` 直接从磁盘返回某个 hostname 的笔记与工具签名。不开浏览器、不加载页面、不花 token 重新摸索上个月已经跑通过的东西。\n- **一次任务一段脚本** —— `ego_run` 把整个浏览器任务交给 ego 运行时的一段脚本，这正是 ego 自己 benchmark 所依据的设计。\n- **把跑通的固化下来** —— `ego_learn` 把有效的一步变成真正的站点工具，用 ego 的格式存，并拒收那些活不到明天的。\n- **调用学过的东西** —— `ego_site_run` 按名字调用已存工具并计数，于是没人用的工具一眼可见。\n- **真的把键盘交给你** —— `ego_handoff` 弹出真正的 dsh **Continue / Finish task** 提示 —— 这正是 ego 自己的 hard-stop 文案在向 harness 要的东西 —— 你说继续，它才把控制权拿回来。\n- **告诉模型你装的是哪一代 ego** —— `ego_doctor` 探测已安装的命令，而不是相信文档，因为同一个命令名后面有两套互不兼容的运行时。\n- **一开始就不是空的** —— 首次启动时，store 会继承你机器上已有 ego skill 的 `learnings/`。\n\n## 它怎么工作（30 秒）\n\n```\n  dsh agent\n     │  ego_run / ego_site_run                    ego_recall / ego_learn\n     ▼                                                      │\n  ┌──────────────────────────────┐                          ▼\n  │ dsh-ego-browser（host 半边） │              ┌──────────────────────────┐\n  │  · argv 与 helper 表面探针   │              │ learnings/<site>/        │\n  │  · 脚本包装与结果归类        │─────────────▶│   manifest.json          │\n  │  · 晋升闸                    │    写入      │   notes/*.md             │\n  └──────────────┬───────────────┘              │   tools/*.js             │\n                 │ stdin heredoc                │   browser-tools/*.js     │\n                 ▼                              └──────────┬───────────────┘\n          `ego-browser`                                    │ EGO_BROWSER_\n                 │                                         │ AGENT_WORKSPACE\n                 ▼                                         ▼\n          ego lite 应用  ◀────────── 同一份 store，ego 自己也读得回去\n          （你的登录态，它自己的 Space）\n```\n\n唯一的那根线就是 ego lite 应用装的 `ego-browser` 命令。这里不内嵌、不打补丁、也不启动任何浏览器。\n\n## 上手（60 秒）\n\n需要运行 dsh 的机器上已安装并完成 ego lite 引导（[lite.ego.app](https://lite.ego.app/)），使 `ego-browser` 在 PATH 上。\n\n```sh\n# 1. 安装\ndsh plugin --profile web add -w @dshworks/dsh-ego-browser\n\n# 2. 重启 dsh\n\n# 3. 确认装上了 —— 七个名字；如果是 [] 就是没装上\ncurl -s localhost:8090/dsh-ego-browser/memory | jq .tools\n```\n\n在 [deva](https://github.com/thevibeworks/deva) 容器里经 ego bridge 跑 dsh？dsh 会从它启动的每个进程的环境里剥掉所有像凭据的变量（`KEY`、`SECRET`、`TOKEN`、`PASSWORD`），所以 bridge 的 token 得在 profile 的 `cordis.patch.yml` 里显式转发：\n\n```yaml\n- id: dsh-ego-browser\n  config:\n    env:\n      DEVA_EGO_TOKEN: !!js process.env.DEVA_EGO_TOKEN\n```\n\n`add` 会顺手把 bundle 登记进 profile 花名册。然后让 agent 先跑一次 `ego_doctor` —— 它就是这样弄清楚该给你装的这一代 ego 写 `cliLog()` 还是 `console.log()` 的：\n\n```\ncommand: ego-browser   invoked as: ego-browser <<'JS'\nego runtime surface: facades (console.log / page / browser / taskSpaces); 7 helper names visible.\nstore: ~/.dsh/ego-browser/workspace (3 sites)\n  github — github.com, *.github.com — 3 tool(s): search_repos (0x), get_open_issues (0x), get_repo_stats (0x)\n  google — google.com, *.google.com, www.google.com — 2 tool(s): search_and_extract (0x), get_autocomplete_suggestions (0x)\n  x-com — x.com, *.x.com, twitter.com, *.twitter.com — 3 tool(s): get_timeline_posts (0x), search_users (0x), post_from_active_element (0x)\n```\n\n*agent 还没浏览任何东西，就已经有三个站点、八个工具 —— 这是 store 把 ego 自带的东西继承了过来。*\n\n## 凭据\n\n**在真实 dsh 上跑过**（0.1.7-rc.2，并在 0.2.0-rc.1 上再跑一遍：打包、用 `dsh plugin add` 装进全新 profile、启动）：\n\n| 声称 | 怎么验的 |\n|---|---|\n| 走 dsh 自己的插件安装路径装得上 | 用 `dsh plugin add` 装入打包好的插件返回 0，即 dsh 的兼容性闸门放行；profile 里没有任何自带的 `@deepseek-ai/*` 包去遮蔽 host 的 harness。`scripts/check-dsh-release.mjs` 在每个 pull request 和每天都重跑这一遍 |\n| 七个工具全部注册 | `GET /dsh-ego-browser/memory` 会列出它们；tools 服务没到位时是 `[]` |\n| 调用经 host 真的到达 ego | 一轮 headless 对话经 dsh 的工具管线和 subprocess 接缝调用了 `ego_doctor`、`ego_recall`、`ego_run`。Mac 上的 ego lite 0.5.1.13 经 deva bridge 从 Linux 容器里被调到，答复：`nodejs` argv、扁平全局量、`ego runtime v24.18.1` |\n| store 会自动继承 | 启动后带着 `google`（2 个工具）和 `x-com`（3 个），来自 ego 自带的 `skills/ego-browser/learnings/` |\n| 我们的校验器与 ego 的格式一致 | 对 ego 自带站点报出**零问题** —— 这个方向的检查才有意义 |\n| 路由有围栏 | loopback 返回 200，`Host` 指向别处返回 **403** |\n\n**对着真实构建出的 `ego-browser` bundle** 和真实 subprocess 接缝：\n\n| 声称 | 怎么验的 |\n|---|---|\n| argv 探针能找到可用形状 | 在当前 CLI 上选中裸调用，在旧版上选中 `nodejs`；两种都失败时把两次输出都报出来 |\n| 表面探针准确 | 对着真实 bundle 返回 `facade` 与 `page, browser, taskSpaces, site, fetch, cdp, help` —— 与其源码完全一致 |\n| 出错也不丢输出 | 抛错不会吞掉抛错前打印的内容；顶层 `return` 依然产出判定 |\n| 用户接管被识别为接管 | 而不是「结果丢了」—— 见[一个命令名，两套运行时](#一个命令名两套运行时) |\n| 晋升闸拦得住 | 快照 ref、错误 schema、缺失导出、无法解析的源码全部拒收，且不写入任何字节 |\n\n```sh\nnpm install && npm test    # 81 个测试，不需要浏览器，约 2 秒\n```\n\n`fixtures/` 里的 CLI 替身是从 ego 自己的源码逐条转写的 —— argv 处理来自 `src/run.ts`，输出 sink 来自 `src/output-sink.ts`，helper 表面来自 `src/helpers.ts` —— 每个文件头都写明了它跟的是上游哪个文件，因为比生产环境更弱的替身什么都测不出来。\n\n**没有验证的**：所有要碰页面的路径 —— 真的加载页面、真的任务空间、真的用户接管。ego lite 是 macOS 应用，而这份代码写在 Linux 容器里。通向它的那根线对着真实 CLI bundle 端到端跑过，也经 deva bridge 对着真实安装的 ego 跑过，但只跑了不打开任何页面的脚本；线那头的东西没有。请先在真机上跑 `ego_doctor`，若与本页所写不符，请带上它的输出[开 issue](https://github.com/dshworks/dsh-ego-browser/issues/new/choose)。\n\n## 让这份记忆值钱的那道闸\n\n`ego_learn` 会拒绝含快照 ref 的代码：\n\n```\nthis is not storable yet:\n  - code contains a snapshot ref (@21 / ref=21). Those are rebuilt on every\n    snapshotText() call and mean nothing on the next run — re-express the step\n    with a stable locator (a CSS selector, or the loc=... value from the\n    snapshot) before promoting it.\n```\n\n这就是「记忆」和「一堆死选择器」的全部差别。刚跑通的脚本里**满是** `@21`，因为五秒前 agent 就是这么找到元素的。原样存下来等于什么都没存。这条规则是 ego 自己的 —— 它的校验器拒绝同一个模式 —— 在写入时就执行它，才能把「跑通过一次」变成「还能再跑」。\n\n## 一个命令名，两套运行时\n\n值得明说，因为任何人写 ego 集成都会碰上。\n\n**argv 形状不稳定。** 已发布的 skill 写的是 `ego-browser nodejs <<'EOF'`；`citrolabs/ego-lite@main` 里的 CLI **完全不接受 argv**，多一个 `nodejs` 就打印用法并 **exit 2**；社区 Linux 移植则把 `nodejs` 当成空前缀吞掉。一个命令名，三种行为。\n\n**helper 表面同样不稳定。** 一代装的是扁平全局量 —— `cliLog`、`snapshotText`、`useOrCreateTaskSpace`；另一代装的是 Playwright 风格的 facade —— `page`、`browser`、`taskSpaces`、`site`，并且用 `console.log` 取代了 `cliLog`。为其中一代写的脚本在另一代上直接 `ReferenceError`，而且靠文档解决不了：两份文档在各自的世界里都是对的。哪怕在 ego 自己仓库的 HEAD 上，`SKILL.md` 和 `references/install.md` 也互相矛盾。\n\n**输出走哪条流也不稳定。** ego 的运行时把脚本输出刷到 stdout；经 deva bridge 调到的 ego 0.5.1.13 却把每个字节都放在 stderr，连 `--version` 也是。插件从带着脚本所打印标记的那条流读取每次运行，stdout 优先。\n\n所以这个插件不假设，它**问** —— 每次启动问一次，然后把答案交给模型。\n\n**还有：输出 sink 会吃掉你的结果。** 用户把任务空间收回去时，ego 会标记 hard stop 并**丢弃脚本打印的每一行**，只留它自己的提示。任何从 stdout 里解析结果哨兵的集成，这时会什么都读不到，然后报一个「解析失败」。在这里，哨兵的**缺席本身**就是信号，这次运行会被正确归类：\n\n```\nhardStop: true —— 用户已接管该任务空间，ego 暂停了 agent。不要重试，也不要自行夺回控制权；\n去问用户，等他们说继续之后用 ego_handoff 恢复。\n```\n\n## 什么时候用，什么时候别用\n\n**适合你**，如果：你希望浏览器工作第二次做起来更便宜；你在 macOS 上装了 ego lite；你想让 agent 访问你已经登录的站点；或者你希望登录墙变成一个你能回答的提示框，而不是白白浪费一轮。\n\n**别用**，如果：\n\n- **你想看着 agent 浏览。** 这个插件没有观察窗。用 [Fisfzy/dsh-ego-browser](https://github.com/Fisfzy/dsh-ego-browser) —— 可以直接点击操作的实时观察窗，外加一份 ego 运行时的 Linux 移植，没有 macOS 应用也能跑。\n- **你不在 macOS 上。** ego lite 目前只发 macOS。同样推荐上面那个。\n- **你想要细粒度的 `click` / `fill` / `scroll` 工具。** 这是故意不做的：ego 自己的 benchmark 把速度归因于「一次任务一段脚本」，堆三十个小动词等于把这个优势花掉。如果你的模型 JavaScript 写得不好，细粒度设计更适合你。\n- **浏览器活儿你只做一次。** 记忆才是重点。没有重复，它相对原版 `ego-browser` skill 只是额外开销。\n- **你要在 CI 里无头跑。** ego lite 是带真实 profile 的桌面应用。这时该用 Playwright 类插件。\n\n## 七个工具\n\n| 工具 | 作用 |\n|---|---|\n| `ego_run` | 在 ego 运行时里跑一段脚本。传 `url` 会先把该站点已学到的东西贴上来；传 `taskSpace` 会用正确的方言先开好任务空间。 |\n| `ego_recall` | 某个 URL 的笔记与工具签名，直接读磁盘。 |\n| `ego_site_run` | 按站点和名字调用已学会的工具，并记一次调用。 |\n| `ego_learn` | 把跑通的一步固化成站点工具 —— 活不到明天的一律拒收。 |\n| `ego_forget` | 删掉一个工具或整个站点。错的记忆比没有记忆更糟。 |\n| `ego_handoff` | 交出浏览器，弹出真正的 Continue / Finish task，选 Continue 就把控制权拿回来。 |\n| `ego_doctor` | 哪个 ego、哪种 argv、哪套 helper、store 在哪、里面有什么。 |\n\n<details>\n<summary><strong>store 用的是 ego 的格式，不是我们的</strong></summary>\n\n```\n<workspace>/learnings/<site-id>/manifest.json          id、name、domains、notes、tools\n<workspace>/learnings/<site-id>/notes/*.md             agent 摸清楚的东西，用散文写\n<workspace>/learnings/<site-id>/tools/*.js             node 工具：export async function f(ctx, args)\n<workspace>/learnings/<site-id>/browser-tools/*.js     页面工具：在标签页里求值\n```\n\n这里学到的东西，在 dsh 之外的原版 `ego-browser` skill 里同样能加载，指向同一个 workspace 的其它 agent 也一样。没有私有格式，也没有需要迁出的东西。\n\n首次启动时，如果找得到已有的 ego skill workspace，会把它的 `learnings/` 继承过来一次。只继承一次；你删掉的站点不会自己回来。\n\n一切都在写入前校验，被拒的晋升不会改动 store 分毫：manifest 形状、域名模式、参数与返回 schema、声明的导出，以及源码语法 —— 用 `node --check` 在**进程外**解析，绝不 import，因为那段代码是写给浏览器运行时的，没有理由在 harness 进程里执行。\n\n随时读 store：\n\n```sh\ncurl -s localhost:8090/dsh-ego-browser/memory | jq\n```\n\n</details>\n\n<details>\n<summary><strong>配置</strong></summary>\n\n所有字段可选。\n\n| 字段 | 默认 | 含义 |\n|---|---|---|\n| `bin` | `ego-browser` | 命令。不在 PATH 上时填绝对路径。 |\n| `workspace` | `$DSH_HOME/ego-browser/workspace`(未设 `DSH_HOME` 时为 `~/.dsh`) | 学到的站点存放处。指向已有的 ego skill 目录即可共用同一份 store。 |\n| `seed` | `true` | 首次启动时继承已有 ego workspace 的 `learnings/`。 |\n| `cwd` | harness cwd | `ego-browser` 进程的工作目录。 |\n| `extraArgs` / `env` | `[]` / `{}` | 追加到每次调用。 |\n| `timeoutMs` | `120000` | 单次脚本的时限。 |\n| `probeTimeoutMs` | `20000` | 能力探针的时限。 |\n| `maxOutputBytes` | `1048576` | 保留的脚本输出；超出保留尾部。 |\n| `route` | `true` | 在 `/dsh-ego-browser/memory` 提供 store。 |\n| `trustedHosts` | `[]` | 除 loopback 外允许读该路由的 authority。 |\n\n只有 `subprocess` 是硬依赖。`tools` 和 `webServer` 存在时才接管，所以 headless profile 也能干净加载，只是没有路由。\n\n</details>\n\n<details>\n<summary><strong>handoff 的完整流程</strong></summary>\n\nego 自己的 hard-stop 文案，几乎是逐字在向 harness 要这个能力：\n\n> *「Offer the user choices like \"Continue\" or \"Finish task\" if your harness supports it」*\n\ndsh 支持。`ego_handoff` 交出任务空间，弹出一个带这两个选项的真实 dsh 提问，选 **Continue** 后把控制权拿回来，下一次 `ego_run` 直接续上 —— 不用「你回一句 continue 我再试试」，也不会在用户还在输密码时把键盘抢走。\n\n如果根本没人可问 —— headless、没有提问 UI，或者调用方是子 agent（harness 会用 `DELEGATED_CALLER` 拒绝而不是永远阻塞）—— 它会直说，而不是假装收到了答案。\n\n</details>\n\n## 相关工作\n\n已经有两位先把 ego 接进了 dsh，两个都值得一看：\n\n- **[Fisfzy/dsh-ego-browser](https://github.com/Fisfzy/dsh-ego-browser)** —— 32 个细粒度 `ego_*` 工具，外加一个可以直接点击操作的实时观察窗，并自带 ego 运行时的 Linux 移植，没有 macOS 应用也能跑。是真下了功夫的作品，对自身局限也很坦诚；如果你要的是**看着** agent 浏览，选它。本插件不与之竞争，也不提供观察窗。\n- **[Da1dr1em/dsh-ego-browser](https://github.com/Da1dr1em/dsh-ego-browser)** —— 围绕 Windows 预览宿主的三个工具：run、help、status。能跑起来的最小诚实实现。\n\n两者都没有往 learnings store 里写东西，也都没有把 ego 的 hard stop 变成真正的提示框。这个插件补的就是这块。\n\n还有东西本身：[**ego lite**](https://github.com/citrolabs/ego-lite)（[CitroLabs](https://github.com/citrolabs) 出品）才是这里的好点子 —— 人和 agent 共用一个浏览器，而不是用框架去驱动另一个。store 格式、临时 ref 规则、handoff 协议全是他们的；这个插件只是把它们填满。\n\n## 贡献 · 安全 · 许可\n\n[CONTRIBUTING.md](CONTRIBUTING.md) —— 哪些需要真实浏览器，哪些不需要。如果你手上有装了 ego lite 的 Mac，真机上的 `ego_doctor` 输出是你能提供的最有用的东西。\n\n[SECURITY.md](SECURITY.md) —— agent 操作的是你真实的登录会话。安装前值得花两分钟看看。\n\nMIT。ego lite 是独立发布的免费下载，遵循它自己的 MIT 许可；本仓库未内嵌其任何代码。与 DeepSeek、CitroLabs 均无关联。\n","readmeFilename":"README.zh.md"}