diff --git a/docs/architecture.md b/docs/architecture.md index 9f5be95d3..1224eae8b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -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//config.json ``` @@ -125,7 +125,7 @@ const p = join(nodesDir(), id, "config.json"); // .anet/nodes//config.json > 上例是 `anet node create 开发马 --runtime claude-agent-sdk --model `(已登录)实际生成的最小集。条件字段:`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 = { anet_version, node_id, node_name, runtime, @@ -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 @@ -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 [--hub ] @@ -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`) ``` {项目}/ @@ -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`。 --- @@ -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//config.json` 不应包含 token(放全局配置;R222 chain 说明项目 config 用 hub/token 字段覆盖全局是 advanced use case) - `.anet/` 应加入 `.gitignore` 防止提交 @@ -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 diff --git a/docs/design-auth-network.md b/docs/design-auth-network.md index 782f1525e..392bb99c8 100644 --- a/docs/design-auth-network.md +++ b/docs/design-auth-network.md @@ -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 拦住),缺的是更细的角色/归属门控 diff --git a/docs/node-lifecycle.md b/docs/node-lifecycle.md index e3b0d958b..97f25cb7c 100644 --- a/docs/node-lifecycle.md +++ b/docs/node-lifecycle.md @@ -169,9 +169,9 @@ register() → callCommHub("report_status", { **触发**: `anet node rename ` [`--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(顺序敏感)**: @@ -199,18 +199,18 @@ register() → callCommHub("report_status", { **触发**: `anet node delete ` (首次提示,再加 `--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//, { 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 指挥室 @@ -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) { diff --git a/docs/pitfalls.md b/docs/pitfalls.md index 78d34763d..b84baef0a 100644 --- a/docs/pitfalls.md +++ b/docs/pitfalls.md @@ -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/...` 全局安装路径兜底 diff --git a/docs/rfcs/RFC-002-channel-bind-cli.md b/docs/rfcs/RFC-002-channel-bind-cli.md index a5978e87e..0ba2b9837 100644 --- a/docs/rfcs/RFC-002-channel-bind-cli.md +++ b/docs/rfcs/RFC-002-channel-bind-cli.md @@ -34,7 +34,7 @@ anet channel add telegram 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//channels/telegram/` 落两份配置: