Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ for await (const message of query({ prompt, options })) { /* ... */ }
默认值(hub=http://127.0.0.1:9200, runtime=claude-agent-sdk)
```

verify [`cli.ts:228 loadProfile`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts):
verify [`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function loadProfile(`:
```ts
const p = join(nodesDir(), id, "config.json"); // .anet/nodes/<id>/config.json
```
Expand Down Expand Up @@ -125,7 +125,7 @@ const p = join(nodesDir(), id, "config.json"); // .anet/nodes/<id>/config.json

> 上例是 `anet node create 开发马 --runtime claude-agent-sdk --model <id>`(已登录)实际生成的最小集。条件字段:`teammateMode`(仅 `claude-code-cli`)、`session`(仅 `claude-code-cli` 或 `--session`)、`maxTurns`(仅 `--max-turns`)、`tools`(仅 `--tools`);`logLevel` 是 **top-level** 字段(不在 `flags` 里),且 `createCommand` 不写它(用户可选加)。

verify [`cli.ts:246-273 saveProfile`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts):
verify [`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function saveProfile(`:
```ts
const toSave: Record<string, any> = {
anet_version, node_id, node_name, runtime,
Expand Down Expand Up @@ -195,7 +195,7 @@ anet server [--port 9200] [--token xxx] [--db path] [--cors origins]

### `anet setup`

R511 校准:旧 doc 写「`anet setup --hub --alias --type`,配置新 Agent 加入网络」是 V2 早期签名 —— 当前 `anet setup`([`cli.ts:556 setupCommand`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts))是**交互式 runtime 依赖安装器**,不带参数,也不写网络配置(入网走 `anet node create`)。
R511 校准:旧 doc 写「`anet setup --hub --alias --type`,配置新 Agent 加入网络」是 V2 早期签名 —— 当前 `anet setup`([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `async function setupCommand(`)是**交互式 runtime 依赖安装器**,不带参数,也不写网络配置(入网走 `anet node create`)。

```bash
anet setup
Expand All @@ -211,7 +211,7 @@ anet setup

### `anet run`

R511 校准:旧 doc 写的 `[--handler script.ts]` flag + 「handler 协议」是 V2 设计草稿,**当前不存在**。当前 `anet run`([`cli.ts:2044 runCommand`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts))是用 Client SDK 起的**极简 standalone SSE agent**:连 hub、监听 task、自动 echo「收到」回复 —— **不跑 LLM**,区别于 `anet node start`(跑真实 AI runtime)。
R511 校准:旧 doc 写的 `[--handler script.ts]` flag + 「handler 协议」是 V2 设计草稿,**当前不存在**。当前 `anet run`([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `async function runCommand(`)是用 Client SDK 起的**极简 standalone SSE agent**:连 hub、监听 task、自动 echo「收到」回复 —— **不跑 LLM**,区别于 `anet node start`(跑真实 AI runtime)。

```bash
anet run --alias <name> [--hub <url>]
Expand Down Expand Up @@ -313,11 +313,11 @@ await startServer({

## 5. Channel 插件自动配置 — R221 校准

`anet node start` 检测到 `runtime: "claude-code-cli"` 时,自动确保 Channel 插件可用([`cli.ts:1644 ensureMcpJson`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts)):
`anet node start` 检测到 `runtime: "claude-code-cli"` 时,自动确保 Channel 插件可用([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function ensureMcpJson(`):

1. 从 npm 包 (`dist/src/node-server.js` 优先 / `src/node-server.ts` 兜底) 复制到 `{项目}/.anet/node-server.js`(**注意:是 `.js` 不是 `.ts`** —— [R216 chain](https://github.com/sleep2agi/agent-network/issues/10#issuecomment-4438192170))
2. 安装依赖(`@modelcontextprotocol/sdk ^1.12.0` 通过 `bun install`)
3. 写入 `.mcp.json`:`commhub → .anet/node-server.js`([cli.ts:1724](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts))
3. 写入 `.mcp.json`:`commhub → .anet/node-server.js`([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `.mcp.json: commhub → .anet/node-server.js`

```
{项目}/
Expand All @@ -327,9 +327,9 @@ await startServer({
└── package.json # @modelcontextprotocol/sdk ^1.12.0
```

已配置过且内容一致直接跳过(compare-by-content:`if (src !== dst) writeFileSync(...)`,[cli.ts:1679-1680](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts))。`anet init project` 也做同样的事(另外还写 CLAUDE.md)。
已配置过且内容一致直接跳过(compare-by-content:`if (src !== dst) writeFileSync(...)`,[`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `if (src !== dst)`)。`anet init project` 也做同样的事(另外还写 CLAUDE.md)。

R221 校准:原 doc 写「`runtime: "claude-code"`」+「`.anet/node-server.ts`」+「`.mcp.json args:[".anet/node-server.ts"]`」三处都是 V2 早期命名/文件名,当前 runtime name 是 `claude-code-cli`([RuntimeName type cli.ts:145](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts)),落盘文件名是 `.js`。
R221 校准:原 doc 写「`runtime: "claude-code"`」+「`.anet/node-server.ts`」+「`.mcp.json args:[".anet/node-server.ts"]`」三处都是 V2 早期命名/文件名,当前 runtime name 是 `claude-code-cli`(RuntimeName type —— 已移出 cli.ts,现在在 [`agent-network/src/normalize-runtime.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/src/normalize-runtime.ts),搜 `export type RuntimeName =`),落盘文件名是 `.js`。

---

Expand Down Expand Up @@ -447,9 +447,9 @@ R223 校准:旧 doc 只写 `bun build src/client.ts bin/cli.ts --outdir dist -
- ⚠️ 旧 `COMMHUB_AUTH_TOKEN` 仅 `/api/*` 读类兼容(v1.0 移除)

### 配置安全 — R223 校准
- `~/.anet/server/admin-utok.json` 自动 chmod 600([`cli.ts:105-111 saveAdminUtok`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) `writeFileSync(..., {mode: 0o600})` + `chmodSync(..., 0o600)`,v0.8 bootstrap 写入 admin token)
- `~/.anet/server/config.json` 自动 chmod 600([`cli.ts:89-95 saveServerConfig`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts))
- ⚠️ `~/.anet/config.json` **不是 600** —— [`cli.ts:77-81 saveGlobal`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) 用默认 `writeFileSync` 无 mode 选项,实际权限通常 `644` (`rw-r--r--`)。在多用户机器上其他本地用户可读你的 utok_。**单用户 host 影响有限,多用户共享 host 建议手动 `chmod 600 ~/.anet/config.json`**(v0.9 RFC 待修)
- `~/.anet/server/admin-utok.json` 自动 chmod 600([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function saveAdminUtok(` `writeFileSync(..., {mode: 0o600})` + `chmodSync(..., 0o600)`,v0.8 bootstrap 写入 admin token)
- `~/.anet/server/config.json` 自动 chmod 600([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function saveServerConfig(`
- ⚠️ `~/.anet/config.json` **不是 600** —— [`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function saveGlobal(` 用默认 `writeFileSync` 无 mode 选项,实际权限通常 `644` (`rw-r--r--`)。在多用户机器上其他本地用户可读你的 utok_。**单用户 host 影响有限,多用户共享 host 建议手动 `chmod 600 ~/.anet/config.json`**(v0.9 RFC 待修)
- 项目 `.anet/nodes/<alias>/config.json` 不应包含 token(放全局配置;R222 chain 说明项目 config 用 hub/token 字段覆盖全局是 advanced use case)
- `.anet/` 应加入 `.gitignore` 防止提交

Expand Down Expand Up @@ -521,7 +521,7 @@ R256 校准:旧 doc 用 `send_task(hub, result)` 回复任务结果 —— 这

## 10. Web Dashboard

> **R220 校准(2026-05-13)**:本节的「内置轻量 UI」+「`http://YOUR_IP:9200/dashboard`」是 V2 早期设计草稿,**v0.8 实际未实现** —— commhub-server `server/src/index.ts` 没有 `/dashboard` 路由([全 source grep `/dashboard` 0 hit](https://github.com/sleep2agi/agent-network/blob/main/server/src/index.ts))。当前**唯一 Dashboard 是独立的 Next.js 包 `@sleep2agi/agent-network-dashboard`**,通过 `anet hub dashboard` 子命令拉起([`agent-network/bin/cli.ts:2386`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) `sub === "dashboard"` 分支,默认端口 3000;版本不再 hardcode pin —— [`dashboardReleaseTag()` cli.ts:347](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) 默认拉 `@preview` tag,可用 `ANET_DASHBOARD_VERSION` env 覆盖,跟 anet release channel 对齐 — 见 #61)。最新部署方式见 [anet.sh/guide/dashboard](https://anet.sh/guide/dashboard)。下面的「两种 Dashboard」/「内置 UI 设计原则」/「实现方案」/「HTML 结构」全是 V2 设计草稿,仅保留历史背景,**当前不适用**。
> **R220 校准(2026-05-13)**:本节的「内置轻量 UI」+「`http://YOUR_IP:9200/dashboard`」是 V2 早期设计草稿,**v0.8 实际未实现** —— commhub-server `server/src/index.ts` 没有 `/dashboard` 路由([全 source grep `/dashboard` 0 hit](https://github.com/sleep2agi/agent-network/blob/main/server/src/index.ts))。当前**唯一 Dashboard 是独立的 Next.js 包 `@sleep2agi/agent-network-dashboard`**,通过 `anet hub dashboard` 子命令拉起([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) `sub === "dashboard"` 分支,默认端口 3000;版本不再 hardcode pin —— [`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function dashboardReleaseTag(` 默认拉 `@preview` tag,可用 `ANET_DASHBOARD_VERSION` env 覆盖,跟 anet release channel 对齐 — 见 #61)。最新部署方式见 [anet.sh/guide/dashboard](https://anet.sh/guide/dashboard)。下面的「两种 Dashboard」/「内置 UI 设计原则」/「实现方案」/「HTML 结构」全是 V2 设计草稿,仅保留历史背景,**当前不适用**。

### 当前 Dashboard

Expand Down
2 changes: 1 addition & 1 deletion docs/design-auth-network.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
> - 首个用户自动 admin
> - users.plan 字段 + networks.visibility/max_members 字段
> - **RFC-001 Phase 1**:COMMHUB_AUTH_TOKEN 软废弃,仅 `/api/*` 只读 + deprecation warning
> - **RFC-001 Phase 2**:admin utok_ bootstrap(`~/.anet/server/admin-utok.json` chmod 600,R224 校准:实际路径是 `~/.anet/server/` 不是 `~/.commhub/`,verify [`cli.ts:28 adminUtokPath`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L28))、`anet passwd` / `anet hub admin reset-user`、密码强度 ≥ 8 + 弱密码字典、`anet doctor --fix` 探测并重发 ntok_
> - **RFC-001 Phase 2**:admin utok_ bootstrap(`~/.anet/server/admin-utok.json` chmod 600,R224 校准:实际路径是 `~/.anet/server/` 不是 `~/.commhub/`,verify [`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function adminUtokPath(`)、`anet passwd` / `anet hub admin reset-user`、密码强度 ≥ 8 + 弱密码字典、`anet doctor --fix` 探测并重发 ntok_
>
> ❌ 未实现(目标态,排到 v0.9+):
> - MCP 写操作的**细粒度**网络角色检查 —— `canWrite` (tools.ts:24 `role !== "viewer"`) 只挡 viewer,owner/admin/member 一视同仁;且**无 per-task ownership 检查**(member 能 cancel/reassign 网络里任何任务,不限自己派的)。注:viewer 已经**不能** send_task(canWrite 拦住),缺的是更细的角色/归属门控
Expand Down
12 changes: 6 additions & 6 deletions docs/node-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ register() → callCommHub("report_status", {

**触发**: `anet node rename <old> <new>` [`--force`]

**前置条件**: rename 需要 hub + token + network_id(`anet login` 后才有,缺则 `process.exit(1)`)。运行中的 node **必须加 `--force`** —— [`cli.ts:2629-2631 renameCommand`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L2629) 检测到 `.pid` 进程存活且没 `--force` 时直接退出;运行中改名走 RFC-010 §4.4 active rename,**不杀进程**。
**前置条件**: rename 需要 hub + token + network_id(`anet login` 后才有,缺则 `process.exit(1)`)。运行中的 node **必须加 `--force`** —— [`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `async function renameCommand(` 检测到 `.pid` 进程存活且没 `--force` 时直接退出;运行中改名走 RFC-010 §4.4 active rename,**不杀进程**。

**RFC-010 两阶段事务** —— R481 校准:旧 doc 的「P0 只改本地 `renameSync` + P1 CommHub rename API 未采纳」已过时,当前 [`cli.ts:2583-2721 renameCommand`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L2583) 实现的是带 CommHub 协同的两阶段事务:
**RFC-010 两阶段事务** —— R481 校准:旧 doc 的「P0 只改本地 `renameSync` + P1 CommHub rename API 未采纳」已过时,当前 [`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `async function renameCommand(` 实现的是带 CommHub 协同的两阶段事务:

- **PHASE 1 — PREPARE(全程可回滚,old node 原封不动)**:写 `rename.lock` → `cpSync(oldDir → newDir)`(**copy 不是 move**)→ 更新 `newProfile.node_name` / `alias` + `saveProfile` → POST `/api/node-rename/prepare` 拿 `txn_id`。任一步失败 → 回滚(删 newDir + POST `/api/node-rename/abort` + 删 lock),`old` 完全不变。
- **PHASE 2 — COMMIT(顺序敏感)**:
Expand Down Expand Up @@ -199,18 +199,18 @@ register() → callCommHub("report_status", {

**触发**: `anet node delete <node-name>` (首次提示,再加 `--force` 才真删)

**前置条件**: 不强制 offline —— `anet node delete` 会先 `stopNode(nodeId)` 杀进程 + `await notifyServerOffline(...)` 通知 hub 后再删本地目录([cli.ts:2800-2840 deleteCommand](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L2800))。
**前置条件**: 不强制 offline —— `anet node delete` 会先 `stopNode(nodeId)` 杀进程 + `await notifyServerOffline(...)` 通知 hub 后再删本地目录([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `async function deleteCommand(`)。

**实际数据变更**:
1. **本地**: `rmSync(.anet/nodes/<id>/, { recursive: true, force: true })` —— 删整个目录(含 config.json、channels/、logs/;目录名是 alias / node_name,不是内部 node_id 字段;R209 chain 一致)
2. **CommHub session**: `notifyServerOffline` 调用 `report_status(offline)`([cli.ts:2725-2750](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L2725))—— **只把 sessions row.status 改成 offline,不 DELETE**。这一行 session 会一直留在 db 里(10 分钟 stale cutoff 触发时也只是再次 mark offline)。
2. **CommHub session**: `notifyServerOffline` 调用 `report_status(offline)`([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `async function notifyServerOffline(`)—— **只把 sessions row.status 改成 offline,不 DELETE**。这一行 session 会一直留在 db 里(10 分钟 stale cutoff 触发时也只是再次 mark offline)。
3. **CommHub inbox**: **不清理** —— 残留 inbox 消息会一直留着。如果之后用同 alias 再 `anet node start`,新进程会从 `getInbox` 拉到旧消息(注意:旧消息可能跟新进程 session 上下文无关)。

::: warning 旧 doc P1 设计未采纳
原 doc 写「DELETE FROM sessions / DELETE FROM inbox」是设计草稿意图,**未实施**。实际只 mark offline + 删本地目录,不清服务端 row(v0.8.2 起验证,至当前 stable 未变)。
:::

**确认流程**([cli.ts:2831-2835](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L2831)):
**确认流程**([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `This will delete "${displayName}" (node_id:`):

```
$ anet node delete 指挥室
Expand Down Expand Up @@ -380,7 +380,7 @@ anet node rename 指挥室 总指挥

### anet 识别 node 的逻辑

实际函数名 `resolveNodeRef`([`cli.ts:198`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L198)):
实际函数名 `resolveNodeRef`([`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `function resolveNodeRef(`):

```typescript
function resolveNodeRef(ref: string) {
Expand Down
2 changes: 1 addition & 1 deletion docs/pitfalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ if (src !== dst) {
}
```

verify [`agent-network/bin/cli.ts:1658-1674`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L1658) `candidates` 数组:源文件搜索顺序为
verify [`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `// dist/src/node-server.js(npm 包混淆后产物,优先)` `candidates` 数组:源文件搜索顺序为
1. `dist/src/node-server.js`(npm 包混淆后产物,优先)
2. `src/node-server.ts`(开发环境源码)
3. `npm root -g/@sleep2agi/agent-network/...` 全局安装路径兜底
Expand Down
2 changes: 1 addition & 1 deletion docs/rfcs/RFC-002-channel-bind-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ anet channel add telegram <node-id>
anet channel ls [node-id]
```

参考实现:[`agent-network/bin/cli.ts:2685-2788`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts#L2685)
参考实现:[`cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-network/bin/cli.ts) —— 搜 `async function channelCommand(`

效果:
- 在 `.anet/nodes/<node-id>/channels/telegram/` 落两份配置:
Expand Down
Loading