@zythegit/agentforge 0.2.0-rc.1 → 0.2.0
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 +32 -369
- package/dist/aforge.js +321 -296
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,74 +11,22 @@
|
|
|
11
11
|
- **learnings/**:从实战经验沉淀、待确认的条目(`aforge learn`);
|
|
12
12
|
- **templates/、skills/、mcp/**:可复用模板、技能与 MCP 服务器声明。
|
|
13
13
|
|
|
14
|
-
执行 `aforge sync` 后,以上内容被渲染并写入各 Agent 的原生规则文件。AgentForge 只管理文件中的 marker
|
|
14
|
+
执行 `aforge sync` 后,以上内容被渲染并写入各 Agent 的原生规则文件。AgentForge 只管理文件中的 marker 区间,区间外你的手写内容原样保留。规则正文之外,同一次 `sync` 还会投影技能目录、MCP 配置,以及(按需开启的)命令薄壳。
|
|
15
15
|
|
|
16
16
|
## 安装
|
|
17
17
|
|
|
18
|
-
### 方式一:npx 直接用(推荐,无需克隆)
|
|
19
|
-
|
|
20
18
|
前置:Node ≥ 20.19。
|
|
21
19
|
|
|
22
20
|
```powershell
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
npx -y @zythegit/agentforge@latest init -i
|
|
26
|
-
|
|
27
|
-
# 常用则全局装,之后直接 aforge
|
|
28
|
-
npm i -g @zythegit/agentforge
|
|
29
|
-
aforge --version
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
包名是 `@zythegit/agentforge`,命令名是 `aforge`。发布产物是 esbuild 打出的单文件 bundle(依赖已内联),因此 `npx` 冷启动只下载一个文件,不再安装任何运行时依赖。
|
|
33
|
-
|
|
34
|
-
### 方式二:下载独立二进制(免 Node,兜底)
|
|
35
|
-
|
|
36
|
-
只有在目标机器装不了 Node 时才需要这条路:二进制内嵌了 bun 运行时,压缩包 36~39 MB(解包后 64~86 MB),比 npm 包大两个数量级。
|
|
37
|
-
|
|
38
|
-
从 [Releases](https://github.com/zyTheGit/AgentForge/releases) 下载对应平台的压缩包(附 `checksums.txt`,内容是**压缩包**的 sha256):
|
|
39
|
-
|
|
40
|
-
| 平台 | 资产 |
|
|
41
|
-
| --- | --- |
|
|
42
|
-
| Windows x64 | `aforge-win32-x64.zip` |
|
|
43
|
-
| Linux x64 / arm64 | `aforge-linux-x64.tar.gz` / `aforge-linux-arm64.tar.gz` |
|
|
44
|
-
| macOS Apple Silicon / Intel | `aforge-darwin-arm64.tar.gz` / `aforge-darwin-x64.tar.gz` |
|
|
45
|
-
|
|
46
|
-
解包后重命名为 `aforge`(Windows 为 `aforge.exe`)放进 PATH 即可。
|
|
47
|
-
|
|
48
|
-
macOS 上二进制未做签名与公证,首次运行会被 Gatekeeper 拦下,需手动去掉隔离属性:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
xattr -d com.apple.quarantine ./aforge
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
`aforge-linux-arm64` 在 CI 里只靠 QEMU 模拟跑过 `--version`,没有 arm64 真机验证;`aforge-darwin-x64` 既无免费 runner 也无法用容器模拟,属于「已交叉编译但完全未冒烟」。
|
|
55
|
-
|
|
56
|
-
### 方式三:从源码构建
|
|
57
|
-
|
|
58
|
-
前置:安装 [bun](https://bun.sh/) 与 [fnm](https://github.com/Schniz/fnm)(或任意 Node 版本管理器)。
|
|
59
|
-
|
|
60
|
-
```powershell
|
|
61
|
-
# 每个新终端先激活 Node 环境(fnm)
|
|
62
|
-
fnm env --shell power-shell | Out-String -Stream | Invoke-Expression
|
|
63
|
-
fnm use 22
|
|
64
|
-
|
|
65
|
-
git clone https://github.com/zyTheGit/AgentForge.git
|
|
66
|
-
cd AgentForge
|
|
67
|
-
npm install
|
|
68
|
-
|
|
69
|
-
npm run build:node # 产出 dist\aforge.js(esbuild 打包压缩,需 Node ≥ 20.19)
|
|
70
|
-
npm run build:bun # 产出当前平台的单文件二进制(dist\aforge-win32-x64.exe 等)
|
|
71
|
-
npm run build:bun:all # 交叉编译五平台(win32-x64 / linux-x64 / linux-arm64 / darwin-x64 / darwin-arm64)
|
|
72
|
-
bun link # 之后任意目录可用 aforge 命令
|
|
21
|
+
npx -y @zythegit/agentforge@latest --version # 免安装试跑
|
|
22
|
+
npm i -g @zythegit/agentforge # 常用则全局装,命令名是 aforge
|
|
73
23
|
```
|
|
74
24
|
|
|
75
|
-
|
|
76
|
-
|
|
25
|
+
免 Node 的独立二进制、从源码构建、macOS / Linux 差异见 [docs/install.md](docs/install.md)。
|
|
77
26
|
|
|
78
|
-
##
|
|
27
|
+
## 快速开始
|
|
79
28
|
|
|
80
29
|
```powershell
|
|
81
|
-
# 进入你的项目
|
|
82
30
|
cd C:\path\to\your-project
|
|
83
31
|
|
|
84
32
|
# ① 交互式初始化:选 scope → 自动探测工具链 → 确认 → 选目标 Agent → 写入(可选立即 sync)
|
|
@@ -101,268 +49,18 @@ aforge sync
|
|
|
101
49
|
aforge import AGENTS.md # 或 CLAUDE.md:识别工具链关键词 → habits 建议字段 + custom 素材
|
|
102
50
|
```
|
|
103
51
|
|
|
104
|
-
##
|
|
105
|
-
|
|
106
|
-
| 命令 | 作用 |
|
|
107
|
-
|------|------|
|
|
108
|
-
| `aforge init -i` | 交互式五步初始化(scope → 探测 → 确认 → 选 target → 写入) |
|
|
109
|
-
| `aforge init [--scope project\|user] [--json]` | 非交互初始化(探测快照 + 骨架落盘) |
|
|
110
|
-
| `aforge detect [--json]` | 探测本机工具链(node/python/包管理器/shell/已有规则文件),无副作用 |
|
|
111
|
-
| `aforge sync [--targets a,b] [--dry-run] [--force] [--json]` | 渲染 SoT 并投影到目标 Agent |
|
|
112
|
-
| `aforge learn [--scope s] [--file f\|'-'] [--id id] [--no-auto-promote]` | 记录一条 learning(不投影;`learning.auto_promote: true` 时顺手 promote,`--no-auto-promote` 单次关掉) |
|
|
113
|
-
| `aforge promote <id> [--to user] [--yes]` | 将 learning 升级为 custom 规则或 skill |
|
|
114
|
-
| `aforge learnings list [--json]` / `show <id>` / `edit <id>` / `rm <id>` | 管理两层 SoT 的 learning 条目 |
|
|
115
|
-
| `aforge source add <path\|git-url> [--ref r] [--id id]` | 登记规则/模板/技能来源(local 或 git) |
|
|
116
|
-
| `aforge source list [--json]` / `remove <id>` / `update <id>` | 管理已登记来源(update 离线报错) |
|
|
117
|
-
| `aforge template list [--json]` / `enable <id>` / `disable <id>` | 管理规则模板 |
|
|
118
|
-
| `aforge skill add <name> [--from src]` / `list [--json]` / `remove <name> [--scope s]` | 安装(实体拷贝)/列出/注销技能(`remove` 只改 profile,文件保留) |
|
|
119
|
-
| `aforge mcp add [--scope s] [--from-json] [--json]` / `remove <name> [--scope s] [--json]` | 登记 / 移除 MCP 服务器声明(`--from-json` 从 stdin 读 JSON 声明) |
|
|
120
|
-
| `aforge status [--json]` | SoT 概览:scope、目标路径、最近 sync、内容计数 |
|
|
121
|
-
| `aforge doctor [--json]` | 体检:配置合法性、投影一致性、环境问题 |
|
|
122
|
-
| `aforge import <path>` | 从既有 AGENTS.md / CLAUDE.md 导入工具链声明与素材 |
|
|
123
|
-
| `aforge bundle export --out <dir>` / `import --from <dir>` | 把一层 SoT 打包搬走 / 落回(迁移、备份、换机器;见下文「迁移 SoT」) |
|
|
124
|
-
|
|
125
|
-
`--json` 同时是 program 级全局标志:任何子命令都可写成 `aforge --json <cmd>`,输出为机器可读 JSON(路径一律绝对路径)。注意 `mcp add` 的**输入**标志叫 `--from-json`,`--json` 只表示输出契约。
|
|
126
|
-
|
|
127
|
-
## 安装 skill
|
|
128
|
-
|
|
129
|
-
`aforge skill add` 接的是**技能名**,不是 URL——URL 要先 `aforge source add` 登记成「源」,再按名安装。以装 vercel-labs/skills 里的 `find-skills` 为例:
|
|
130
|
-
|
|
131
|
-
```powershell
|
|
132
|
-
# ① 登记 git 源(必须显式 --ref,Spec 不跟踪浮动分支)
|
|
133
|
-
aforge source add https://github.com/vercel-labs/skills --ref main
|
|
134
|
-
# clone 到 %USERPROFILE%\.agentforge\store\skills;id 由 basename 派生为 "skills"
|
|
135
|
-
# 想自定义 id 加 --id vercel-skills
|
|
136
|
-
|
|
137
|
-
# ② 看源里有哪些技能可装(status=available 的条目)
|
|
138
|
-
aforge skill list
|
|
139
|
-
|
|
140
|
-
# ③ 按名安装:实体拷贝到 SoT 的 skills\find-skills\
|
|
141
|
-
aforge skill add find-skills --from skills
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
`--from` 可省略(按登记顺序在所有启用的源中找首个含该技能的源),也可直接传路径而完全跳过 `source add`——传源根目录(其下有 `skills\<name>\`)或直接传含 `SKILL.md` 的技能目录本身:
|
|
145
|
-
|
|
146
|
-
```powershell
|
|
147
|
-
aforge skill add find-skills --from D:\clones\vercel-labs-skills # 源根
|
|
148
|
-
aforge skill add my-skill --from .\drafts\my-skill # 技能目录本身
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
`skill add` 除了把文件拷进 `.agentforge\skills\`,还会把技能名登记进**同一层** `profile.yaml` 的 `skills.always`(幂等,重复 add 不会写重名),所以装完直接 `sync` 就能投影:
|
|
152
|
-
|
|
153
|
-
```yaml
|
|
154
|
-
# .agentforge\profile.yaml(skill add 自动维护)
|
|
155
|
-
skills:
|
|
156
|
-
copy_mode: copy
|
|
157
|
-
always:
|
|
158
|
-
- find-skills
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
```powershell
|
|
162
|
-
aforge sync
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
注意:凡是会写 `profile.yaml` 的命令(`skill add`、`skill remove`、`mcp add`、`mcp remove`、`template enable`)都是整份重新序列化,YAML 注释、空行和行内数组写法(`targets: [claude]`)会丢失,键顺序变成程序内部顺序——手写过的 `profile.yaml` 被这些命令改过后格式会变。
|
|
166
|
-
|
|
167
|
-
只想拷文件、自己手工编排 `profile.yaml` 的话加 `--no-register`:
|
|
168
|
-
|
|
169
|
-
```powershell
|
|
170
|
-
aforge skill add find-skills --no-register
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
投影落点(project scope,`SKILL.md` 正文):
|
|
174
|
-
|
|
175
|
-
- opencode → `.opencode\skills\<name>\SKILL.md`
|
|
176
|
-
- codex → `.agents\skills\<name>\SKILL.md`
|
|
177
|
-
- claude → `.claude\skills\<name>\SKILL.md`
|
|
178
|
-
- pi → `.pi\skills\<name>\SKILL.md`
|
|
179
|
-
|
|
180
|
-
要点:
|
|
181
|
-
|
|
182
|
-
- 源仓库布局须为 `<源根>\skills\<name>\SKILL.md`;
|
|
183
|
-
- 目标 `skills\<name>` 已有内容 → 退出码 3,先手删该目录再装;
|
|
184
|
-
- 源里的 symlink 一律跳过不跟随(防私钥等被读进 SoT),跳过项在输出的 `skipped` 里列出;
|
|
185
|
-
- `skills.always` 点了名却没装 → `sync` 直接报错退出码 2;
|
|
186
|
-
- 装到 user 层时注意 §5.3 合并语义:`merge.arrays: replace`(缺省)下 project 层自己写了 `skills.always` 就会整体覆盖 user 层那份;
|
|
187
|
-
- 附属文件(脚本、参考资料)会拷进 SoT,但当前只有 `SKILL.md` 正文参与投影。
|
|
188
|
-
|
|
189
|
-
不想再让某个技能被投影时用 `skill remove`——它**只**把名字从该层 `profile.yaml` 的 `skills.always` 摘掉,`skills\<name>\` 目录原样留在磁盘上:
|
|
190
|
-
|
|
191
|
-
```powershell
|
|
192
|
-
aforge skill remove find-skills
|
|
193
|
-
# skill removed: find-skills (profile only)
|
|
194
|
-
# scope : project
|
|
195
|
-
# profile : D:\proj\.agentforge\profile.yaml
|
|
196
|
-
# always : pdf-tools
|
|
197
|
-
# skill dir : D:\proj\.agentforge\skills\find-skills (kept on disk)
|
|
198
|
-
#
|
|
199
|
-
# note: removed from profile.yaml only. run `aforge sync` to drop the
|
|
200
|
-
# projected copies (project level):
|
|
201
|
-
# D:\proj\.opencode\skills\find-skills\SKILL.md
|
|
202
|
-
# D:\proj\.agents\skills\find-skills\SKILL.md
|
|
203
|
-
# D:\proj\.claude\skills\find-skills\SKILL.md
|
|
204
|
-
# D:\proj\.pi\skills\find-skills\SKILL.md
|
|
205
|
-
# manually edited copies are kept and listed under `prune skipped`.
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
- **投影产物由下一次 `aforge sync` 清理。** 摘除只作用于 SoT;再跑一次 `sync` 会按上一轮记账(`sync-meta.json` 的 `artifacts`)删掉 `.claude\skills\<name>\SKILL.md`(`.opencode` / `.agents` / `.pi` 同理),并在输出的 `pruned` 里列出。只删内容仍与记账一致的文件——手工改过的那份会保留并报进 `prune skipped`,详见 Spec §7.6;
|
|
209
|
-
- `--scope project|user` 指定改哪一层(缺省同 `add`:AGF_SCOPE > project 在用 > user 在用);两层都登记了同名技能时要各删一次;
|
|
210
|
-
- 该层 `skills.always` 里没有这个名字 → 退出码 2(不当成幂等成功,多半是层选错了)。错误提示会说明目录是否还在盘上;如果另一层登记了同名,提示会直接给出可复制的 `--scope <另一层>`;
|
|
211
|
-
- 摘完 `always` 只剩空数组时那一行显示 `(none)`;注意 `merge.arrays: replace` 下空数组**仍会覆盖** user 层,要让 user 层的同名技能重新生效得手工删掉 project 层的整个 `skills.always` 键;
|
|
212
|
-
- 要腾空间 / 想重装,删完登记后手工删除 `skills\<name>\`(`skill add` 遇到已存在且非空的目录会报退出码 3)。
|
|
213
|
-
|
|
214
|
-
## 登记 MCP 服务器
|
|
215
|
-
|
|
216
|
-
`aforge mcp add` 把声明写进目标层 `profile.yaml` 的 `mcp.servers`(同名 upsert,重复 add 即更新),`sync` 时再翻译成各 Agent 的原生 MCP 配置。
|
|
217
|
-
|
|
218
|
-
交互录入(需要真实终端)。以装 `npx -y @zythegit/jenkins-config-mcp` 为例:
|
|
219
|
-
|
|
220
|
-
```powershell
|
|
221
|
-
aforge mcp add
|
|
222
|
-
# name : jenkins-config
|
|
223
|
-
# transport : stdio
|
|
224
|
-
# command : npx
|
|
225
|
-
# args : -y @zythegit/jenkins-config-mcp ← 空格分隔,自动切成数组
|
|
226
|
-
# env : 留空(需要凭据时填 JENKINS_URL=...,JENKINS_TOKEN=...)
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
脚本化:从 stdin 读一个 JSON 声明(注意标志是 `--from-json`):
|
|
52
|
+
## 常用指令
|
|
230
53
|
|
|
231
54
|
```powershell
|
|
232
|
-
#
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
#
|
|
237
|
-
|
|
238
|
-
aforge mcp add --from-json
|
|
239
|
-
|
|
240
|
-
# 写到用户层,让所有项目共享
|
|
241
|
-
'{"name":"jenkins-config","transport":"stdio","command":"npx","args":["-y","@zythegit/jenkins-config-mcp"]}' |
|
|
242
|
-
aforge mcp add --from-json --scope user
|
|
243
|
-
|
|
244
|
-
aforge sync
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
必填字段:`name` + `transport`;`stdio` 必须给 `command`,`http` / `sse` 必须给 `url`,否则退出码 2。声明里带 `"enabled": false` 的 server 不投影,但保留在 `profile.yaml` 里。
|
|
248
|
-
|
|
249
|
-
不想再用某个 server 时用 `mcp remove` 把声明从该层 `mcp.servers` 里摘掉:
|
|
250
|
-
|
|
251
|
-
```powershell
|
|
252
|
-
aforge mcp remove jenkins-config
|
|
253
|
-
# mcp server removed: jenkins-config
|
|
254
|
-
# transport : stdio
|
|
255
|
-
# scope : project
|
|
256
|
-
# profile : D:\proj\.agentforge\profile.yaml
|
|
257
|
-
# servers : ctx7
|
|
258
|
-
#
|
|
259
|
-
# note: removed from profile.mcp.servers only. run `aforge sync` to drop the
|
|
260
|
-
# "jenkins-config" entry from these project-level files:
|
|
261
|
-
# D:\proj\opencode.json
|
|
262
|
-
# D:\proj\.mcp.json
|
|
263
|
-
# D:\proj\.pi\mcp.json
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
- **投影里的 server 键由下一次 `aforge sync` 摘除。** `sync` 按上一轮记账(`sync-meta.json` 的 `mcpServers`)算差集,把被删的 server 从 `opencode.json` / `.mcp.json` / `.pi\mcp.json` 里摘掉,文件本身与其余键原样保留。这不违背 merge_json 的「未知键一律保留」(Spec §8.2)——摘的只是记账里认领过的键;codex 的 `.codex\config.toml` 走 marker 段整段重写,本来就会自动跟上。详见 Spec §7.6;
|
|
267
|
-
- `--scope project|user` 指定改哪一层(缺省同 `add`);`--json`(或 `aforge --json mcp remove <name>`)输出机器可读结果,含被删条目 `removed` 与该层剩余 `servers`;
|
|
268
|
-
- 该层没有这个名字 → 退出码 2,错误消息会列出该层现有的 server 名;如果另一层登记了同名,提示会直接给出可复制的 `--scope <另一层>`;
|
|
269
|
-
- 摘掉最后一条后 `servers` 一行显示 `(none)`;
|
|
270
|
-
- 只想临时停用而保留配置的话,别用 remove——把声明里的 `enabled` 改成 `false` 重新 `add`(同名 upsert)即可。
|
|
271
|
-
|
|
272
|
-
投影落点(project scope):
|
|
273
|
-
|
|
274
|
-
- opencode → `opencode.json` 的 `mcp` 键(merge_json,未知键保留)
|
|
275
|
-
- codex → `.codex\config.toml` 的 `# BEGIN AGENTFORGE MCP` 标记段(merge_toml,段外 TOML 与注释原样保留)
|
|
276
|
-
- claude → `.mcp.json` 的 `mcpServers` 键(merge_json)
|
|
277
|
-
- pi → `.pi\mcp.json` 的 `mcpServers` 键(merge_json,**soft 项**:写失败只报 warning,不算 sync 失败、不触发回滚)。pi 本体不内建 MCP,先装适配扩展才生效:`pi install npm:pi-mcp-adapter`(见 <https://pi.dev/packages/pi-mcp-adapter>);写 `.pi\mcp.json` 而不是根 `.mcp.json`,是为了不与 claude 的投影争用同一路径(同一次 sync 里两个 projector 写同一文件会互相覆盖)。适配器优先级:`.pi\mcp.json`(项目级)> `.mcp.json`(项目共享)> `<Pi agent dir>\mcp.json`(user 级,即 user scope 的落点)> `~\.config\mcp\mcp.json` / `~\.agents\mcp.json`——user 级 pi 配置会被任何项目的 `.mcp.json` 盖掉,别把它当兜底;user scope 目前也不认 `PI_CODING_AGENT_DIR`,置位该变量时这份投影落在 pi 不读的路径上
|
|
278
|
-
|
|
279
|
-
> 升级提示:早期版本把 pi 的 MCP 写在 `.pi\settings.json`(user 级 `~\.pi\agent\settings.json`)。现在落点是同目录的 `mcp.json`,旧文件**不会被自动迁移或删除**——确认新 `mcp.json` 生效后请手工删掉旧文件里的 `mcpServers` 键(整份文件没有你自己的 pi 设置时可直接删除)。`aforge doctor` 会把它报为 `residual/pi-legacy-mcp` warning。
|
|
280
|
-
|
|
281
|
-
以上面的 jenkins-config 为例,`sync` 后 `.mcp.json` 里会多出:
|
|
282
|
-
|
|
283
|
-
```json
|
|
284
|
-
{
|
|
285
|
-
"mcpServers": {
|
|
286
|
-
"jenkins-config": {
|
|
287
|
-
"command": "npx",
|
|
288
|
-
"args": ["-y", "@zythegit/jenkins-config-mcp"]
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
opencode 侧同一条声明会被译成 `{ "type": "local", "command": ["npx", "-y", "@zythegit/jenkins-config-mcp"], "enabled": true }`——各 target 的键名与形状不同,AgentForge 负责翻译,你只写一份声明。
|
|
295
|
-
|
|
296
|
-
Windows 上 `command: "npx"` 可能起不来:部分客户端不经 shell 直接 spawn,而 `npx.cmd` 不是可执行文件。启动失败就把 `command` 换成 `cmd`、`args` 前面补 `/c` 重新 add(同名 upsert,直接覆盖旧声明):
|
|
297
|
-
|
|
298
|
-
```powershell
|
|
299
|
-
'{"name":"jenkins-config","transport":"stdio","command":"cmd","args":["/c","npx","-y","@zythegit/jenkins-config-mcp"]}' |
|
|
300
|
-
aforge mcp add --from-json
|
|
55
|
+
aforge status # SoT 概览:scope、各 target 落点与技能调用前缀、最近一次 sync
|
|
56
|
+
aforge doctor # 体检:配置合法性、投影一致性、环境问题
|
|
57
|
+
aforge sync --dry-run # 只看会写哪些文件,不落盘
|
|
58
|
+
aforge learn # 记一条 learning(不投影,promote 后才进规则)
|
|
59
|
+
aforge skill add <name> # 装技能进 SoT 并登记,sync 后投影到四家
|
|
60
|
+
aforge mcp add # 登记 MCP 服务器,sync 时翻译成各 Agent 的原生配置
|
|
301
61
|
```
|
|
302
62
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
## 迁移 SoT(换机器 / 备份 / 复制到另一个项目)
|
|
306
|
-
|
|
307
|
-
`aforge bundle export` 把**一层** SoT 打成一个可搬走的目录,`bundle import` 把它落回另一层。注意与 `aforge import <path>`(从既有 AGENTS.md 抽工具链声明)不是一回事,两者刻意分开命名。
|
|
308
|
-
|
|
309
|
-
```powershell
|
|
310
|
-
# 旧机器:导出 project 层
|
|
311
|
-
aforge bundle export --out D:\agf-bundle
|
|
312
|
-
# 产物:D:\agf-bundle\manifest.json + D:\agf-bundle\sot\...
|
|
313
|
-
|
|
314
|
-
# 新机器:落回(不需要先 init,目录会自动创建)
|
|
315
|
-
aforge bundle import --from D:\agf-bundle
|
|
316
|
-
aforge detect # 重建本机工具链快照
|
|
317
|
-
aforge sync # 投影到四个目标
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
完整参数:
|
|
321
|
-
|
|
322
|
-
| 参数 | 用在 | 说明 |
|
|
323
|
-
|------|------|------|
|
|
324
|
-
| `--out <dir>` | export | 必填。输出目录,相对当前目录解析;必须为空或不存在 |
|
|
325
|
-
| `--from <dir>` | import | 必填。`bundle export` 产出的目录(其下应有 `manifest.json` 与 `sot/`) |
|
|
326
|
-
| `--scope project\|user` | 两者 | export 缺省按有效 scope;import 缺省 `AGF_SCOPE` → `project`。两端可以不同层:`export --scope user` 后 `import --scope project` 就是把用户层内容复制进项目层 |
|
|
327
|
-
| `--no-redact` | export | 原样带走 MCP 凭据(缺省抹成占位符)。此时 bundle 本身即密钥载体,别放进 git |
|
|
328
|
-
| `--keep-detected` | export | 保留 `habits.detected`(缺省剔除) |
|
|
329
|
-
| `--on-conflict skip\|overwrite\|rename` | import | 目标已存在同名文件时的策略,缺省 `skip`。拼错**不会**静默退化成缺省值,直接退出码 2 |
|
|
330
|
-
| `--json` | 两者 | 机器可读输出(绝对路径)。人类可读输出里超过 20 条的清单会折叠,要全量就用这个 |
|
|
331
|
-
|
|
332
|
-
常见用法:
|
|
333
|
-
|
|
334
|
-
```powershell
|
|
335
|
-
# 只想备份用户层(含 store/ 之外的全部沉淀)
|
|
336
|
-
aforge bundle export --scope user --out D:\agf-user-backup
|
|
337
|
-
|
|
338
|
-
# 目标已有内容、又不想丢自己的改动:两份都留着自己合并
|
|
339
|
-
aforge bundle import --from D:\agf-bundle --on-conflict rename
|
|
340
|
-
|
|
341
|
-
# 先看清楚会写哪些文件(--json 输出 entries[].target 是绝对路径)
|
|
342
|
-
aforge --json bundle import --from D:\agf-bundle
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
带走什么、留下什么(由 `core/bundle/layout` 的分类表决定,`manifest.excluded` 会逐条报出原因):
|
|
346
|
-
|
|
347
|
-
- **带走**:`habits.yaml`、`profile.yaml`、`sources.json`、`custom/`、`learnings/`(含未 promote 的条目)、`templates/`、`skills/`、`mcp/`;
|
|
348
|
-
- **剔除 `sync-meta.json`**(`machine-state`):里面是上一轮产物的**绝对路径 + prune 白名单**,换机器后基准是错的;
|
|
349
|
-
- **剔除 `.sync.lock` / `.agf-backup*`**(`transient`):事务残留;
|
|
350
|
-
- **剔除 `store/`**(`cache`):user 层的 git 源 clone,`aforge source update` 可重建;
|
|
351
|
-
- **剔除 `habits.detected`**:本机探测快照,`aforge detect` 一条命令重建(要留就加 `--keep-detected`);
|
|
352
|
-
- **其它非布局条目**(你随手放在 SoT 里的文件)报为 `not-part-of-sot`,既不带走也不静默丢弃。
|
|
353
|
-
|
|
354
|
-
安全与完整性:
|
|
355
|
-
|
|
356
|
-
- **默认抹掉 MCP 凭据**:`mcp.servers[].env` / `.headers` 的值换成占位符,字段路径记进 `manifest.redacted`,`import` 时会打出来提醒你重新填。真要原样带走密钥加 `--no-redact`。注意 redact **只覆盖这两处**——凭据若内联在 `command` / `args` / `url` 里(`--token xxx`、`https://user:pass@host`),形状不可知、抹不了,export 会在 warnings 里提示你自己过一遍;
|
|
357
|
-
- **import 先校验后落盘**:逐个文件比对 `manifest` 里的 sha256(LF 规范化,经 git / 压缩包搬运不会误报),任一处不符 → 退出码 2 且**一个字节都不写**;
|
|
358
|
-
- **manifest 按不可信输入对待**(它是可手工编辑的普通文件):`files[].path` 含 `..` / 绝对路径 / 盘符一律拒绝;首段不属于「带走」集合的也拒绝——`sync-meta.json` 这类被 export 剔除的本机状态**不接受反向导入**,否则下一次 `sync` 会照着别的机器的 prune 白名单删本机文件;
|
|
359
|
-
- **symlink 一律不跟随**:export 遇到 symlink(含顶层带走目录自身是 symlink)跳过并报进 warnings;import 在写第一个字节之前确认目标路径链上没有 symlink,有则退出码 2——防的是「SoT 里的 `custom/` 是条指向别处的链接,合法相对路径被穿透写到链接目标」;
|
|
360
|
-
- **默认不覆盖你的文件**:冲突策略缺省 `skip`,可选 `--on-conflict overwrite`(替换)或 `rename`(来料另存为 `<name>.imported`,两份都留着自己合并);
|
|
361
|
-
- `import` 全程持 SoT 事务锁(与 `sync` 同一把),但**不会自动 sync**——填 SoT 与写别人的文件是两件事。
|
|
362
|
-
|
|
363
|
-
退出码:`2` 配置/校验类(未 init、`--out` 落在 SoT 内、manifest 坏或路径越界、哈希不符、路径链上有 symlink、`--on-conflict` 取值非法);`3` 冲突类(`--out` 非空、SoT 锁被他人持有、`rename` 落点耗尽);`4` 权限类(目标不可写)。
|
|
364
|
-
|
|
365
|
-
已知取舍:`habits.yaml` / `profile.yaml` 经「解析 → 净化 → 重新序列化」往返,**YAML 注释会丢**(同 `skill add` 写 profile 的代价);`--no-redact --keep-detected` 时两份文件走原文直拷,注释保留。内容一律按 UTF-8 文本处理,二进制附属文件不在支持范围内。bundle 目录是可丢弃产物,写到一半失败就删掉重跑。契约细节见 Spec §7.9。
|
|
63
|
+
任何子命令都可加 `--json` 拿机器可读输出(路径一律绝对路径)。完整 14 个命令、参数与退出码见 [命令速查](docs/commands.md)。
|
|
366
64
|
|
|
367
65
|
## 工作原理
|
|
368
66
|
|
|
@@ -377,7 +75,13 @@ aforge --json bundle import --from D:\agf-bundle
|
|
|
377
75
|
└────────────────────────────┘
|
|
378
76
|
```
|
|
379
77
|
|
|
380
|
-
|
|
78
|
+
规则文件之外,同一次 `sync` 还落三类**整文件产物**(不用 marker,改名/摘名后由下一次 `sync` prune):
|
|
79
|
+
|
|
80
|
+
- **技能**:`skills/<name>/SKILL.md` 投影到四家各自的技能目录,`status` 会打出每家的调用前缀;
|
|
81
|
+
- **MCP**:一份 `profile.mcp.servers` 翻译成 opencode / codex / claude / pi 的原生配置;
|
|
82
|
+
- **命令薄壳**:`skills.expose_as_command` 点名的技能额外落一份命令/prompt,支持 `ns/name` 命名空间与 `$1..$9` 位置参数(见 [技能](docs/skills.md#额外投影成命令expose_as_command))。
|
|
83
|
+
|
|
84
|
+
每个投影的**规则文件**中,AgentForge 只管理 marker 区间:
|
|
381
85
|
|
|
382
86
|
```markdown
|
|
383
87
|
<!-- BEGIN AGENTFORGE -->
|
|
@@ -389,61 +93,20 @@ aforge --json bundle import --from D:\agf-bundle
|
|
|
389
93
|
|
|
390
94
|
- **变更检测**:sync 前对比 marker 区间指纹,发现你手改过区间内容 → 拒绝写入(退出码 3),`--force` 可覆盖;
|
|
391
95
|
- **事务化写入**:多 target 投影失败自动回滚已写文件;
|
|
392
|
-
- **两级合并**:user 层 SoT 与 project 层 SoT 按层合并(project
|
|
96
|
+
- **两级合并**:user 层 SoT 与 project 层 SoT 按层合并(project 优先);
|
|
97
|
+
- **环境无关**:投影正文不受 `CI` 等环境变量影响,同一份 SoT 在 CI 与本机渲染出的 `contentHash` 一致,`aforge doctor` 的 hash 比对才不会误报漂移。
|
|
393
98
|
|
|
394
|
-
##
|
|
395
|
-
|
|
396
|
-
- **路径**:统一使用绝对路径输出;用户级 SoT 默认在 `%USERPROFILE%\.agentforge`,项目级在 `<项目根>\.agentforge`。含中文与空格的路径已受测试覆盖,可放心使用。
|
|
397
|
-
- **换行**:投影文件默认 LF(可通过 `profile.yaml` 的 `projection.line_ending: crlf` 修改);SoT 内部素材统一 LF,换行差异由投影层吸收,不会造成虚假 diff。
|
|
398
|
-
- **离线**:无网络环境完全可用(init/sync/template/skill 等纯本地操作)。git 源的 `source update` 需要网络,离线时明确报错(退出码 5)。也可设 `AGF_OFFLINE=1` 显式声明离线意图,让需要网络的操作尽早失败。
|
|
399
|
-
- **权限**:**无需 Administrator**。全部文件读写都在你的用户目录与项目目录内;写失败时给出可操作的修复提示(退出码 4)。
|
|
400
|
-
- **控制台编码**:非交互命令输出为纯 ASCII(GBK 代码页 `chcp 936` 下不乱码);`init -i` 的交互 UI 需要真实终端(TTY)。
|
|
401
|
-
|
|
402
|
-
### 环境变量
|
|
403
|
-
|
|
404
|
-
| 变量 | 作用 |
|
|
405
|
-
|------|------|
|
|
406
|
-
| `AGF_SCOPE` | 缺省 scope(`project` / `user`) |
|
|
407
|
-
| `AGF_HOME` | 覆盖用户级 SoT 根目录 |
|
|
408
|
-
| `AGF_LINE_ENDING` | 覆盖投影换行风格(`crlf` / `lf`) |
|
|
409
|
-
| `AGF_OFFLINE` | 设为 `1` 声明离线模式 |
|
|
410
|
-
|
|
411
|
-
## 退出码约定
|
|
412
|
-
|
|
413
|
-
| 码 | 含义 |
|
|
414
|
-
|----|------|
|
|
415
|
-
| 0 | 成功 |
|
|
416
|
-
| 2 | 配置错误(未初始化、非法参数、非 TTY 环境跑交互命令等) |
|
|
417
|
-
| 3 | 冲突(marker 区间被手改,拒绝覆盖) |
|
|
418
|
-
| 4 | 权限错误(目标不可写) |
|
|
419
|
-
| 5 | 离线(需要网络的操作在离线模式下失败) |
|
|
420
|
-
|
|
421
|
-
## 已知限制
|
|
422
|
-
|
|
423
|
-
- **并发安全**:多进程并发执行 `aforge sync` 或 `aforge source add` 等行为未定义。建议避免并发操作同一 SoT 目录(`.agentforge/`)。如需自动化调度,请确保串行执行。
|
|
424
|
-
- **Symlink 支持**:`skills/` 目录恒使用实体拷贝,不使用 symlink。`profile.skills.copy_mode` 虽然接受 `symlink`,但 MVP 忽略该值(symlink 属 Phase 2)——声明 `symlink` 时 `aforge doctor` 会告警提示"当前恒为实体 copy",投影结果不受影响;`skills/` 下已存在的断开 symlink 也会被 doctor 检出。
|
|
425
|
-
|
|
426
|
-
## macOS / Linux 旁注
|
|
427
|
-
|
|
428
|
-
- 首选装法与 Windows 一致:`npx -y @zythegit/agentforge@latest`(或 `npm i -g`);
|
|
429
|
-
- 从源码构建:`fnm env --shell bash | source -`(或 zsh)后 `npm install` + `npm run build:node`;
|
|
430
|
-
- 用户级 SoT 在 `$HOME/.agentforge`;投影换行默认规则同 Windows(profile 可配置);
|
|
431
|
-
- `npm run build:bun` 自动按当前平台选 target,`build:bun:all` 一次交叉编译五平台;
|
|
432
|
-
- macOS 二进制未签名未公证,见上文「方式二」的 `xattr` 说明。
|
|
433
|
-
|
|
434
|
-
## 开发
|
|
435
|
-
|
|
436
|
-
```powershell
|
|
437
|
-
fnm env --shell power-shell | Out-String -Stream | Invoke-Expression
|
|
438
|
-
fnm use 22
|
|
439
|
-
npm install
|
|
440
|
-
npm test # 全量测试(vitest)
|
|
441
|
-
npm run typecheck # tsc --noEmit
|
|
442
|
-
npm run build # 双轨构建(node + bun)
|
|
443
|
-
```
|
|
99
|
+
## 文档
|
|
444
100
|
|
|
445
|
-
|
|
101
|
+
- [命令速查与约定](docs/commands.md)——14 个命令、`--json` 契约、环境变量、退出码
|
|
102
|
+
- [安装与构建](docs/install.md)——三种装法、双轨构建、开发命令
|
|
103
|
+
- [技能](docs/skills.md)——登记来源、安装、投影落点与调用前缀,以及 `expose_as_command` 命令薄壳(命名空间、`$1..$9`)
|
|
104
|
+
- [MCP](docs/mcp.md)——一份声明翻译成四家的原生配置
|
|
105
|
+
- [learning](docs/learning.md)——`learn` / `promote` 闭环与 `auto_capture`
|
|
106
|
+
- [迁移 SoT](docs/bundle.md)——`bundle export/import` 换机器、备份
|
|
107
|
+
- [平台注意事项与已知限制](docs/platform.md)——Windows 路径 / 换行 / 编码,并发与 symlink 边界,尚未实现的字段
|
|
108
|
+
- 规格与需求:[AgentForge-Spec.md](AgentForge-Spec.md)、[AgentForge-PRD.md](AgentForge-PRD.md)
|
|
446
109
|
|
|
447
110
|
---
|
|
448
111
|
|
|
449
|
-
|
|
112
|
+
*版本以 git tag 为唯一来源(`v*` tag → npm 包版本 + Release 资产),本机版本用 `aforge --version` 查。*
|