agent-purge 0.2.1 → 0.2.3

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/README.md CHANGED
@@ -1,76 +1,193 @@
1
- # agent-purge
2
-
3
- 一份系统提示词,喂给多个 coding agent。支持替换(replace)、追加(append)、清空(off)三种模式,可热切换,全程可逆。
4
-
5
- ```
6
- agent-purge web # 本地控制台 http://127.0.0.1:7788
7
- agent-purge codex # 用当前 persona 启动 codex
8
- agent-purge pi --ask "…" # 一次性提问
9
- ```
10
-
11
- ## 它做什么
12
-
13
- 每家 coding agent 读系统提示词的位置都不一样:有的认启动参数,有的认配置文件,有的只能靠插件改运行时对象。agent-purge 把这些入口统一成三件事:
14
-
15
- | 通道 | 机制 | 生效范围 |
16
- |---|---|---|
17
- | `install` | 写入该 harness 的托管配置块(Markdown / hooks / 插件) | 常驻,别人启动也生效 |
18
- | `shim` | 往 PATH 前置同名小壳,转发给 `agent-purge <h>` | 裸敲命令也接管 |
19
- | `slash` | 会话内 `/purge on\|off\|status` | 热切换,不动磁盘 |
20
-
21
- 三层都写的是同一份 `personas/<id>.md` 的正文。`--mode off` 或 Web 总开关关掉时,全部撤回到原样——不留残渣。
22
-
23
- ## 安装
24
-
25
- ```bash
26
- npm i -g agent-purge # 或 npx agent-purge web
27
- ```
28
-
29
- 要求 Node ≥ 20,零依赖。
30
-
31
- **数据独立存放**,升级不会被覆盖:默认 `~/.agent-purge/`(Windows `C:\Users\<你>\.agent-purge\`),里面是 `state.json` 和 `personas/`。想换位置就设环境变量:
32
-
33
- ```bash
34
- export AGENT_PURGE_HOME=/path/to/your/data # Windows: setx AGENT_PURGE_HOME D:\ap-data
35
- ```
36
-
37
- 旧版本(0.1.x)把数据放在包目录里,首次运行会自动搬到新家,原文件不动。
38
-
39
- ## 人设
40
-
41
- `personas/<id>.md` = frontmatter(`id` / `name` / `description` / `harness` / `model`)+ 正文。正文就是会被写进系统提示词的那一段。
42
-
43
- ```bash
44
- agent-purge ls # 列出全部 persona,标出当前匹配的
45
- agent-purge use <id> # 切换当前 persona
46
- agent-purge pi --persona <id> # 只这一轮用别的
47
- ```
48
-
49
- 首次运行会在 `personas/` 下生成 `neutral.md` 起步模板。
50
-
51
- ## 支持情况
52
-
53
- `agent-purge ls` 和 Web 控制台显示的是**运行期真值**:每个 harness 有没有装、版本、注入层(SYS / USER)、三个通道各自可用性。`matrix.json` 里是静态能力表,两者冲突时以运行期为准。
54
-
55
- 闭源桌面端(提示词在服务端或二进制里)只做原样启动,不做任何注入——`agent-purge <h>` 会明确打印原因,不会假装生效。
56
-
57
- ## 目录
58
-
59
- ```
60
- bin/ CLI 入口
61
- lib/ 状态、persona、注入、通道、检测
62
- backends/ 每个 harness 的启动参数与身份句处理
63
- web/ 控制台(server.mjs + ui.html)
64
- bench/ 注入成功率实测与裁判脚本(开发用,不参与运行)
65
- matrix.json 能力矩阵
66
- ```
67
-
68
- ## 边界
69
-
70
- - 只改提示词相关的位置,不碰二进制、不破解、不绕过任何授权。
71
- - 所有改动可逆:`agent-purge uninstall <h>` / `disarm` / `--mode off`。
72
- - 状态只存本机 `state.json`,不上传任何数据。
73
-
74
- ## License
75
-
76
- MIT
1
+ # agent-purge
2
+
3
+ [![npm](https://img.shields.io/npm/v/agent-purge)](https://www.npmjs.com/package/agent-purge)
4
+ [![downloads](https://img.shields.io/npm/dm/agent-purge)](https://www.npmjs.com/package/agent-purge)
5
+ [![stars](https://img.shields.io/github/stars/ZiChuanLan/agent-purge)](https://github.com/ZiChuanLan/agent-purge/stargazers)
6
+ [![license](https://img.shields.io/npm/l/agent-purge)](LICENSE)
7
+
8
+ 一份系统提示词,喂给多个 coding agent。支持替换(replace)、只发人设(strict)、追加(append)、清空(off)四种模式,可热切换,全程可逆。
9
+
10
+ ```
11
+ agent-purge web # 本地控制台 http://127.0.0.1:7788
12
+ agent-purge codex # 用当前 persona 启动 codex
13
+ agent-purge pi --ask "…" # 一次性提问
14
+ ```
15
+
16
+ ## 它做什么
17
+
18
+ 每家 coding agent 读系统提示词的位置都不一样:有的认启动参数,有的认配置文件,有的只能靠插件改运行时对象。agent-purge 把这些入口统一成三件事:
19
+
20
+ | 通道 | 机制 | 生效范围 |
21
+ |---|---|---|
22
+ | `install` | 写入该 harness 的托管配置块(Markdown / hooks / 插件) | 常驻,别人启动也生效 |
23
+ | `shim` | 往 PATH 前置同名小壳,转发给 `agent-purge <h>` | 裸敲命令也接管 |
24
+ | `slash` | 会话内 `/purge on\|off\|status` | 热切换,不动磁盘 |
25
+
26
+ 三层都写的是同一份 `personas/<id>.md` 的正文。`--mode off` 或 Web 总开关关掉时,全部撤回到原样——不留残渣。
27
+
28
+ ## 安装
29
+
30
+ ```bash
31
+ npm i -g agent-purge # 或 npx agent-purge web
32
+ ```
33
+
34
+ 要求 Node ≥ 20,零依赖。
35
+
36
+ **数据独立存放**,升级不会被覆盖:默认 `~/.agent-purge/`(Windows `C:\Users\<你>\.agent-purge\`),里面是 `state.json` 和 `personas/`。想换位置就设环境变量:
37
+
38
+ ```bash
39
+ export AGENT_PURGE_HOME=/path/to/your/data # Windows: setx AGENT_PURGE_HOME D:\ap-data
40
+ ```
41
+
42
+ 旧版本(0.1.x)把数据放在包目录里,首次运行会自动搬到新家,原文件不动。
43
+
44
+ ## 人设
45
+
46
+ `personas/<id>.md` = frontmatter + 正文。正文就是会被写进系统提示词的那一段。
47
+
48
+ frontmatter 用 `description` 写「说明」(Web 列表和 `agent-purge ls` 显示的就是它);旧的 `desc` 仍然认,不会报错。可选 `order`(排序)、`harness` / `model`(匹配用)。Web 里只改名字和说明时会保留 frontmatter 的其它键,不整段重写。
49
+
50
+ ```bash
51
+ agent-purge ls # 列出全部 persona,标出当前匹配的
52
+ agent-purge use <id> # 切换当前 persona
53
+ agent-purge pi --persona <id> # 只这一轮用别的
54
+ ```
55
+
56
+ 首次运行会在 `personas/` 下生成 `neutral.md` 起步模板。
57
+
58
+ ## 支持情况
59
+
60
+ 每个数字都是实测值:本地假 provider 抓真实请求体,不是估算。
61
+
62
+ | harness | 机制 | 实测版本 | 默认 system | 注入后 |
63
+ |---|---|---|---|---|
64
+ | `codex` | 启动参数 `-c model_instructions_file=` | 0.163.0 | 21,026 | 24 |
65
+ | `claude` | `--system-prompt-file` + 二进制补丁清残留身份句 | 2.1.304 | 6,379 | 156 |
66
+ | `grok` | `--system-prompt-override` | 1.0.62 | 5,146 | 21 |
67
+ | `omp` | `--system-prompt` | 17.4.2 | 34,511 | 10,106 |
68
+ | `hermes` | 临时 HOME 里替换 `SOUL.md` | 0.21.5 | 8,139 | 7,554 |
69
+ | `zcode` | UserPromptSubmit hook(user 角色)+ `customSystemPrompt` | 0.16.9 | 9,359 | 9,359 |
70
+ | `opencode` | cwd 下 `.opencode/plugin/*.ts` 原地改 `output.system` | 1.19.3 | 19,332 | 112 |
71
+ | `opencode2` | `plugins/agent-purge-v2.ts` 的 `ctx.session.hook("context")` | 0.0.0-beta-17823 | 8,279 | 3,189 |
72
+ | `dsh` | cordis 插件(三个 profile 各一份) | 0.2.1-rc.2 | 5,713 | 68 |
73
+ | `pi` | 原生扩展,会话内 `/purge` | — | — | — |
74
+ | `antigravity` | 等长替换二进制里的身份句 | 1.23.x | ≈20,498 | — |
75
+ | `codebuddy` | `--system-prompt-file` | 2.171.0 | — | — |
76
+ | `qoder` / `workbuddy` | 不支持(提示词在服务端) | — | — | — |
77
+
78
+ `opencode` 和 `opencode2` 是两个不同的 npm 包(`opencode-ai` 1.x 与 `@opencode/cli` 2.x),插件接口完全不同,各自独立支持。
79
+
80
+ `agent-purge ls` 和 Web 控制台显示的是**运行期真值**:每个 harness 有没有装、版本、注入层(SYS / USER)、三个通道各自可用性。`matrix.json` 里是静态能力表,两者冲突时以运行期为准。
81
+
82
+ 闭源桌面端(提示词在服务端或二进制里)只做原样启动,不做任何注入——`agent-purge <h>` 会明确打印原因,不会假装生效。
83
+
84
+ ### dsh(DeepSeek Harness)
85
+
86
+ desktop / web / headless 三个形态共用一套插件:往每个 profile 的 `node_modules/agent-purge/` 放一个 cordis 插件,在 `cordis.patch.yml` 里用 `- insert` 挂上。**不改 `app.asar`,不碰安装目录,不依赖任何第三方插件。**
87
+
88
+ ```bash
89
+ agent-purge install dsh # 写插件 + 挂载(三个 profile 一起)
90
+ agent-purge dsh # 按当前 persona 启动桌面版
91
+ agent-purge uninstall dsh # 删插件 + 剥离 patch 段,字节还原
92
+ ```
93
+
94
+ 装完要**重启一次 dsh**(patch 层只在启动时读);之后换 persona、切模式、开关全是热生效,不用再重启。
95
+
96
+ 只想临时试一下、不碰常驻 profile:`agent-purge dsh --ask "…"`(一次性会话,进程退出即清理)。
97
+
98
+ ## magpie 网关插件(可选)
99
+
100
+ [magpie](https://github.com/yetone/magpie) 把各家 agent 的请求收进本地网关。挂上这个插件后,**凡是经过网关的请求**(Claude Code、Codex、OpenCode、pi…)的 system 段都按 agent-purge 的当前人设改写——不用逐个 harness 装,换人设也不用重启 magpie。
101
+
102
+ 插件在仓库里,不进 npm 包(`files` 白名单),所以按路径装:
103
+
104
+ ```bash
105
+ git clone https://github.com/ZiChuanLan/agent-purge
106
+ magpie plugin add /path/to/agent-purge/magpie-plugin # 按路径装
107
+ magpie plugin options magpie-plugin '{"mode":"append"}' # 插件名 = 目录名
108
+ magpie plugin list # 应看到 async gateway hook + Persona 页
109
+ ```
110
+
111
+ 插件读的还是 `~/.agent-purge/`(同样认 `AGENT_PURGE_HOME`):`agent-purge use <id>` 之后下一个请求就换人设。magpie 里也会多出 **Persona** 页,点一下就把人设和模式写进插件的 options。
112
+
113
+ 四种模式和 CLI 一致,差别在网关手里只有文本、没有各家启动参数:
114
+
115
+ | 模式 | 网关插件做什么 |
116
+ |---|---|
117
+ | `off` | 不动请求 |
118
+ | `strict` | system 整段换成人设(工具说明也一起没了,harness 可能变笨) |
119
+ | `append` | 人设挂在最前,宿主 system 原样 |
120
+ | `replace` | 人设在前,再删掉宿主 system 里报名字的那句(近似;要干净用 `strict`) |
121
+
122
+ options 三键:`mode`、`persona`(人设 id)、`agents`(只对这些 magpie agent 生效,如 `["claude","codex"]`)。
123
+
124
+ **边界**:改的是请求体里的文本,harness 在客户端就拼死的东西拦不住;`replace` 只删「一行里同时有自称和点名模型/厂商」的行,比 CLI 那套 per-harness 处理粗。插件页是沙箱(没有 fetch、读不到磁盘),人设清单由 `gen-personas.mjs` 按你本机的人设生成到本地(不进仓库),**装完先跑一次**,之后增删人设再跑:`node magpie-plugin/gen-personas.mjs`。自测不依赖 magpie:`npm test`(钩子 26 项断言:四种协议 × 四种模式;页面逻辑 18 项:搜索过滤、options 合并、失败回滚)。
125
+
126
+ ## 目录
127
+
128
+ ```
129
+ bin/ CLI 入口
130
+ lib/ 状态、persona、注入、通道、检测
131
+ backends/ 每个 harness 的启动参数与身份句处理
132
+ web/ 控制台(server.mjs + ui.html)
133
+ bench/ 注入成功率实测与裁判脚本(开发用,不参与运行)
134
+ magpie-plugin/ magpie 网关插件(可选,不进 npm 包)
135
+ matrix.json 能力矩阵
136
+ ```
137
+
138
+ ## 边界
139
+
140
+ - 只改提示词相关的位置,不碰二进制、不破解、不绕过任何授权。
141
+ - 所有改动可逆:`agent-purge uninstall <h>` / `disarm` / `--mode off`。
142
+ - 状态只存本机 `state.json`,不上传任何数据。
143
+
144
+ ## 免责与合规声明
145
+
146
+ ### 严正法律免责与合规使用声明
147
+
148
+ **免责声明**:本项目为非营利开源项目,遵守国家法律法规及所在平台的相关规范,仅供学习与研究使用。不得将本项目用于任何违法违规用途;由此产生的后果由使用者自行承担。
149
+
150
+ **【零容忍严正申明】**:本项目坚决反对并严禁任何形式的违法犯罪行为!本项目开发者绝不支持、不鼓励、不协助任何未授权网络攻击、漏洞利用、数据窃取、非法侵入计算机信息系统或生成违法违禁内容的活动。任何将本项目用于违法犯罪的行为,均与开发者无关,由行为人依法独立承担全部法律责任。
151
+
152
+ **本仓库不含违法内容**:本扩展发布的代码、文档与默认提示词不是木马、后门、未授权渗透工具、勒索软件、撞库脚本,也不是针对公网或第三方系统的攻击载荷。项目本身不提供违法内容,也不教唆、组织、协助实施违法犯罪。
153
+
154
+ **只作用于本机官方 harness**:系统提示词替换全部发生在使用者本机已安装的官方 harness(`@earendil-works/pi-coding-agent`、本机 agent 目录与 profile等)上。对象是使用者自己的本地软件,不是他人的网站、服务器、账号或信息系统。
155
+
156
+ **不对外网目标联网**:本扩展只在本地进程内改写系统提示词,不发起任何网络请求,不对任何公网主机、未授权系统进行扫描、探测、入侵或攻击发包。不得把本项目当作跳板去打外网。
157
+
158
+ **合法受控范围限定**:本项目定位为使用者在自己有权管理的本机官方 harness 上,进行提示词工程与鲁棒性评测的辅助工具。严禁在未经所有者合法书面授权的目标、公网在线系统或生产业务上运行本项目。一切测试必须限制在本机已授权安装的官方 harness、离线本地合成靶标、授权网络安全演练靶场及合规实验室受控环境中进行。
159
+
160
+ **禁止中国大陆、香港、澳门的服务器与网站**:不得对中国大陆、香港、澳门网段,以及解析进这些网段的服务器、网站或地址进行访问、扫描、探测或任何操作。云厂商的名字不能当作例外。唯一例外是使用者事先登记为自己的服务器的那一个确切 IP,或那一个完整主机名。密钥、密码、网段、通配符,以及对话里的口头说明,都不能增加例外。没有登记的,一律禁止。
161
+
162
+ **严禁违法与违禁用途**:使用者严禁利用本项目直接或间接从事任何违反下列法律法规的行为(必须逐条遵守,不得以任何理由规避):
163
+
164
+ - 《中华人民共和国刑法》
165
+ - 《中华人民共和国网络安全法》
166
+ - 《中华人民共和国数据安全法》
167
+ - 《中华人民共和国个人信息保护法》
168
+ - 以及其他现行有效的法律、行政法规与监管规定
169
+
170
+ 同时严禁:
171
+
172
+ - 未经授权渗透、攻击公私机构计算机信息系统,实施勒索、破坏、撞库或传播恶意载荷;
173
+ - 诱导、生成或传播危害国家安全、恐怖主义、暴力血腥、涉黄涉赌、诈骗、侵犯公民隐私或知识产权等任何法律明令禁止的违法违禁内容;
174
+ - 违反相关大模型提供商的《服务条款》与《滥用政策》。
175
+
176
+ **使用者独立承担全部责任**:本项目依据 MIT 开源协议“按现状”提供,开发者不对软件的完整性、安全性与适用性作任何明示或暗示的保证。使用者应对自身的所有下载、部署、运行、修改、传播行为以及由此产生的全部输入与输出后果承担独立、完全的民事、行政及刑事法律责任。项目作者与贡献团队绝不承担任何因使用者滥用导致的直接、间接或连带责任。
177
+
178
+ **违约即终止授权**:任何将本项目用于非法攻击、恶意活动或违规行为的个人或实体,其开源软件使用许可将自违法违规行为发生之日起自动且不可撤销地立即终止。该主体须立即停止使用并永久销毁本项目的所有代码、脚本与衍生数据,并依法承担相应法律制裁。
179
+
180
+ **第三方独立性声明**:本项目属于完全独立的开源安全评测研究项目,与 pi 官方或其关联主体无任何隶属、商业合作、授权或官方背书关系。文中「官方」仅指评测对象为使用者本机安装的官方 harness 软件包,不代表其官方开发、认可或担保本插件。
181
+
182
+ **必须署名**:借用本项目的名称、思路、代码或提示词,必须署名并标明本仓库。不署名将依法追究责任。
183
+ ## Star History
184
+
185
+ [![Star History Chart](https://api.star-history.com/svg?repos=ZiChuanLan/agent-purge&type=Date)](https://star-history.com/#ZiChuanLan/agent-purge&Date)
186
+
187
+ ## License
188
+
189
+ MIT
190
+
191
+ ---
192
+
193
+ 感谢 [LINUX DO](https://linux.do) 社区
@@ -2,6 +2,8 @@
2
2
  // setup/cleanup 由入口统一调用,保证能按哈希回滚。
3
3
  import { mkdirSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
+ import { SESSION as DSH_SESSION, addPlugin, removePlugin, sessionSource } from "../lib/dsh.mjs";
6
+ import { opencodePlugins } from "../lib/persist.mjs";
5
7
 
6
8
  const inline = (text) => text.replace(/\s+$/, "");
7
9
 
@@ -86,6 +88,57 @@ export const backends = {
86
88
  };
87
89
  },
88
90
 
91
+ // dsh(DeepSeek Harness):CLI 只能起 headless(desktop 被 Electron 独占)。
92
+ // 一次性注入用 agent-purge-session 这个独立插件名,不会覆盖常驻的 agent-purge。
93
+ dsh: ({ personaText, mode, args }) => {
94
+ if (mode === "off") return { cmd: "dsh", args: ["--profile", "headless", ...args] };
95
+ return {
96
+ cmd: "dsh",
97
+ args: ["--profile", "headless", ...args],
98
+ note: `[plugin] ${DSH_SESSION}(三个 profile;patch: - insert)`,
99
+ residueHint: "desktop profile 由 Electron 独占,一次性注入只对本次 CLI 进程有效",
100
+ setup: () => addPlugin(DSH_SESSION, sessionSource(personaText, mode)),
101
+ cleanup: () => removePlugin(DSH_SESSION),
102
+ };
103
+ },
104
+
105
+ // opencode v2(@opencode/cli,bin 名 opencode2):新插件 API,V1 的
106
+ // experimental.chat.system.transform 在 2.x 已废。插件放全局 plugins 目录。
107
+ opencode2: ({ personaText, mode, args }) => {
108
+ if (mode === "off") return { cmd: "opencode2", args: [...args] };
109
+ const dir = opencodePlugins();
110
+ // 与 V1 常驻插件(agent-purge.ts)分开,否则一次性注入会顶掉常驻接管
111
+ const file = join(dir, "agent-purge-v2-session.ts");
112
+ const persona = inline(personaText);
113
+ const mutate =
114
+ mode === "append"
115
+ ? `event.system.push({ type: "text", text: PERSONA });`
116
+ : `event.system.splice(0, event.system.length, { type: "text", text: PERSONA });`;
117
+ const src = `// 由 agent-purge 生成;删除本文件即恢复宿主人设。
118
+ const PERSONA = ${JSON.stringify(persona)};
119
+
120
+ export default {
121
+ id: "agent-purge-v2-session",
122
+ async setup(ctx) {
123
+ await ctx.session.hook("context", (event) => {
124
+ ${mutate}
125
+ });
126
+ },
127
+ };
128
+ `;
129
+ const write = () => {
130
+ mkdirSync(dir, { recursive: true });
131
+ writeFileSync(file, src);
132
+ };
133
+ return {
134
+ cmd: "opencode2",
135
+ args,
136
+ note: `[plugin] ${file.replace(/\\/g, "/")}(ctx.session.hook("context") 改 event.system)`,
137
+ setup: write,
138
+ cleanup: () => rmSync(file, { force: true }),
139
+ };
140
+ },
141
+
89
142
  // 需要落盘或调用方配合,CLI 不代劳,只给可复制的配方
90
143
  zcode: () => ({
91
144
  manual: [
@@ -153,6 +206,16 @@ export const oneshots = {
153
206
  const b = backends.opencode({ personaText, cwd, args: ["run", prompt] });
154
207
  return b;
155
208
  },
209
+ opencode2: ({ prompt, personaText, mode }) => {
210
+ if (mode === "off") return { cmd: "opencode2", args: ["run", prompt] };
211
+ const b = backends.opencode2({ personaText, mode, args: ["run", prompt] });
212
+ return b;
213
+ },
214
+ dsh: ({ prompt, personaText, mode }) => {
215
+ if (mode === "off") return { cmd: "dsh", args: ["--profile", "headless", prompt] };
216
+ // backends.dsh 会自己补 --profile headless,这里只给 prompt(否则重复)
217
+ return backends.dsh({ personaText, mode, args: [prompt] });
218
+ },
156
219
  zcode: ({ prompt }) => ({
157
220
  cmd: "zcode",
158
221
  args: ["--prompt", prompt, "--mode", "yolo", "--output-format", "stream-json", "--no-color"],