Conversation
- 新增统一 ResourceProvider、capability、registry 与故障隔离调度,并将现有 Git source 接入同一同步生命周期。 - 将 ClawPro 协议实现迁入独立 HTTP adapter,保留 local-agent 兼容门面和旧版 HTTP 初始化路径。 - 支持多个具名 HTTP Provider;配置、凭据、绑定、manifest、插件、缓存与日志均按 Provider 隔离,凭据使用 0600 权限单独保存。 - 增加 provider add/list/sync/remove/set-primary/migrate-legacy 命令,push 校验可写目标,并为旧 source HTTP 命令保留带弃用提示的兼容入口。 - 为 Git 同名 skill 增加 priority 选择与来源删除回退;通过 2928 项单元测试、3 项 E2E、构建及双 HTTP 后端真实 CLI 验证。
- HTTP Provider 按优先级从低到高同步,确保冲突资源最终由最高优先级的成功来源生效。 - 在 set-primary 时直接拒绝不可写的 HTTP Provider 与 Git 订阅源。 - 增加多 HTTP Provider 调度顺序的端到端覆盖,并通过类型检查和定向回归测试。
|
这个改动比较复杂,需要做时间更久的 review 和 端到端验证。 |
|
|
||
| // Existing ~/.teamai/local-agent installs remain live throughout migration. | ||
| let legacyOutput: string | null = null; | ||
| if (await loadLocalAgentConfig()) legacyOutput = await reportAndSyncFromHook(stdin, tool); |
There was a problem hiding this comment.
[阻塞] 命名 provider 与遗留单例会在每次 hook 重复上报/同步
syncHttpProvidersFromHook 跑完所有命名 provider 后,只要 loadLocalAgentConfig() 非空就无条件再跑一次遗留路径:
if (await loadLocalAgentConfig()) legacyOutput = await reportAndSyncFromHook(stdin, tool);main 上每次 hook 只 dispatch 单例一次;本 PR 变成两次——命名后端 + 遗留后端各收到一轮 report+sync+get-config,且遗留(未 scope)快照会覆盖写盘。
触发条件(任一即中):
~/.teamai/local-agent/config.json存在且无migrated-to标记;~/.teamai/config.yaml为kind: http——正是init.ts:369里init --http写的,所以「先init --http后provider add http」必中;- 设了
TEAMAI_HTTP_ENDPOINT/TEAMAI_ENDPOINT/TEAMAI_API_BASE_URL。
client.ts:575 的 migrated-to 护栏只覆盖条件 1,且 migrate-legacy 只往 local-agent/ 写标记、从不清理 config.yaml 的 kind: http,条件 2 会一直重复。本 PR 自带的 http-provider-multi-e2e 里那行无 [provider:*] 前缀的 sync FAILED: 未登录,就是这条遗留路径真实打到后端的证据。
建议:注册了命名 HTTP provider 时,若其 endpoint 与遗留单例相同则按 endpoint 去重跳过遗留路径;或把 backfill / env 两条 fallback 也纳入迁移标记门控,而不只是 local-agent/ 目录那条。
已本地复现(回归测试 + 隔离子进程各一,均能稳定重现重复 /sync)。
| ...(await listHttpProviderConfigs()).map((item) => item.name), | ||
| ]); | ||
| if (!names.has(name)) throw new Error(`Resource provider "${name}" was not found.`); | ||
| if (name !== 'main' || !writableMain) { |
There was a problem hiding this comment.
[建议] provider set-primary <name> 实际只接受 main,命令签名有误导
providerSetPrimary 中 if (name !== 'main' || !writableMain) throw,任何非 main 目标都被拒;getPrimaryProvider 也只被 push 消费,而 push 同样硬编码只认 main(push.ts:283)。等于当前整套 primary 机制只能表达 "main" 一个值,但命令签名 set-primary <name> 却接收任意 <name>,用户会以为能把命名 provider 设为主。
建议:要么在 help/文档里注明「当前仅 main 可写、可作 primary」,要么明确标注这是 #404 后续 PR 的前置桩,避免误导。
现有 ClawPro HTTP 分发以全局
local-agent单例存在,和 Git source 使用不同生命周期,无法安全挂载多个后端。本 PR 引入统一ResourceProvider、capability、registry 与故障隔离调度,并将 ClawPro 协议实现迁入独立 HTTP adapter。主要行为:
local-agent、repo.kind: http和 source HTTP 命令的迁移兼容路径。#404 中跨 HTTP Provider 的持久 ownership ledger,以及删除 active HTTP 来源后的全资源类型自动回退仍适合在后续小 PR 中完成,因此这里引用 issue,不自动关闭。
验证:
npm run typechecknpm run buildRefs #404