# TeamAI CLI — 团队接入与使用指南 > [English](usage-guide.md) | [简体中文](usage-guide.zh-CN.md) > **teamai-cli** — AI Agents 的团队协作层 > > **让每个团队通过 AI 持续变得更聪明。** 统一工作方式(Team Execution)、共享团队 Context(Team Context),并把真实 Session 沉淀成团队能力(Team Improvement)。TeamAI 统一管理 Claude Code、Codex、CodeBuddy、WorkBuddy、OpenCode、Cursor 及其他受支持 Agent 的 Skills、Rules、Docs、Env、MCP 等资源。 --- ## 目录 - [TeamAI 是什么](#teamai-是什么) - [核心概念](#核心概念) - [安装](#安装) - [管理员初始化](#管理员初始化) - [项目级(Project Scope)](#项目级project-scope) - [用户级(User Scope)](#用户级user-scope) - [如何选择 Scope?](#如何选择-scope) - [单仓模式(业务仓即团队仓)](#单仓模式业务仓即团队仓) - [在项目仓库下叠加组织级仓库](#在项目仓库下叠加组织级仓库) - [成员接入](#成员接入) - [日常使用](#日常使用) - [共享团队资源](#共享团队资源) - [知识沉淀与检索](#知识沉淀与检索) - [知识库健康报告](#知识库健康报告) - [提交 Co-Author 署名](#提交-co-author-署名) - [团队文化](#团队文化) - [进阶功能](#进阶功能) - [配置文件参考](#配置文件参考) - [卸载](#卸载) - [常见问题 FAQ](#常见问题-faq) --- ## TeamAI 是什么 Agent 作为个人工具已经很强,但学到的东西留在个人手里:昨天某位成员的 Agent 摸索出来的结论,今天到不了其他人的 Agent 面前。 TeamAI 的产品是一条闭环,而不是三个独立产品: | 层 | 要解决的问题 | 在本 CLI 中怎么用 | |----|--------------|-------------------| | **Team Execution** | 让每个 Agent 按团队的方式工作 | `init` / `pull` / `push` 共享 Harness(skills、rules、agents、hooks、MCP、env) | | **Team Context** | 让每个 Agent 理解整个团队 | recall、docs、learnings、代码知识图谱 | | **Team Improvement** | 让每一次执行都成为团队能力的积累 | 基于摩擦信号的经验分享、sessions、digest | **Execute → Understand → Learn → Self-Improve。** 从 Harness 分发起步;Context 与 Improvement 随团队真实使用 Agent 而加深。 --- ## 核心概念 | 概念 | 说明 | |------|------| | **Team Repo** | 一个 Git 仓库,集中存放团队 Harness 与知识(Skills / Rules / Docs / Env / Packages,以及 learnings、wiki) | | **Scope** | 资源安装位置:`project`(当前项目,默认)或 `user`(用户主目录)| | **Team Execution** | 一份共享 Harness,分发到每位成员的 Agent | | **Team Context** | 可检索的团队知识,避免 Agent 每次 Session 从零理解团队 | | **Team Improvement** | 把 Session 摩擦与用量信号转化为新的 Skill、Rule 和知识 | | **Skills** | AI 可调用的自定义技能(目录形式,含 `SKILL.md`) | | **Rules** | Markdown 格式的团队规范,自动合并到 AI 工具配置中 | | **Docs** | 团队共享文档,供 AI 参考 | | **Env** | 团队共享环境变量,自动注入 shell | | **Packages** | 全团队统一的 npm 包和 Claude Code 插件,通过 `teamai packages` 主动安装 | ``` ┌───────────────┐ teamai push (MR) ┌───────────────────┐ │ 你的本地资源 │ ──────────────────────→ │ Team Repo (Git) │ │ skills/rules │ │ skills/rules/docs │ └───────────────┘ ←────────────────────── └───────────────────┘ teamai pull (自动) │ ▼ ┌──────────────────┐ │ AI 工具自动获取 │ │ Claude / CodeBuddy│ │ Cursor / Codex │ └──────────────────┘ ``` --- ## 安装 ```bash npm install -g teamai-cli # 验证 teamai --version ``` **前置依赖:** Node.js ≥ 20、Git(TGit 用户还需 `gf` CLI、CNB 用户还需 `cnb` CLI,`teamai init` 时都会自动安装) --- ## 管理员初始化 > 只需一位管理员完成,其他成员跳到[成员接入](#成员接入)。 在 GitHub、GitLab(gitlab.com 或自建实例)、GitCode(gitcode.com)、CNB(cnb.cool)、TGit,或任意私有/自建 Git 服务上创建一个空仓库(命名建议:`TeamAi-<团队名>`)。对于支持自动建仓的 provider,也可直接执行 `teamai init`,按提示创建尚不存在的仓库。 使用自建 GitLab 时,先配置实例地址和具有 `api` 权限的 Personal Access Token: ```bash export GITLAB_URL=https://git.example.com export GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxx teamai init https://git.example.com/yourgroup/yourrepo ``` 对于未知 host,`init` 会匿名检查 GitLab 登录页,总超时为三秒。确认是 GitLab 后,会在认证、克隆或写入配置前停止,提示设置实例地址和 token 后重试。探测不发送 token,也不跟随重定向。无法确认时,初始化继续使用通用 `git` provider;它支持 Git 传输,但不能自动建仓或创建 PR/MR。实例若由 SSO 遮蔽、部署在子路径下,或无法被探测访问,请显式设置 `GITLAB_URL`。 **已经初始化为 `provider: git`?** 设置上述环境变量,并把团队仓库 `teamai.yaml` 中的 `provider` 改为 `gitlab`。仅设置环境变量不会改变已有 provider 选择。失败的 `teamai push` 可能已经推送了分支;若其诊断探测到 GitLab,会输出这些修复步骤。详见 [Provider 配置](providers.md#gitlab-provider含自托管)。 ### 项目级(Project Scope,默认) 资源安装到项目目录下(`/.claude/skills/` 等),适用于项目特定的技能和规则。 ```bash # project 是默认值,可省略 --scope cd /path/to/my-project teamai init https://github.com/yourorg/yourrepo # 等价别名:teamai init --repo https://github.com/yourorg/yourrepo ``` 生成的目录结构: ``` /path/to/my-project/ # 你的业务仓库 —— 零 teamai 残留 ├── .claude/skills/ # 项目级 skills(自动同步) ├── .claude/rules/ # 项目级 rules(自动同步) └── src/ ~/.teamai/projects/my-project-/ # 本项目的机器数据分区 ├── config.yaml ├── state.json └── team-repo/ # 团队仓库克隆 ``` 项目的机器数据(config、state、team-repo 克隆、搜索索引、MCP manifest、资源缓存) 存放在 `~/.teamai/projects//` 下的按项目分区里,**不再**放进业务仓库,因此工作区 无 teamai 残留,且同一仓库的 `git worktree` 共享同一分区。各 Agent 的项目根目录 (`.claude/`、`.cursor/`、`.codebuddy/` 等)仍在工作区内、于 **SessionStart** 时按刚打开的 工具创建。例如,打开 Claude Code 时会创建 `.claude/`,再由 pull 写入。单独执行 `teamai pull` 仍会跳过项目里还不存在根目录的工具,因此不会给尚未在本项目打开过的 Agent 凭空建目录。 > **从旧版 teamai 升级?** 升级后首次执行 `teamai init` / `pull` / `push` 会自动把已有的 > `/.teamai/` 迁移进分区(复制 → 校验 → 原子切换),并把旧目录保留为 > `/.teamai.bak/`,待你确认一切正常后自行删除。只读命令与 `hook-dispatch` 路径 > 永不触发迁移;`teamai --dry-run pull` 可预演。**迁移后不支持降级**——旧版会把项目判定为 > 未初始化;`.teamai.bak/` 是人工回滚路径。 如果仓库启用了角色化 skills(存在 `manifest/roles.yaml`),`teamai init` 还会交互式要求你选择: - `primaryRole`:默认 skill 同步和推送的目标 namespace - `additionalRoles`:额外需要同步的 skill namespace 也可以通过 CLI 参数跳过交互,实现完全非交互式初始化(适合 CI/CD 或 AI agent): ```bash teamai init https://github.com/yourorg/yourrepo --scope project --role hai_dev --force ``` | 参数 | 说明 | |------|------| | `[repo]` / `--repo ` | 团队仓库地址(推荐位置参数;`--repo` 为永久别名) | | `--scope ` | 安装作用域,默认 `project`(机器数据在 `~/.teamai/projects//`,资源落在 ``)。需要装到 `~/` 时用 `user` | | `--inherit-user-scope` | 仅 project scope:同时同步安全的 user 资源并检索 user 知识 | | `--no-inherit-user-scope` | 关闭当前项目先前配置的 user scope 继承 | | `--role ` | 直接指定 primaryRole,跳过角色交互选择 | | `--project ` | 从 `manifest/projects.yaml` 激活的逻辑项目(逗号分隔)。决定本目录同步哪些项目的资源与 learnings。详见下方 [多项目](#多项目project-作为与-role-正交的维度) | | `--force` | 覆盖已有配置,跳过确认提示 | #### 多项目:`project` 作为与 `role` 正交的维度 当一个团队仓库承载多个项目时,`project` 是与 `role` 平级的第二个分发维度,由 admin 在 `manifest/projects.yaml` 中声明。`role` 回答「我的职能是什么」,`project` 回答「这个目录属于哪个项目」。两者正交且相加 —— 成员得到的是其 role namespace 与激活 project namespace 的**并集**(两者之间没有覆盖关系)。 项目身份跟着工作目录走,与 `--role` 完全同一个模式: ```bash cd ~/work/hai-inference && teamai init --project hai-inference cd ~/work/billing && teamai init --project billing ``` 此后每个目录只同步自己项目的 skills/rules/CLAUDE.md 与 learnings。要点: - **learnings 隔离。** 仓库 `learnings/` 根目录对全团队共享;项目私有经验放在 `learnings//` 子目录下,只对该项目成员的 `teamai recall` 可见。 未激活任何项目的目录只能看到共享的根目录。 - **不自动激活。** 与「唯一 role 会被自动选中」不同,唯一的 project 不会自动选中 —— 成员可以不属于任何项目(仍能获得 `common` 与共享的 learnings 根)。 - **向后兼容。** 没有 `manifest/projects.yaml` 的仓库行为与之前完全一致;现存扁平 的 `learnings/*.md` 继续对所有人共享(零迁移)。 - **`teamai contribute`** 在恰好激活一个项目时,把经验落到该项目子目录,否则落到 共享的根目录。 `manifest/projects.yaml` 示例: ```yaml version: 1 projects: - id: hai-inference name: HAI Inference resources: knowledge: [hai-inference] skills: [hai-inference] learnings: [hai-inference] ``` **命令**(低频的事后修正与查询,对标 `teamai roles …`): ```bash teamai projects list # 已定义的项目 + 本目录激活的项目 teamai projects set hai-inference # 设置本目录激活的项目(覆盖语义;逗号分隔或重复;留空清除) teamai projects members hai-inference # 查看某项目下注册了哪些成员 ``` 成员登记是 `init` 的**副作用**:执行 `teamai init --project ` 会把 `` 追加进你的 `members/.yaml` 名册(跨目录 append + 去重),于是团队侧可以回答 「谁在项目 X」。`teamai push --project ` 会把 skill 推送到该项目的 skills namespace(从 manifest 解析),对标 `teamai push --role`。 本地配置示例: ```yaml repo: localPath: ~/.teamai/projects/my-project-/team-repo remote: https://github.com/yourorg/yourrepo.git username: alice scope: project projectRoot: /path/to/my-project # 资源落地位置(当前 checkout) inheritUserScope: true # 可选,仅 project scope primaryRole: hai additionalRoles: - pm resourceProfileVersion: 1 ``` ### 用户级(User Scope) 资源安装到用户主目录(`~/.claude/skills/` 等),适用于通用团队规范、跨项目技能。 ```bash teamai init https://github.com/yourorg/yourrepo --scope user ``` 生成的目录结构: ``` ~/.teamai/ ├── config.yaml # 本地配置 ├── team-repo/ # 团队仓库克隆 │ ├── teamai.yaml # 远端团队配置 │ ├── skills/ rules/ docs/ env/ members/ │ ├── manifest/roles.yaml # 角色定义(启用角色化 skills 时) │ └── learnings/ # 团队知识库 ~/.claude/skills/ # 团队 skills(自动同步) ~/.claude/rules/ # 团队 rules(自动同步) ``` ### 如何选择 Scope? | 维度 | Project Scope(默认) | User Scope | |------|-------------------|---------------| | **资源安装位置** | 项目目录下 | `~/` 下 | | **适用场景** | 项目特定的技能和规则 | 通用团队规范、跨项目技能 | | **能否共存** | ✅ 可以;project 保持当前 scope,并可选择继承安全的 user 资源 | ✅ 可以;仍是独立的用户主目录级安装 | > **本机安装位置**仅由 `teamai init` 的 `--scope`(默认 `project`)决定。远端 `teamai.yaml` 中若仍有 `scope` 字段会被忽略。 ### 单仓模式(业务仓即团队仓) 无需单独的团队仓库,可以让某个已有项目自己的 git 仓库直接充当团队仓。在项目内运行: ```bash cd /path/to/my-project teamai init . # 交互式:选择要启用哪些 AI 工具 teamai init . --agent claude,codex # 非交互:启用 Claude Code + Codex ``` **选择启用哪些 AI 工具。** 单仓模式会在你的仓库里为每个工具创建一个目录(如 `.claude/`、`.codex/`)——建好 skills 目录、注入 teamai hooks,并把该工具的 settings 提交到 main,让队友 clone 后即可获得。由你决定启用哪些工具: - **`--agent `** —— 显式列表,可重复或逗号分隔:`--agent claude`、`--agent claude,codex`、`--agent claude --agent cursor`。常用 id 包括 `claude`、`codex`、`cursor`、`joycode`、`codebuddy`、`workbuddy`、`dsh`(DeepSeek Harness)。 - **交互式(无 `--agent`、有终端)** —— teamai 弹出多选列表。第 1 项是 **Auto**,会列出你本机已安装的 AI 工具(`~/.claude`、`~/.codex`……)并作为回车默认项;其余各项是具体工具。Auto 与具体工具可以组合勾选。 - **非交互(无 `--agent`、无终端 —— CI、hook、clone 时自愈 bootstrap)** —— teamai 会按你本机 home 目录下已装的工具(`~/.claude`、`~/.codex`……)来建。若一个都没检测到,则什么都不建(你仍拿到知识,可稍后运行 `teamai init .` 再选工具)。 **数据如何在分支间拆分:** | 数据 | 存放位置 | 随 `git clone` 一起带走? | |------|----------|---------------------------| | 知识资产:`skills/` `rules/` `docs/` `learnings/`、`teamai.yaml` | **main** 分支的 `.teamai/` | ✅ 会 | | 上报数据:`members/` `sessions/` `votes/` `stats/` | `teamai-reports` **孤儿分支** | 推送到 `origin`(独立历史) | | 本机私有:`config.yaml`、`state.json`、搜索索引、env 备份、MCP manifest | `~/.teamai/projects//`(**分区**,在仓库之外) | ❌ 不会(每台机器本地) | | 可丢弃的 git worktree(`reports-wt/`、`knowledge-wt/`) | `.teamai/`(已 gitignore;按需重建) | ❌ 不会(每台机器本地) | 本机私有数据存放在仓库之外的按项目**分区**里,因此单仓模式的 `.teamai/` 只保留提交到 main 的团队知识 —— `git status` 保持干净。旧版单仓装升级后,下一次 `init`/`pull`/`push` 会自动把这些机器数据搬进分区(main 上的知识原封不动)。 **克隆即初始化。** 由于知识资产和 `.teamai/teamai.yaml` 里的 `mode: self` 标记都提交在 main 上,团队成员 clone 仓库后会被自动初始化:下一条 `teamai` 命令或 AI 会话会识别该标记,并(在其 git provider 已认证的前提下)自动写入本机配置、注入 hooks、在孤儿分支上注册成员 —— 无需手抄 repo/role 参数。若尚未认证,teamai 会提示其运行一次 `teamai init .`。 **安全性。** 单仓模式下 teamai 的每一次 git 写操作(知识 PR 和上报孤儿分支)都在 `.teamai/` 下的隔离 git worktree 中进行,绝不会 checkout、reset 或切换你的工作区和当前分支。隔离 worktree 里的提交会跳过本地 git hook(例如 husky / lint-staged):从 `origin/` 检出的干净工作区往往只有 hook 脚本、没有本地生成的 `husky.sh`,而且知识/上报文件本来就不该跑业务仓的 lint。你在业务仓里的普通 `git commit` 仍会走 hook。 **管理员在 `teamai init .` 之后的清单:** 1. `teamai init .` 已经帮你把 `.teamai/`(skills、rules、docs、learnings、`teamai.yaml`、`.gitignore`)以及每个所选工具的 settings(如 `.claude/settings.json`、`.codex/hooks.json`)提交到当前分支。 2. 推送 main,供团队成员 clone。 3. 之后新增资源用 `teamai push` —— 它会(通过隔离 worktree)向你的仓库开 PR,而不是直接改动你的工作区。单仓模式下,你既可以在 AI 工具目录(如 `~/.claude/skills/`)里编写,**也可以**直接把资源放进仓库里的 `.teamai/`: - `.teamai/skills/` —— 团队 skills - `.teamai/rules/` —— 共享 rules - `.teamai/agents/` —— subagent 定义(`.yaml`,或旧版 `.md`) - `.teamai/env/env.yaml` —— 共享环境变量 `teamai push` 会同时扫描这些目录和你的 AI 工具目录,只呈现真正的新增或修改(已提交的内容会被跳过)。如果你改了某个 agent 的扩展名(如 `helper.md` → `helper.yaml`),请手动删掉旧文件 —— `teamai push` 不会替你删除,同 stem 的两个文件会在 pull 时冲突。 4. **docs / hooks / mcp** 通过直接编辑对应文件来贡献 —— 它们不走 `teamai push`,用普通的 `git commit` + push 即可分发: - `.teamai/docs/` —— 团队文档 - `.teamai/hooks/hooks.yaml` —— 团队 hooks - `.teamai/mcp/mcp.yaml` —— 共享 MCP servers > **关于 `env` 的提醒。** 单仓模式下 `.teamai/env/env.yaml` **会被提交到 main**(不同于独立模式的每机本地 env),因此会随 clone 分发给所有人。`env.yaml` 存的是明文键值对 —— 只放非敏感的共享配置,真正的密钥请留在你自己未追踪的环境里。 > **限制。** 单仓模式把一套团队配置绑定到一个业务仓。如果需要一套团队知识库被多个业务仓共享,请改用独立团队仓(`teamai init `)。 ### 在项目仓库下叠加组织级仓库 当一部分经验全组织通用、另一部分只属于具体项目时,可以使用两个 Team Repo。CLI 只安装一次,但两个 scope 各有独立的本地配置和仓库克隆: ```bash # 每位开发者执行一次:组织通用 skills、rules、docs、agents 和 learnings teamai init https://github.com/yourorg/engineering-practices --scope user # 在 Java 项目中:项目资源保持当前 scope,recall 时优先 cd /path/to/java-service teamai init https://github.com/yourorg/java-service-teamai --inherit-user-scope ``` 启用继承后,`teamai pull` 会先把 user 的 `skills`、`rules`、`docs`、`agents`、共享指令/文化和检索索引刷新到用户主目录级位置,再刷新项目目录中的 project scope。user 的 `env`、hooks、MCP 定义、跨团队 sources、usage reporting 和远端仓库写入不会被继承。两个配置和两个 Git 仓库仍然分离;该功能组合的是安全读取路径,不会合并 Git 仓库或文件。同名的已安装资源仍分别位于 user/project 路径,由具体 AI 工具决定运行时优先级;Recall 则明确保证相同资源类型和文件名的 project 条目覆盖 user 条目。 --- ## 成员接入 管理员将团队仓库地址分享给成员后: **项目级团队(默认):** ```bash npm install -g teamai-cli cd /path/to/my-project teamai init https://github.com/yourorg/yourrepo # 完成!AI 工具已自动获得团队资源 ``` **用户级团队:** ```bash npm install -g teamai-cli teamai init https://github.com/yourorg/yourrepo --scope user ``` **HTTP 模式(只读消费者):** 无需 git 访问、仅消费 skills/rules 的用户或 agent: ```bash teamai init --http https://your-team-host/api --token ``` - 只读模式:`push` / `contribute` / `remove` 不可用。 - 无需 git clone——skills/rules 通过 report/sync/ack 生命周期按 session 下发。 - 支持的 agent 在 session 启动时自动上报已安装 skill 状态,并拉取服务端管理的安装/更新/卸载指令。 - API key 存储为 `0600` 权限,也可通过 `TEAMAI_API_TOKEN` 环境变量传入。 **验证:** ```bash teamai status # 查看状态 teamai members # 查看团队成员 teamai list # 全部资源类型(skills|rules|docs|env|agents|hooks|mcp)+ 本地 skills teamai list mcp # 只看团队 MCP servers teamai list --source repo # 只看团队仓库 teamai list --source local # 各已安装 agent 下的 skills teamai list --agent claude --verbose teamai list env --reveal # 明文显示 env(默认脱敏) teamai skill # 等价于 teamai list skills --source all teamai skill show hai-deploy-test # 看单个 skill 的来源 / 贡献者 / 安装位置 / 描述摘要 ``` --- ## 日常使用 ### 自动同步 `teamai init` 时已注入 Hooks 到你的 AI 工具中。**每次启动 AI 会话时会自动执行 `teamai pull`**,无需手动操作。在 project scope 下,该 SessionStart hook 会先为当前 Agent 创建项目根目录(例如用 Claude Code 打开仓库时创建 `/.claude`),然后再 pull。 *(注:会话启动自动同步依赖工具的生命周期 Hooks 支持,如 Claude Code、Codex、Cursor、CodeBuddy、WorkBuddy、Qoder、OpenCode、Hermes、OpenClaw 等。对于暂无 Hooks 支持的工具(如 JoyCode、Gemini CLI 等),无法触发会话启动 Hook,需在终端手动执行 `teamai pull` 同步团队资源。)* 如果需要立即同步,可以手动执行: ```bash teamai pull # 手动拉取 teamai pull --dry-run # 试运行,不实际修改 ``` > Project scope 默认与 user scope 隔离。当前工作目录包含 project scope 的 `.teamai/config.yaml` 时,`pull` 会处理该项目并跳过 user scope;仅当本地配置包含 `inheritUserScope: true` 时,才会先刷新安全的 user 资源通道。当前目录没有 project 配置时,`pull` 处理 user scope。project 模式下,user 的 `env`、MCP 定义、sources、reporting 和写入行为仍保持隔离。hooks 是唯一例外:project scope 的 hooks 会注入到你的 **HOME** 工具设置(`~/.claude/settings.json` 等),而非 ``——因为内置 hooks 依据传给 `hook-dispatch` 的 `cwd` 门控,且 `~/.claude` 恒存在、能通过「已安装工具」门槛(详见 Hooks 章节)。self 单仓模式则把 hooks 保留在业务仓库里,随 clone 传播。 启用角色化 skills 后,`pull` 的 skills 同步来源会变成 `skills//` 中的内容,按 `primaryRole + additionalRoles` 展开对应的 namespace,拍平安装到本地各 AI 工具 skills 目录。`rules/`、`docs/` 仍然保持原有同步逻辑。`learnings/` 根目录对所有人共享,而 `learnings//` 子目录只对本目录激活的项目同步(见 [多项目](#多项目project-作为与-role-正交的维度))。 ### 团队包 `teamai packages` 通过现有团队仓库统一声明和恢复 npm 包与 Claude Code 插件。TeamAI 调用原生 `npm` 和 `claude plugin` CLI,不自行分发包内容。 **管理员操作:** 传入 target 时,命令会完成安装,并将声明写入团队仓库的 `teamai.yaml`: ```bash # npm 包(默认安装为项目依赖) teamai packages install typescript # 未带 scope 的 name@version 与 plugin@marketplace 有歧义,需显式指定 npm teamai packages install typescript@5.9.2 --npm # 从指定 registry 安装全局 npm CLI teamai packages install eslint@latest --global \ --registry https://registry.npmjs.org/ # Claude 插件 teamai packages install code-review@claude-plugins-official # 通过现有评审流程分享更新后的 teamai.yaml teamai push ``` npm target 支持 `name` 或 `name@version`。由于未带 scope 的 `name@value` 也可能表示 `plugin@marketplace`,当后缀不是已声明或已注册的 Claude marketplace 时需使用 `--npm`。带 scope 的 npm 名称(`@scope/name`)、无版本名称、`--global` 和 `--registry` 已能明确表示 npm,不会探测 Claude CLI。安装项目依赖时,当前目录必须包含 `package.json`;机器级 CLI 工具使用 `--global`。`--registry` 会随该包的声明保存,且必须是不包含凭据的 HTTP(S) URL。registry 认证信息应保存在 npm 配置或环境变量中。 Claude 插件 target 使用 `plugin@marketplace` 格式。`claude-plugins-official` 官方 marketplace 会自动解析;使用其他 marketplace 前,需先在 Claude Code 中注册,以便 TeamAI 获取并记录其来源。可使用 `--claude` 明确指定生态,并在 marketplace 不可用时获得针对性的错误。存在歧义的 target 会直接失败,不会运行任一包管理器。`--global` 和 `--registry` 仅适用于 npm target。 **成员操作:** 现有 SessionStart hook 会执行 `teamai pull`。当 `packages` 声明发生变化时,它只会提示成员检查 `teamai.yaml` 并主动安装,不会自动执行第三方包或插件代码。pull 继续在后台运行,避免网络延迟阻塞 IDE;如果声明在 SessionStart 输出窗口结束后才拉取完成,TeamAI 会把同一条提示安全地排队,并在本会话下一次 UserPromptSubmit 时投递。 ```bash teamai packages # 安装团队声明的全部包和插件 teamai packages --dry-run # 预览底层命令,不安装也不写文件 teamai doctor # 检查运行环境及声明的包、marketplace、插件状态 ``` 安装成功后,TeamAI 会在当前 scope 的 `.teamai` 目录下写入本地快照 `teamai.lock`。该文件记录已安装版本,以及供 SessionStart 提示比对的声明哈希,不会写入团队仓库。在 user scope 下,全局 npm 工具和 Claude 插件只需确认一次;项目 npm 依赖会按工作目录分别确认,避免在一个仓库安装后错误关闭另一个仓库的提示。 **声明格式:** 以下内容由 `teamai packages install ` 自动维护: ```yaml packages: npm: - name: typescript version: "*" - name: eslint version: latest global: true registry: https://registry.npmjs.org/ claude: marketplaces: - name: claude-plugins-official repo: anthropics/claude-plugins-official plugins: - name: code-review@claude-plugins-official ``` - `npm[].version` 默认为 `*`,`global` 默认为 `false`。 - `claude.marketplaces` 记录 marketplace 名称与仓库来源。 - Claude 插件必须使用 `plugin@marketplace` 格式,且对应 marketplace 必须已声明。 - `packages` 内未知或拼错的键会在 install 或 push 前被拒绝。 - 包声明对全团队生效,不受角色或项目筛选影响。 ### 排除个人不需要的 Skill 如果团队共享的某个 skill 不适合你,可以只在本地将它排除,无需修改团队仓库,也不会影响其他成员: ```bash teamai skill exclude add using-superpowers teamai pull # 从本地 AI 工具中删除 teamai skill exclude list teamai skill exclude remove using-superpowers teamai pull # 重新同步 ``` 排除列表保存在当前 user 或 project scope 的 `config.yaml` 中: ```yaml excludedSkills: - using-superpowers ``` 排除规则在角色和标签过滤之后生效。执行 `teamai pull` 时,被排除的 skill 不会同步,并且会清理由之前 pull 安装的副本。 ### 推送本地资源 ```bash teamai push # 扫描新增/修改的资源,创建 MR teamai push --all # 跳过确认,直接推送 teamai push --role pm # 将本次 skill 推送到 skills/pm// ``` **命名空间选择(新 skill):** 推送新 skill 时,CLI 会自动检测可用的命名空间并提供交互式选择: ``` Which namespace should new skills be pushed to? 1. common 2. hai 3. pm Choose namespace [1-3] (default: 1 = common): ``` - 有 `primaryRole` 时,从 manifest 展开可用 namespace 列表 - 无 `primaryRole` 时,自动扫描团队仓库目录结构 - 单一命名空间时自动选中;也可用 `--role ` 显式指定 - 修改已有 skill 时自动保持原 namespace **更新已存在的 PR 而非重复创建:** 如果某个资源已在一个未合并的 PR 中等待评审,再次对它执行 `teamai push` 会就地更新那个已存在的 PR(通过 force-push 其分支),而不是新开一个重复的 PR。保持该资源被选中即更新其 PR;取消勾选则不动它。同一次运行中选中的其他无关资源会进入各自新开的 PR。一旦该 PR 合并(或其分支从远端删除),记录会被清除,下次 push 照常新开 PR。 **YAML Frontmatter 自动补全:** 推送时 CLI 自动检查合法的 mapping 形式 `SKILL.md` frontmatter,缺少 `name`/`description` 则自动补全。格式损坏或根节点为标量时会保留原文并告警,需要手动修复。 ### 查看状态 ```bash teamai status # 当前 scope、同步时间、资源统计 teamai status --all # 列出 ~/.teamai/projects 下所有项目数据分区 ``` `--all` 会枚举每个项目的机器数据分区,并标注为 **active**(项目仍在磁盘上)、 **ORPHAN**(项目已移动/删除——该分区可安全 `rm -rf`)或 **unknown**(无 `anchor` 文件,无法确认是否孤儿——绝不建议删除)。ORPHAN 判定只依据 anchor,因此绝不会凭猜测 把分区标记为可删除。teamai 从不自动回收孤儿分区,因此这是你找出可手动删除分区的方式。 ### 角色管理 角色(Roles)控制每个成员看到哪些 skills。管理员通过 `manifest/roles.yaml` 定义角色,成员选择自己的角色后,pull 会同步对应 namespace 的 skills。启用标签订阅后,还可以额外同步其他 namespace 中显式匹配标签的 skills,但不会包含非活跃 namespace 中未打标签的 skills。 **管理员操作:** ```bash # 初始化(交互式创建 manifest) teamai roles init # 添加角色 teamai roles add devops --namespaces common,infra -d "基础设施团队" # 修改角色(增删 namespace、改描述) teamai roles update hai --add-namespaces infra teamai roles update hai --remove-namespaces legacy -d "新描述" # 删除角色 teamai roles remove devops # 预览变更 teamai roles add test --namespaces common,test --dry-run ``` 以上命令会自动 push 分支并创建 MR,合并后对全团队生效。 **成员操作:** ```bash # 查看可选角色 teamai roles list # 选择自己的角色 teamai roles set hai teamai roles set hai --add pm # 主角色 hai + 额外角色 pm # 同步新角色的资源 teamai pull ``` > **安全降级:** 如果管理员删除了某个角色,仍然配置了该角色的成员在 pull 时不会报错,而是回退到全量同步并输出警告,提示重新选择角色。 ### 标签订阅 标签让成员订阅默认角色 namespace 之外的指定 skills 和 rules。 ```bash teamai tags list teamai tags subscribe frontend testing teamai tags unsubscribe testing ``` 管理员可通过 `teamai tags add` 和 `teamai tags remove` 管理资源标签。修改订阅后运行 `teamai pull`。 --- ## 共享团队资源 这是 Team Execution:Skills、Rules 等 Harness 定义一次,经 MR 评审后由 `teamai pull` 分发到每个 Agent。 ### Skills(技能) ```bash # 创建 skill mkdir -p ~/.claude/skills/my-deploy-helper cat > ~/.claude/skills/my-deploy-helper/SKILL.md << 'EOF' # Deploy Helper 当用户请求部署时,按以下步骤执行: 1. 检查当前分支是否为 master 2. 运行测试 `npm test` 3. 构建 `npm run build` 4. 部署 `./deploy.sh` EOF # 推送到团队(YAML frontmatter 会自动补全) teamai push # 推送到指定角色 namespace teamai push --role pm ``` > **Frontmatter 自动补全:** 推送时 CLI 会检查 `SKILL.md` 的 YAML frontmatter(`name`/`description`),缺失则自动从目录名和内容中推导并补全。你也可以手动添加更精确的 frontmatter: > > ```yaml > --- > name: my-deploy-helper > description: 帮助团队部署服务的自动化技能 > tags: [deploy, automation] > --- > ``` > > YAML 格式损坏或 frontmatter 根节点不是 mapping 时,CLI 会保留原文并输出告警;请手动修复后再推送。 启用角色化 skills 后,push 的目标目录为: - 默认:`skills///` - 显式覆盖:`skills///`(通过 `--role`) ### Rules(规则) ```bash # 创建 rule cat > ~/.claude/rules/code-review-guide.md << 'EOF' # 代码审查规范 - 所有函数必须有 JSDoc 注释 - 禁止使用 `any` 类型 - 测试覆盖率不低于 80% EOF # 推送 teamai push ``` > 管理员可在 `teamai.yaml` 中设置强制规则(`sharing.rules.enforced`),成员不可删除。 ### Env(环境变量) ```bash teamai env add API_ENDPOINT https://api.example.com --description "团队 API 地址" teamai env list teamai push ``` ### Docs(文档) 将文档放入团队仓库 `docs/` 目录,push 后团队成员 pull 时自动同步。 ### MCP Server 在团队仓库的 `mcp/mcp.yaml` 中声明一次,`teamai pull` 时会按各工具的原生格式写入它们各自的 MCP 配置文件。 ```yaml servers: - name: gpu-analysis description: GPU 存量与价格查询 transport: http # stdio | http | sse url: https://example.com/api/mcp headers: Authorization: Bearer ${GPU_ANALYSIS_TOKEN} timeout: 600000 - name: local-formatter transport: stdio command: npx args: ['-y', '@acme/formatter-mcp'] env: FORMATTER_MODE: strict requires: [npx] # npx 不存在时跳过并提示 tools: [claude, cursor] # 可选;默认所有支持 MCP 的工具 ``` 各工具的落点: | 工具 | 用户级 | 项目级 | |---|---|---| | claude | `~/.claude.json` | `/.mcp.json` | | cursor | `~/.cursor/mcp.json` | `/.cursor/mcp.json` | | codebuddy | `~/.codebuddy/mcp.json` | `/.mcp.json` | | workbuddy | `~/.workbuddy/mcp.json` | `/.workbuddy/mcp.json` | | codex | `~/.codex/config.toml` | 不支持 | | qoder | `~/.qoder/settings.json` | `/.qoder/settings.json` | | opencode | `~/.config/opencode/opencode.json` | `/opencode.json` | CodeBuddy Code 的 [MCP 文档](https://www.codebuddy.cn/docs/cli/mcp) 明确将项目根目录的 `.mcp.json` 列为首选项目配置。 该路径与 TeamAI 的用户级目标 `~/.codebuddy/mcp.json` 相互独立。 `teamai.yaml` 中显式设置的 `toolPaths.codebuddy.mcpProject` 仍然优先生效。 已有团队若固定使用 `.codebuddy/mcp.json`,请先在对应工作区执行 `teamai mcp remove`,再将该值改为 `.mcp.json`,最后运行 `teamai mcp inject`。请检查并保留两处文件中自行添加的服务; TeamAI 不会迁移或删除旧文件。Claude Code 也读取根目录的 `.mcp.json`, 因此两个工具共享该文件。 Codex 支持 `stdio` 与 `http`,`sse` 会被跳过。Qoder 使用对应作用域 `.qoder/settings.json` 中与 Claude 兼容的 `mcpServers` 格式。OpenCode 支持 `stdio`(写成其 `type:"local"` 形态)与 `http`(`type:"remote"`),`sse` 会被跳过,其 server 位于共享 `opencode.json` 的 `mcp` 键下。归属记录在 `~/.teamai/managed-mcp.json`——手动添加的 server 不动;与手写同名则跳过,除非 `--force`。 **密钥**:在 `mcp.yaml` 里写 `${VAR}`,不要写明文。取值优先来自环境变量,其次是 `env/env.yaml` → `~/.teamai/env`。变量无法解析则跳过并提示。 teamai 会**把每个 `${VAR}` 解析成取值后原样写入**各工具的配置文件(新建文件权限为 `0600`)。它不依赖任何工具自身的环境变量展开——因为那种展开很脆弱:最典型的是,以 GUI 方式(Dock/Launchpad)启动的 IDE 不会继承你 shell 中 `export` 的变量,`${VAR}` 占位符会展开为空、导致服务端 401。解析成明文可以保证无论工具如何启动,token 都在。 > ⚠️ **解析后的 token 会落盘。** 项目级 MCP 配置(`.mcp.json`、`.cursor/mcp.json`、`.codex/config.toml`、`opencode.json`)因此含有明文密钥——请把它们加入 `.gitignore`,切勿提交。 Claude Code 可能把来自仓库的 `.mcp.json` 标为待批准,需在交互式会话中确认一次。 ```bash teamai mcp list # 查看 server、密钥状态与安装位置 teamai mcp inject # 立即注入;--dry-run 预览,--force 覆盖同名 teamai mcp remove # 移除所有 teamai 管理的 server ``` --- ## 知识沉淀与检索 这是 Team Context,也是 Team Improvement 的起点:先记下本次 Session 真正学到的东西,再让下一次 Agent 能检索到。 ### 贡献知识 AI 通过 Hooks 追踪你的编码会话。当会话结束时(Stop hook),系统按**摩擦信号**评分——你是否打断/纠正了 AI、拒绝了工具调用,或 AI 反复重试出错的工具。又长又顺的会话(工具调用多但没摩擦)不会触发,真正踩过坑的会话才会。达标后会显示如下英文提醒: ``` [teamai] This session may contain a problem worth documenting: you interrupted the AI twice, the AI retried failing tools 8 times. Task: Fix duplicate project-level Hook injection Consider running /teamai-share-learnings to summarize what you learned and share it with your team. ``` 提醒会列出实际触发它的非零摩擦信号;如果能取得首个任务,还会附上脱敏、单行化后的任务摘要,便于判断本次 session 是否值得分享。使用内置 skill `/teamai-share-learnings`,AI 会自动总结本次 session 经验并贡献到团队知识库。每个 session 最多提示一次。 在 Codex 中,Stop hook 会暂存贡献和知识引用提醒,在同一会话的下一次 UserPromptSubmit 交付,不会强制开启额外一轮。贡献提醒只交付一次;若下一次输入前已经贡献,则丢弃该提醒。 也可以手动指定文件: ```bash teamai contribute --file /tmp/session.md teamai contribute --file /tmp/session.md --scope project ``` #### 关闭提醒 如果团队通过自己的评审流程沉淀知识(例如个人复盘后提交普通 PR),可以只关闭这条提醒,Stop hook 的其余功能(更新检查、votes 同步、dashboard 上报)照常运行。配置方式与 recall 相同,分两层: | 层级 | 配置文件 | 字段 | 说明 | |------|----------|------|------| | 团队默认 | `teamai.yaml` | `sharing.contributeHint.enabled` | `true`(默认)/ `false` | | 用户覆盖 | `~/.teamai/config.yaml` | `contributeHintEnabled` | `true` / `false`,优先级高于团队默认 | | 环境变量 | shell | `TEAMAI_CONTRIBUTE_HINT_DISABLED=1` | 强制关闭提醒(紧急开关) | 只影响提醒本身:摩擦评分、`teamai contribute --file` 和手动调用 `/teamai-share-learnings` 不受影响。 ### 搜索知识 ```bash teamai recall "API 超时" teamai recall "GPU 内存不足" ``` - 支持中英文混合搜索 - 当前工作目录包含 project scope 配置时搜索该项目;配置 `inheritUserScope: true` 后先搜索 project、再搜索 user,并标注 `[project]`/`[user]` 来源;否则搜索 user scope - 资源类型和文件名都相同时由 project 条目优先;不同资源类型即使文件名相同也分别保留 - 当前 scope 中被查阅的知识自动 upvote;项目运行期间继承的 user 命中保持只读 - 提供轻量相关性预检 `teamai recall --check "<关键词>"`,输出 `RELEVANT score= threshold=` 或 `NOT_RELEVANT score= threshold=`,不读取文件、不 upvote —— recall subagent 用它在任务与团队知识无关时跳过检索。当 top 命中为 `RELEVANT` 时,还会输出 `matched=`/`missing=`,即命中/未命中其 title 与 tag 的查询词 - `RELEVANT` 表示分数越过阈值、值得花成本读文件,**不代表**知识库覆盖了你要找的主题。请用 `matched=`/`missing=`(以及完整结果里的 `Matched:`/`Missing:` 行)自行判断:若关键区分词全部落在 missing 里,那条只是主题相邻,并非答案 ### 开启 / 关闭 Recall Recall 功能通过两级配置控制——管理员设置团队默认值,成员可在本地覆盖: | 层级 | 配置文件 | 字段 | 说明 | |------|----------|------|------| | 团队默认 | `teamai.yaml` | `sharing.recall.enabled` | `true` / `false`(默认 `false`) | | 用户覆盖 | `~/.teamai/config.yaml` | `recallEnabled` | `true` / `false`,优先级高于团队默认 | | 环境变量 | shell | `TEAMAI_RECALL_DISABLED=1` | 强制禁用所有 recall hooks(应急开关) | ```bash teamai recall enable # 开启 recall,部署 subagent 和 rules teamai recall disable # 关闭 recall,移除 subagent 和 rules teamai recall status # 查看当前生效状态(团队默认 + 用户覆盖) ``` 关闭后,`teamai pull` 将跳过部署 recall subagent、recall rules 注入块和 TodoWrite 提醒 hook。手动执行 `teamai recall ` 搜索不受此开关影响。 ### 知识库维护 随着时间推移,部分 learnings 会积累低置信度(无人 upvote)或变得过时。`teamai recall maintenance` 可保持知识库健康: | 选项 | 说明 | |------|------| | `--prune` | 查找低于置信度阈值的 learnings 并删除 | | `--threshold ` | 剪枝用置信度阈值(默认 `0.15`) | | `--archive` | 将剪枝条目移至 `archive/` 而非直接删除 | | `--confidence-writeback` | 从投票历史重新计算置信度,并回写到 frontmatter | | `--update-quality` | 找出高召回但低认可的 docs/rules/skills,生成 AI 更新草稿(`.draft.md` 文件) | | `--dry-run` | 预览将要执行的操作,不做任何实际修改 | ```bash # 预览过时条目,不做任何修改 teamai recall maintenance --prune --dry-run # 归档低置信度 learnings(置信度 < 0.15) teamai recall maintenance --prune --archive # 按当前投票重新计算并回写置信度分数 teamai recall maintenance --confidence-writeback # 查找过时条目并生成更新草稿 teamai recall maintenance --update-quality ``` 运行 `--update-quality` 后,审查生成的 `.draft.md` 文件,将满意的文件重命名为 `.md` 即可应用更新。 ### 晋升 Learnings 当 learning 达到成熟标准时,可将其晋升为正式团队知识(skill、rule 或 doc)。晋升判据:置信度 ≥ 0.90、≥ 5 次 upvote、≥ 2 个不同贡献者、存在时长 ≥ 14 天。 ```bash # 列出所有可晋升候选 teamai recall promote # 晋升指定 learning(AI 将其改写为目标格式) teamai recall promote # 晋升到指定类别 teamai recall promote --category skills # 预览操作,不写入文件 teamai recall promote --dry-run ``` 选项: | 选项 | 说明 | |------|------| | `--category ` | 目标类别:`skills` \| `rules` \| `docs` | | `--dry-run` | 预览操作,不做任何实际修改 | --- ## 知识库健康报告 看板内置了一个 **KB Health**(知识库健康)报告页面,展示团队知识库的使用情况与健康状态,涵盖 `teamai recall` 投票、learnings、docs、rules 和 skills 采集到的所有数据。 ```bash # 启动看板后,点击顶部的 "KB Health" 链接 teamai dashboard # 报告也可直接访问: # http://localhost:3721/kb-report ``` 报告会聚合本地 `~/.teamai` 知识库(或已配置的团队仓库),打开页面即按需渲染,无需任何参数。 ### 报告内容 | 区块 | 说明 | |------|------| | **概览卡片** | 总条目数、总召回次数、整体覆盖率%、贡献者数 | | **各类型覆盖率** | skills、rules、docs、learnings 的召回覆盖率分类 | | **高频召回排行** | 召回次数最多的条目排名列表 | | **沉默条目** | 从未被召回的条目——待剪枝或重写的候选 | | **召回趋势** | 召回活跃度随时间的变化 | | **作者贡献** | 每位贡献者的条目数与召回占比 | | **维护控制台** | 三个操作区:待晋升条目、建议归档条目、过时待更新条目,每条附可复制命令 | ### 典型工作流 ``` 打开看板 → KB Health 页面 ↓ 查看维护控制台 ↓ 晋升成熟 learnings: teamai recall promote ↓ 归档低价值条目: teamai recall maintenance --prune --archive ↓ 更新过时的 docs/rules/skills: teamai recall maintenance --update-quality (审查 .draft.md → 重命名为 .md) ↓ teamai push # 将清理后的知识库分享给团队 ``` --- ## 提交 Co-Author 署名 AI 编码工具会在它生成的提交上打一个 `Co-Authored-By:` / attribution 尾注。希望保持干净历史的团队可以为全员关闭它,成员仍可在自己机器上覆盖。`teamai pull` 会把最终生效的意图写入每个已安装工具各自的配置文件。 该功能采用与 recall 相同的两级配置: | 层级 | 配置文件 | 字段 | 说明 | |------|----------|------|------| | 团队默认 | `teamai.yaml` | `sharing.coAuthor.enabled` | `true` = 保留尾注 / `false` = 去除尾注。整块省略表示"无意见"(teamai 不做任何改动) | | 用户覆盖 | `~/.teamai/config.yaml` | `coAuthorEnabled` | `true` / `false`,优先级高于团队默认 | 不同工具家族映射到不同的设置项: | 工具家族 | 文件 | 写入的设置 | 作用域 | 可靠性 | |------|------|------|------|------| | Claude(`claude`、`codebuddy`、`workbuddy`) | `settings.json` | `attribution.commit` / `attribution.pr` 置为 `""` | 用户 **或** 项目(跟随当前 scope) | 确定生效 | | Codex(`codex`) | `~/.codex/config.toml` | `commit_attribution = ""` | 仅用户 | 尽力而为 —— 仅当 `[features].codex_git_commit = true` 时生效,teamai 不会强制开启该开关 | | Cursor | `~/.cursor/cli-config.json` | `attribution.attributeCommitsToAgent = false` | 仅用户 | 尽力而为 —— 存在[上游已知 bug](https://forum.cursor.com/t/local-executor-ignores-cli-config-attribution-opt-out-forcing-co-authored-by-trailer/167722),local executor 可能忽略该设置 | 语义: - **只写不删。** teamai 一旦写入某个值,之后团队撤下策略也不会改动该值 —— teamai 绝不还原它去除过的尾注。若要重新启用,请显式把意图设回 `true`(这会移除 teamai 的覆盖,从而恢复工具自身的默认行为)。 - **幂等。** teamai 在 `state.json` 的 `coAuthorManaged` 中记录每个文件上次写入的值,无变化时跳过写入。 - **只改动已安装的工具**,并保留各配置文件中已有的键与注释(键级别的精修,而非整文件重生成)。 `pull` 之后请重启 AI 工具会话使改动生效。 --- ## 团队文化 TeamAI 支持将团队文化注入到 AI 工具中,让 AI 编码助手在每次会话中都能感知你的团队文化、价值观和编码准则。 ### 创建 culture.md 管理员在团队仓库根目录创建 `culture.md` 文件: ```markdown --- company: name: Acme Corp mission: Build great things vision: A world where AI helps everyone values: - Innovation - Integrity - User First team: name: Platform Team mission: Enable developers to ship faster goals: - Ship v2.0 by Q2 - Improve test coverage to 90% --- ## 编码准则 - 所有 PR 必须有至少一个 reviewer 审批 - 禁止直接 push master - 测试覆盖率不低于 80% ## 协作规范 - 使用 conventional commits 格式 - PR 描述必须包含 ## Summary 和 ## Test Plan - 重大变更需要先写设计文档 ``` ### frontmatter 字段 | 字段 | 类型 | 说明 | |------|------|------| | `company.name` | string (必填) | 公司名称 | | `company.mission` | string | 公司使命 | | `company.vision` | string | 公司愿景 | | `company.values` | string[] | 公司核心价值观 | | `team.name` | string (必填) | 团队名称 | | `team.mission` | string | 团队使命 | | `team.goals` | string[] | 团队目标 | frontmatter 之后的 markdown body 部分会作为团队文化指引的正文内容,整体注入到 CLAUDE.md 中。 ### 工作原理 ``` 团队仓库 ├── culture.md ← 管理员维护 ├── skills/ ├── rules/ └── ... teamai pull │ ▼ 解析 culture.md │ ├─ frontmatter → 结构化公司/团队信息 │ └─ body → 团队文化指引正文 │ ▼ 编译为 CLAUDE.md 注入块 │ ▼ 注入到各 AI 工具的 CLAUDE.md ├─ ~/.claude/CLAUDE.md ├─ ~/.cursor/CLAUDE.md └─ ... ``` 注入的内容位于 `` 和 `` 标记之间,每次 pull 时自动更新,不会影响文件中的其他内容。 ### 查看效果 pull 后可以直接查看 AI 工具的 CLAUDE.md: ```bash teamai pull cat ~/.claude/CLAUDE.md ``` 你会看到类似这样的注入块: ```markdown ## Team Culture (teamai) ## Company: Acme Corp **Mission:** Build great things **Vision:** A world where AI helps everyone **Values:** Innovation, Integrity, User First ## Team: Platform Team **Mission:** Enable developers to ship faster **Goals:** - Ship v2.0 by Q2 - Improve test coverage to 90% ## 编码准则 - 所有 PR 必须有至少一个 reviewer 审批 ... ``` --- ## 进阶功能 ### HTTP 契约(面向后端实现者) 使用 `teamai init --http ` 时,端点需要提供以下接口(`Authorization: Bearer ` 鉴权): | 端点 | 方法 | 用途 | |------|------|------| | `{baseUrl}/api/local-agent/report` | POST | session 启动:upsert agent + 已装 skill | | `{baseUrl}/api/local-agent/sync` | POST | 上报状态 + 返回待执行的 skill 命令 | | `{baseUrl}/api/local-agent/commands/ack` | POST | 回执单条命令(`{ id, status, error }`) | `POST /api/local-agent/sync` 返回待执行命令: ```json { "ok": true, "commands": [{ "id": 1, "type": "install_skill", "skill_slug": "x", "skill_version": "1.0.0", "download_url": "https://signed-url/..." }] } ``` 后端可下发 **`apply_model_config`** 任务,其 `cmd` 为 JSON。客户端同时兼容设计文档中的候选集结构和 旧版单模型结构:`{"models":[...]}` 按完整快照处理,直接模型对象按增量 upsert 处理。 `max_tokens` 可选(对应 CodeBuddy / WorkBuddy 的 `maxOutputTokens`);缺省或 `0` 时默认 `4096`。Claude 不使用该字段。 ```jsonc { "id": 16, "type": "apply_model_config", "cmd": "{\"models\":[{\"provider\":\"openai\",\"model_id\":\"gpt-4o\",\"name\":\"GPT-4o\",\"base_url\":\"https://proxy.example.com/v1\",\"api_key\":\"\",\"max_tokens\":4096,\"context_window\":128000}]}" } ``` 候选集只会写入当前上报任务的 agent。CodeBuddy 使用用户级 `~/.codebuddy/models.json`(`{ "models": [...] }`); WorkBuddy 使用 `~/.workbuddy/models.json`;当前 `{ "models": [...] }` 和旧版顶层数组两种结构都支持, 已有文件保持原结构。CodeBuddy 或 WorkBuddy 的 workspace 级任务写入 `/.codebuddy/models.json`,与产品内嵌模型加载器一致;该含凭证文件会被加入 `/.codebuddy/.gitignore`。仅当目标路径已存在于 reporter 的 workspace bindings 中时, 才接受 workspace 级下发。若同一模型 ID 已由用户配置,则保留用户条目。 Claude 侧会生成独立配置 `~/.claude/teamai-models.json`;仅当不存在冲突的用户 Anthropic 网关配置时, 才把网关环境变量写入默认 settings。冲突检测会**同时**检查 `~/.claude/settings.json` 的 `env` 和当前进程的 shell 环境变量(`export ANTHROPIC_*`),因此通过 shell 环境变量使用 Claude 的用户会保留自己的网关—— TeamAI 跳过写入,并把跳过的 key 记入 `~/.teamai/reporter/errors.jsonl`。受保护的 key 包括 `ANTHROPIC_BASE_URL`、`ANTHROPIC_AUTH_TOKEN`、`ANTHROPIC_API_KEY`、`ANTHROPIC_CUSTOM_HEADERS`、 `ANTHROPIC_CUSTOM_MODEL_OPTION{,_NAME}` 以及 `ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODEL`。 若某个 shell 值与 TeamAI 上次写入的值一致(Claude 会把 `settings.json` 的 `env` 回注到 hook 进程), 则识别为托管值而非用户冲突,因此后续同步仍可更新或删除托管网关。不支持的 agent 会回执失败,不会误写其他 agent 的配置。用户配置文件是符号链接时会保留链接。以上含凭证文件权限均为 `0600`。落盘成功后以 `type: "apply_model_config"` 回执;非法 payload 回执 `failed`。未来未知任务类型会静默跳过,以保持协议向后兼容。 反向的模型上报走已有的 `report` 接口:仅上报 TeamAI manifest 已记录、且磁盘上的模型 ID 和 provider 仍可识别的模型,用户级放在 `user_level.models`,workspace 级放在对应的 `workspaces[].models`。agent 正常补充元数据不会导致漏报; 模型落盘成功后会在同一次 sync 中立即补一次 report,无需等待下一次 session。用户自有模型不上报, 因为后台无法识别。服务端要求 `provider` 与 `model_id` 同时存在。与 skills/rules 一致,没有任何符合条件的 模型时该字段整体省略——因为存在的数组会被当作全量快照。CodeBuddy、WorkBuddy 和 Claude (`~/.claude/settings.json` 里的 `ANTHROPIC_CUSTOM_MODEL_OPTION` 网关)有可发现的模型配置, 其余工具不上报。上报条目的 `source` 固定为 `enterprise`。 **`api_key` 不会被回传** —— ProxyToken 只留在本地磁盘。 ```jsonc { "agent_type": "codebuddy", "local_agent_id": "...", "user_level": { "models": [ { "provider": "tokenhub", "model_id": "gpt-4o", "name": "GPT-4o", "source": "enterprise" } ] } } ``` HTTP 契约用于自建集成。普通用户只需使用[成员接入](#成员接入)中的 `teamai init --http` 命令。 ### 代码知识图谱 `teamai import` 将源码仓库解析为结构化知识图谱(存储在团队仓库的 `teamwiki/` 目录下),实现结构感知的知识检索: ```bash # 从本地目录提取 teamai import --dir /path/to/project # 从远程仓库导入 teamai import --from-repo https://github.com/org/repo # 批量导入组织下所有仓库 teamai import --from-org myorg # 从白名单批量导入 teamai import --from-repo-list repos.yaml # 从已合并的 MR/PR 提取经验 teamai import --from-mr https://github.com/org/repo/pull/123 # 增量模式(跳过未变更文件) teamai import --from-repo https://github.com/org/repo --incremental # 仅提取结构,跳过 AI 增强 teamai import --from-repo https://github.com/org/repo --skip-enrich ``` 对于 API 网关后的 GitLab,先设置 `GITLAB_URL` 和 `GITLAB_API_PREFIX=api/gitlab`,再运行 `teamai import --from-org https://gitlab.example.com/myorg`。组织仓库列表的每一页请求都会使用配置的前缀;未设置或为空时默认使用 `api/v4`。 图谱存储组件、接口、配置和跨仓库依赖关系。`teamai recall` 利用图谱进行 BM25 + graph-boost 增强排名。 依赖边由两条并行轨道提取:WASM tree-sitter **AST 轨**(TypeScript/JavaScript、Python、Go),将 import、调用、以及 TS `implements` 子句解析为精确的文件到文件边(`code-ast`);以及正则 **启发式轨**(所有语言,`code-heuristic`),同时覆盖 AST 轨未支持的语言。重叠时 AST 结果优先。AST 解析器无需原生编译工具链;加载失败时提取会降级到启发式并记录一条 `AST_UNAVAILABLE` gap。设置 `TEAMAI_SKIP_AST=1` 可强制仅用启发式提取。 ```bash # 从本地仓库提取代码事实与图谱(写入 /teamwiki/) teamai codebase --extract /path/to/repo --project my-service # 增量刷新:复用首次提取的仓库路径和项目名 teamai codebase --extract /path/to/repo --project my-service --incremental # 从已提取的 evidence 生成深度知识文档(--output 指向仓库根目录) teamai codebase --deep-enrich --project my-service --output /path/to/repo # 将 teamwiki/product 和 teamwiki/docs 与提取的代码页面进行对账 teamai codebase --reconcile --output /path/to/repo # 检查本地提取的图谱;--output 指向仓库根目录,而非 teamwiki/ teamai codebase --lint --output /path/to/repo ``` ### Dashboard ```bash teamai dashboard # 启动 Web 面板(默认端口 3721) teamai dashboard --port 8080 ``` 实时查看团队成员的 AI 编码会话状态。 #### 人工干预指标(Human Intervention) 每个会话卡片会显示一个 `⚠ N` 徽标,统计该对话中用户的**人工干预次数**——干预越少,说明 agent 一次把事做对的能力越强。鼠标悬停可看分类明细,三类信号各计一次: | 类型 | 含义 | 数据来源 | |------|------|----------| | `interrupt` | 用户在 agent 执行中途按 ESC 打断 | transcript 中被中断的 turn | | `toolReject` | 用户拒绝某个工具调用(permission deny) | transcript 中标记拒绝的 tool_result | | `correction` | agent stop 后 60s 内用户追加含「不对 / 重来 / 错了 / wrong / redo / 違う / やり直し」等纠偏词(中、英、日)的 prompt | stop → prompt_submit 事件模式 | > 隐私:只统计**次数**,不落地任何 prompt 或 transcript 原文。 干预数据会随 `teamai pull` 自动聚合上报到团队 `stats/.yaml`,并在 `teamai digest` 的「会话自主性」榜单中给出团队均值与人均干预率排行,可用于验证某个 skill / rule 上线后干预率是否下降。无 transcript 的工具(如 Cursor)会优雅降级,只统计 `correction`。 #### 对话量与 Token 用量 每个会话卡片还会显示两个徽标: | 徽标 | 含义 | 数据来源 | |------|------|----------| | `💬 N` | 该会话里**人类对话的轮数**(发了几次 prompt) | `UserPromptSubmit` 事件数 | | `⛁ X` | 该会话累计 **token 用量**(鼠标悬停看 输入 / 输出 / 缓存读 / 缓存写 明细) | Claude Code `message.usage`、CodeBuddy `requests[].usage`,或 Codex 最新的会话级 `token_usage_record`;旧版 `event_msg.token_count` 按 rollout 文件各取最新快照后累加 | > 隐私:只统计**轮数与 token 数量**,不落地任何 prompt 或 transcript 原文。 这两项同样随 `teamai pull` 聚合到 `stats/.yaml`(`prompts` 与 `tokens` 字段),并在 `teamai digest` 的「对话量与 Token 用量」板块给出团队对话总轮数、token 总量(分桶)与人均 token 用量排行。拿不到 transcript 的工具(如 Cursor)会优雅降级:仍统计对话轮数,token 显示为 0 / N/A。 #### 每日会话趋势与估算成本 Dashboard 和 digest 会比较最近 7 个 UTC 自然日与此前 7 天。会话归属到首次 stop 事件所在日期,每个已定价请求则归属到请求自身的 UTC 日期;活跃时长只累计不超过 5 分钟的相邻事件间隔,避免终端空闲时间把数据放大。会话结束时没有错误、中断或纠偏才计为成功;被拒绝的工具调用仍作为独立干预信号统计。仅包含模型、token 数、估算成本和价格表版本的请求明细保存在本地 `~/.teamai/dashboard/requests.jsonl`,不包含提示词或回复内容;重复 Stop 不会重复写入,超过 90 天会自动清理。 成本是 API 等价估算值:对可识别的 Claude 模型,根据带版本的公开目录价,以及 transcript 中的输入、输出、缓存读取和缓存写入 token 分桶计算。由于 transcript 不提供缓存 TTL,缓存写入按 5 分钟费率估算。未知模型以及无法取得详细用量的工具不会进入估算成本,也不会进入成本覆盖率分母。该数据适合观察趋势,但不等同于账单或订阅席位费用。 每日聚合会在 `teamai pull` 时写入 `stats/.yaml`;原有累计字段继续作为历史总量展示。恢复执行的会话会在原记录上更新,不会重复累计已完成会话。团队仓库只接收聚合计数和按微美元保存的估算总额;prompt 原文与逐请求记录保留在本机。 ### Session Save(会话存档) `teamai session save` 把 dashboard 已有的**单次会话事件流**(工具调用序列、prompt 轮次、干预记录)折叠成一份精简、脱敏的 markdown 摘要——不调用 LLM,也不新增采集路径。 ```bash teamai session save # 存档最近一次会话(本地) teamai session save --session-id # 存档指定会话 teamai session save --push # 把「有价值」的会话推送到团队仓库 teamai session save --push --force # 即便是琐碎会话也推送 teamai session save --push --include-prompt # 额外带上(脱敏后的)首个 prompt 行 ``` **本地(始终执行):** 追加到 `~/.teamai/session-logs/<年-月>.md`。按会话幂等(当月已记录的会话会跳过),且超过 90 天的日志会自动清理。 **团队(`--push`,需显式开启):** 直接提交(不走 PR)到团队仓库的 `sessions//<年-月>.md`——正是 `teamai digest` 读取的路径,于是该会话会出现在 **Session Highlights** 板块。默认只推送**有价值**的会话:出现摩擦(interrupt / tool-reject / correction)或工具使用充分(≥ 3 种不同工具)。琐碎会话除非加 `--force`,否则只留本地。对只读(HTTP 模式)的团队,`--push` 会优雅失败并保留本地日志。 > 隐私:推送到团队的内容默认**只含计数 + 工具名**。首个 prompt 行需通过 `--include-prompt` 显式开启,且即便开启也会经过与别处一致的密钥脱敏(`ghp_…` → ``)。本地日志因为不出本机,会保留脱敏后的首个 prompt 行。 ### Hooks `teamai init` 自动注入的 Hooks: | Hook 事件 | 操作 | |-----------|------| | `SessionStart` | 先为当前 Agent 创建项目根目录(project scope),再自动 pull + 上报会话启动 | | `PostToolUse` | skill 追踪 + 知识贡献检测 + dashboard 上报 | | `UserPromptSubmit` | slash 命令追踪 | | `Stop` | CLI 更新检查 + 上报会话结束 | ```bash teamai hooks list # 查看生效的内置和团队 hooks teamai hooks inject # 重新注入 teamai hooks remove # 移除 ``` inject 和 remove 只会操作你实际已安装的工具(即 `~/./` 根目录已存在的工具)。对于 `toolPaths` 中已配置但未安装的工具,命令不会为其凭空创建根目录。 > **Codex 信任门槛** — Codex(OpenAI / ChatGPT Codex 应用,工具 id 为 `codex`)对非托管 hooks 设有显式的用户信任机制。teamai 写入 `~/.codex/hooks.json` 后,对于新增或变更的 hook,Codex 可能会跳过执行,直到你在 `/hooks` 或 Settings → Hooks 中 review/trust。当检测到 Codex hooks 已安装时,`teamai hooks inject` 与 `teamai doctor` 会输出提示;teamai 从不修改 Codex 的 `[hooks.state]` 来自动信任 —— 信任操作交由你手动完成。 ### 团队 Hooks 声明 团队可在仓库 `hooks/hooks.yaml` 中声明自定义 hooks,`teamai pull` 自动分发到所有成员的 AI 工具: ```yaml hooks: - id: block-secret description: 提交前扫描密钥 event: PreToolUse matcher: Bash command: 'bash -lc "~/.teamai/team-scripts/scan-secret.sh" || true' timeout: 15 tools: [claude, cursor] builtin: disabled: [Hook dispatch post-tool-use TodoWrite] overrides: Hook dispatch stop: { timeout: 20 } ``` | 字段 | 说明 | |------|------| | `id` | 唯一标识,`^[a-z0-9-]+$` | | `event` | Claude PascalCase 事件名(跨工具通用) | | `matcher` | 可选,工具 matcher | | `tools` | 可选,目标工具列表(默认 = 所有 hook 支持的工具) | | `builtin.disabled` | 禁用的内置 hook 列表 | | `builtin.overrides` | 仅可覆盖内置 hook 的 `timeout` | 安全治理: - `sharing.hooks.autoApply: false`(`teamai.yaml`):pull 时仅提示,需手动 `teamai hooks inject` 确认 - `sharing.hooks.requireTeamScripts: true`:拒绝 command 不在 `~/.teamai/team-scripts/` 下的 hook - `TEAMAI_HOOKS_DISABLED=1`:本地禁用所有团队 hooks(内置 hooks 不受影响) ### Agents 资源类型 团队仓库可在 `agents/` 目录下维护自定义 subagent 定义(每个 agent 一个 `*.md` 文件): ```text team-repo/ agents/ code-reviewer.md # 团队自定义 subagent .removed # tombstone(由 teamai remove agents 自动管理) ``` `teamai pull` 会将它们复制到每个 Tier-1 工具的 `agents/` 目录(如 `~/.claude/agents/`)。CLI 内置的 `teamai-recall.md` 与团队 agents 并列部署,但不会被 `teamai push` 上传。 ### OpenCode [OpenCode](https://opencode.ai) 已作为一等工具支持。由于它的配置布局与 Claude 系不同,teamai 对以下几点做了特殊处理: - **作用域。** OpenCode 的用户配置在 `~/.config/opencode/` 下,项目配置在 `/.opencode/` 下——前缀与其他所有工具都不同。teamai 会按 `--scope` 写入正确的位置,且仅在该作用域确实安装了 OpenCode 时才碰它的文件(绝不会为未使用 OpenCode 的用户创建 `~/.config/opencode/`)。Hooks 是唯一的例外——始终写在用户级,原因见下。 - **Skills** 落在 `.opencode/skills/`(项目)或 `~/.config/opencode/skills/`(用户)。OpenCode 也原生读取 `.claude/skills`,但 teamai 仍会写 OpenCode 路径,好让只用 OpenCode 的用户也能拿到。 - **Subagents** 会被渲染成 OpenCode 自己的 `agents/*.md` 格式:frontmatter 带 `description` + `mode: subagent`(以及 `model` 和 `tool_extras.opencode` 中的字段,如 `temperature`);agent 名取自文件名。OpenCode **不**读取 `.claude/agents`,因此这份原生副本是必需的。 - **Rules** 会被复制到 `.opencode/rules/`(或 `~/.config/opencode/rules/`),但 OpenCode 不会自动扫描 rules 目录——文件在被引用前是惰性的。因此 teamai 会往 `opencode.json` 的 `instructions` 数组里加一条 `rules/*.md` glob,并在团队最后一条 rule 消失时再把它移除,且只编辑这一个键、不动你自己的 `instructions` 条目。 - **Hooks** 以 OpenCode *plugin* 形式交付,而非配置文件条目——OpenCode 没有 `hooks` 数组,它会**同时**加载 `~/.config/opencode/plugin/` 和 `/.opencode/plugin/` 下的 JS/TS 插件。两个目录都有插件时会被加载两次,每个事件也就派发两次,因此 teamai 只保留一份:写在用户目录的 `teamai-hooks.ts`,覆盖所有项目;早期布局残留的项目级副本会在下次同步时被删除。这与其他工具一致——它们的 `settings.json` hooks 同样放在 HOME,靠传给 `hook-dispatch` 的 `cwd` 做作用域判断。插件订阅 OpenCode 自己的事件,并 shell 到其他所有工具共用的 `teamai hook-dispatch` 入口。事件映射对齐 Claude 内置集合:`session.created` → session-start、`session.idle` → stop、`chat.message` → prompt-submit、`tool.execute.after` → post-tool-use。插件会转发与其他工具一致的 STDIN 负载(`cwd`、`tool_name`、`tool_input`、`prompt`),并把 OpenCode 的小写工具 id(`skill`、`todowrite`)映射回 handler 注册表期望的 PascalCase matcher。OpenCode 无法把 hook 的 stdout 回注到会话,因此 hooks 只为副作用运行(状态上报 / 同步 / 更新)。注意 OpenCode 会 **await** 它的具名 hook(`chat.message`、`tool.execute.after`),所以这两个事件的派发会短暂等待 `teamai` 子进程后 agent 才继续;错误始终被吞掉,hook 永远不会让会话失败。服务端下发的 agent hook(`teamai-agent-.ts`)同样装在这个用户级 plugin 目录下。 - **MCP** server 位于共享 `opencode.json` 的 `mcp` 键下(详见上文 MCP 章节)。 ### Qoder Qoder 已作为内置目标支持。TeamAI 会将 Skills、Rules 和 Subagents 分别下发到 `.qoder/skills/`、`.qoder/rules/` 和 `.qoder/agents/`。Hooks 与 MCP Server 会合并进对应作用域的 `.qoder/settings.json`,并保留用户已有的其他设置;这些路径与 Qoder 的用户级和项目级配置约定一致。 ### ZCode ZCode 已作为内置目标支持。Skills 下发到 `.zcode/skills/`(ZCode 同时会读取中央目录 `~/.agents/skills/`,该目录由 `agents` 条目覆盖),Subagents 以 Claude 风格 Markdown 下发到 `.zcode/agents/`。Hooks 会合并进共享的 `~/.zcode/cli/config.json`,并保留插件状态等无关键值。写入器为你处理了两个 ZCode 特有的细节: - ZCode 的配置文件钩子**默认禁用**——TeamAI 会强制置 `hooks.enabled: true`,确保写入的条目真正生效。 - 钩子条目使用 `process` 类型(`bash -lc ` 以 argv 向量执行)而非 shell 字符串,规避 Windows 下 PATH 解析命中 WSL `bash.exe` 而非 Git Bash 的陷阱。 以上路径已对照 ZCode 桌面端实测验证:设置页「新建子智能体」写入的就是 `~/.zcode/agents/*.md`,反向放入的文件也会出现在页面的已安装列表中。MCP Server 下发到 `~/.agents/mcp.json`(用户级,Claude 的 `mcpServers` 结构——正是 ZCode 自己的 MCP 设置页读取的文件)。项目级暂未接入:ZCode 的工作区 MCP 使用不同的键(`.zcode/config.json` 内的 `mcp.servers`),Claude 写入器无法生成该结构。ZCode 暂无用户级 Rules 目录约定,因此 Rules 不同步。 ### JoyCode JoyCode 已作为内置目标支持。Skills、Rules 和 Subagents 分别下发到 `.joycode/skills/`、`.joycode/rules/` 和 `.joycode/agents/`。Rules 使用与 Cursor 兼容的 `.mdc` 格式,包括下文所述的派生 frontmatter 和仅正文往返同步;Subagents 使用带 YAML frontmatter 的 Markdown 文件。 JoyCode 规则清理采用保守策略:不在团队规则列表中的本地 `.mdc` 和 `.md` 文件会被保留,只有团队明确记录了删除标记(tombstone)才会清理。这能保护同一目录中的个人规则;缺少删除记录的旧团队副本也会保留,不会猜测其已过期。 对于以 YAML 保存的团队 Agent,push 会将本地文件与对应工具的渲染结果比较,只将真实编辑合并回原始配置。部署范围 `targets`、其他工具的元数据,以及本地格式未输出的字段都会保留。遇到冲突或无法解析的编辑时跳过回写,不会替换团队源文件。 **Hooks 与手动同步**:JoyCode 当前没有提供生命周期 Hooks 机制或专用启动适配器(无类似 `settings.json` hooks 数组或 `hooks.json` 的事件配置)。因此,打开或启动 JoyCode 不会触发 TeamAI 的 `SessionStart` 事件,无法进行后台自动拉取、使用指标上报(`teamai track`)或自动更新检测。JoyCode 用户需要通过在终端手动运行 `teamai pull` 来同步团队最新技能、规则与 Agent,通过 `teamai push` 贡献变更。若 JoyCode 后续版本提供了 Hooks 或插件生命周期机制,将通过专用适配器接入。 ### Cursor Cursor 的项目规则必须以 **`.mdc`** 文件形式放在 `.cursor/rules/` 下,且带 YAML frontmatter——放在那里的纯 `.md` 会被 Cursor 直接忽略。因此 teamai 向 Cursor 写规则时用 `.mdc`(其他工具仍写纯 `.md`),并从团队规则派生 frontmatter: - 带 `paths:` 列表的规则会转成 `globs: "<逗号拼接>"` + `alwaysApply: false`(上下文中有匹配文件时 Cursor 自动附加该规则)。值加引号是因为以 `*` 开头的 glob 不加引号时并非合法 YAML。 - 无 `paths` 的规则(团队强制规则)会转成 `alwaysApply: true`(每个 Cursor 会话都应用)。 两种格式之间只有 markdown 正文互通,各自的 frontmatter 归各自所有。`pull` 时 Cursor 的 frontmatter 由机器派生(正文原样拷贝,仅规范化首尾空行),因此 `pull` → `push` 往返不会被误判为内容变更。`push` 时,在 `.cursor/rules/*.mdc` 里改完正文再执行 `teamai push`,**只有正文**会回流上游——团队规则自己的 `paths:` frontmatter 会被保留,规则的作用域不会被悄悄丢掉。 有两类文件刻意**不会**从 Cursor 规则目录推送: - 团队仓库中没有同名规则的 `.mdc`。`.cursor/rules/` 同时也是 Cursor 自带的 *New Cursor Rule* 命令写入个人规则的地方,teamai 不会把它们当作新的团队资源。 - CLI 内置规则——它们是被下发的(对 Cursor 同样写成 `.mdc`),而非同步而来。 从旧版本升级:旧布局写入的 `.cursor/rules/*.md` 是无效文件(Cursor 从未读取过它们),因此 `pull`、`remove`、`uninstall` 会连同 `.mdc` 一起删除。你自己放在那里的 `.md` 不受影响。 ### 其他 ```bash teamai doctor # 配置诊断 teamai stats # skill 使用统计 teamai update --check # 仅检查 CLI 更新,不安装 teamai update # 检查并安装 CLI 更新 teamai digest # 生成团队活动周报 teamai remove skills # 删除资源 teamai remove rules teamai remove agents teamai remove mcp ``` 自动更新在 Stop hook 中执行,可通过两层控制: | 层级 | 文件 | 字段 | 值 | |------|------|------|------| | 团队默认 | `teamai.yaml` | `autoUpdate` | `true`(默认)/ `false` | | 用户覆盖 | `~/.teamai/config.yaml` | `updatePolicy` | `auto` / `prompt` / `skip` | 用户级 `updatePolicy` 始终优先于团队级 `autoUpdate`。 ### CI 集成 `teamai ci extract-mr` 接入 CI 流水线,从每个 MR/PR 自动提取知识: ```bash # 评论模式:以评论形式发布建议(在 PR 打开/更新时运行) teamai ci extract-mr --url "$MR_URL" --mode comment --individual-comments # 写入模式:合并后将审批通过的建议写入知识库 teamai ci extract-mr --url "$MR_URL" --mode write --team-repo ./team-repo --individual-comments ``` 工作流程: 1. MR 打开/更新 → CI 触发 `--mode comment`,提取知识建议并发布为 MR 评论 2. Reviewer 审查评论,对不需要的建议添加拒绝标记(GitHub 👎 / TGit ☝️) 3. MR 合并 → CI 触发 `--mode write`,将未被拒绝的建议写入团队知识仓库 开箱即用模板: - `examples/ci/github-actions-mr-extract.yml`(GitHub Actions) - `examples/ci/coding-ci-mr-extract.yaml`(Coding CI / TGit) ### 跨团队 Skill 订阅 `teamai source` 让你订阅其他团队的公共 skill 仓库,pull 时自动获取最新 skills: ```bash # 添加订阅源 teamai source add https://github.com/other-team/teamai-public.git --name other-team # 查看订阅列表 teamai source list # 浏览订阅源的 skills teamai source browse other-team # 移除订阅(同时清理其 skills) teamai source remove other-team ``` 订阅源的 skills 在 `teamai pull` 时自动同步到本地,与团队自有 skills 共存。`teamai source add`/`remove` 会立即更新当前 scope 的团队仓,因此改动尚未提交时,本机的 `list`、`browse` 和 `pull` 也会使用它。订阅配置存储在该仓库 `teamai.yaml` 的 `sources` 字段中。运行 `teamai push` 会开一个包含配置改动的 PR;合入后,每位成员的 `teamai pull` 都会自动获取到新的订阅源。 源仓只会共享它在自己 `teamai.yaml` 的 `publicSkills` 列表里显式声明的 skill。如果对方仓库没有 `teamai.yaml`,或没有声明 `publicSkills`,`teamai source add` 仍会成功,但会警告该源将同步 **0 个 skill**——需要对方团队先发布 `publicSkills` 列表,才会有内容流转过来。 #### HTTP 源 除了 git 订阅源,还可以在已有 git 主仓的基础上附加一个 HTTP 源——适用于服务端管理的 skill 下发: ```bash # 附加 HTTP 源(git 主仓不受影响) teamai source add-http https://your-team-host/api --token # 查看(在 "HTTP source" 下显示) teamai source list # 解绑并卸载其资源 teamai source remove-http ``` HTTP 源通过 hook dispatch 在每次 session 中上报状态并拉取 skill 指令。每个安装仅支持一个 HTTP 源。若主仓本身已是 HTTP 模式(`init --http`),则 `add-http` 不可用(主仓已占用 HTTP 配置)。 --- ## 配置文件参考 ### teamai.yaml(远端团队配置) ```yaml team: my-team description: 团队 AI 资源仓库 repo: https://github.com/yourorg/yourrepo.git provider: github # scope: 若存在则忽略——本机安装位置由 `teamai init --scope` 决定 reviewers: - reviewer1 packages: npm: - name: typescript version: "*" sharing: rules: enforced: [code-review-guide] recall: enabled: false # 可选;成员可在本地覆盖 docs: localDir: ./.teamai/docs env: injectShellProfile: true coAuthor: enabled: false # 可选,为全团队去除 AI 工具提交尾注 contributeHint: enabled: true # 可选,false = 高摩擦 session 结束后不再提示 /teamai-share-learnings ``` ### config.yaml(本地配置) ```yaml repo: localPath: /path/to/.teamai/team-repo remote: https://github.com/yourorg/yourrepo.git username: your-name updatePolicy: auto scope: project # project(init 默认)或 user projectRoot: /path/to/project # 仅 project scope inheritUserScope: true # 可选,仅 project scope,默认 false coAuthorEnabled: true # 可选,每机器的 co-author 覆盖 contributeHintEnabled: false # 可选,每机器覆盖 sharing.contributeHint.enabled ``` --- ## 卸载 `teamai uninstall` 会智能清理所有 teamai 管理的资源,**保留用户自建内容**。 ```bash # 预览将要移除的每个受管路径(不做实际变更) teamai uninstall --dry-run # 交互式确认卸载 teamai uninstall # 跳过确认直接卸载(适合脚本/CI) teamai uninstall --force # 只卸载某一个工具的资源(与 init --agent 对称) teamai uninstall --agent claude ``` 移除内容: - AI 工具 settings 中的 teamai hooks - CLAUDE.md 中的 teamai rules 块(保留用户自写内容) - 团队同步的 skills,包括 OpenClaw workspace skills(保留用户自建 skills) - 团队同步的 rules - 团队同步的自定义 agents 和 CLI 内置 agents(保留用户自建 agents) - Shell profile 中的 env 块 - `~/.teamai/` 目录 ### 只卸载单个工具(`--agent `) `--agent ` 只移除该工具的 teamai 资源(hooks、CLAUDE.md 块、skills、rules、团队同步的自定义 agents、内置 agents)。工具名即 `toolPaths` 的键(如 `claude`、`codex`、`codebuddy`),匹配大小写不敏感。传入未知工具名会直接报错并列出可用工具、不执行任何删除,并以非零状态码退出。 跨工具共享资源(shell profile env 块、docs 目录、`~/.teamai/`)**仅当该工具自身存在 teamai 资源、且它是最后一个仍在使用 teamai 的工具时**才一并移除,否则会为其余工具保留。(因此,定向卸载一个自身没有任何 teamai 资源的工具是 no-op,即便它恰好是唯一的工具,也不会删除共享资源。) 该排除是持久的:`uninstall --agent ` 会把该工具从 `enabledAgents` 移除并记入 `disabledAgents`,因此之后的 `pull`(或其他工具的 session-start hook)不会再把它的 skills、rules、agents、CLAUDE.md 块或 hooks 重新装回。重新执行 `init --agent ` 会清除该排除、恢复对该工具的同步。 卸载后如需重新加入: ```bash teamai init --repo https://github.com/yourorg/yourrepo --scope user --role --force teamai pull ``` --- ## 常见问题 FAQ **Q: User scope 和 Project scope 可以共存吗?** 可以,但 project scope 默认保持隔离。当前工作目录包含 project scope 配置时,该项目生效并跳过 user scope。先初始化 user scope,再使用 `--inherit-user-scope` 初始化项目(或在项目本地配置中设置 `inheritUserScope: true`),即可组合安全资源和 Recall 结果;可执行配置和控制面配置(`env`、MCP)仍只使用 project scope;hooks 例外——非-self 的 project scope 会把 hooks 注入到 HOME,以便 `hook-dispatch` 依据 `cwd` 门控(详见 Hooks 章节)。 **Q: `teamai init` 提示已初始化?** 交互模式下会提示是否覆盖,输入 `y` 即可。也可用 `--force` 跳过确认: ```bash teamai init --repo https://github.com/yourorg/yourrepo --force ``` **Q: 在项目里执行 `teamai init` 后没有 `.claude/`(或 `.cursor/`、`.codebuddy/`)目录?** 这是预期行为。`init` 不知道你会打开哪个 Agent。在项目中打开 Claude Code / Cursor / CodeBuddy:SessionStart hook 会创建该工具的项目根目录并随后 pull。单独执行 `teamai pull` 不会为缺失的 Agent 根目录建目录。 **Q: Hooks 没有自动触发?** ```bash teamai doctor # 诊断 teamai hooks inject # 重新注入 ``` **Q: push 提示 "no new resources detected"?** `push` 只检测新增或修改的资源。没有变更时无需推送。 **Q: 如何删除已推送的资源?** ```bash teamai remove skills teamai remove rules ``` --- > **仓库**:https://github.com/Tencent/teamai-cli > **问题反馈**:https://github.com/Tencent/teamai-cli/issues