teamai-cli 0.16.9 → 0.17.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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. See [standa
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ### 💥 破坏性变更
8
+
9
+ - **移除 `auto-recall` PostToolUse hook**:不再在 `Bash`/`Grep`/`WebSearch`/`WebFetch` 工具调用后被动、隐式地自动搜索团队知识库——这条链路噪音大、命中率低,且与更早前上线的 `teamai-recall` subagent(任务开始前主动检索,支持 codebase 图谱 drill-down、输出结构化摘要)功能重叠。已安装环境的 hooks 配置会在下次 `teamai pull` / `hooks inject` 时自动清理,无需手动迁移
10
+ - `contribute-check` 的知识空白检测(Phase 2)改为由 `teamai recall`(手动 + `teamai-recall` subagent 均会触发)记录召回质量,缓存格式不变,功能保留
11
+ - `TEAMAI_RECALL_DISABLED=1` 现在控制 `teamai recall` 的质量记录而非 auto-recall hook
12
+
7
13
  ### ✨ 新功能
8
14
 
9
15
  - **跨 agent skills 视图**:`teamai list` 新增 `--source <repo|local|all>` 和 `--agent <id>` 参数(默认 `--source all`)。`local` / `all` 模式会扫描所有已安装 AI agent 的 skills 目录,每个 skill 标注来源 `[team]` / `[builtin]` / `[source:<name>]` / `[local-only]`。`--verbose` 时展开每个 agent 的 skill 列表与描述摘要。未安装的 agent 不出现在输出里
package/README.md CHANGED
@@ -67,39 +67,105 @@ The CLI picks a provider automatically from the repo URL:
67
67
  - `yourorg/yourrepo` or `https://github.com/yourorg/yourrepo` → GitHub
68
68
  - `https://git.woa.com/yourteam/yourrepo` → TGit
69
69
 
70
+ ### Read-only consumers (HTTP team repo, no git)
71
+
72
+ Some users or agents only need to *consume* a team's skills/rules — no git clone, no push. Onboard them over plain HTTP with just an API key:
73
+
74
+ ```bash
75
+ teamai init --http https://your-team-host/api --token <api-key>
76
+ ```
77
+
78
+ - **Read-only:** `push` / `contribute` / `remove` are disabled for HTTP repos.
79
+ - The API key is stored `0600` (never written to config, never committed); `TEAMAI_API_TOKEN` is also honored.
80
+ - If the team-repo endpoint (`/repo`) is not live yet, init falls back to **reporting-only mode** — hooks and status reporting are wired immediately, and skills/rules begin syncing automatically once the endpoint is available.
81
+
82
+ #### Agent status reporting
83
+
84
+ Once initialized, supported agents (CodeBuddy / WorkBuddy) report their installed-skill state on session start and pull down server-managed skill install / update / uninstall commands, driven by the existing hook dispatch (`session-start` → report + sync, `prompt-submit` → sync). Failed deliveries are buffered to an offline queue and retried next time.
85
+
86
+ > **Privacy.** The install path and machine id are only hashed *locally* to derive a stable `local_agent_id` — neither is ever uploaded.
87
+
88
+ <details>
89
+ <summary><b>HTTP contract</b> (for backend implementers) — what the <code>--http</code> endpoint must serve</summary>
90
+
91
+ The value you pass to `--http <baseUrl>` is the base; every endpoint is relative to it and authenticated with `Authorization: Bearer <api-key>`.
92
+
93
+ | Endpoint | Method | Purpose | Path |
94
+ |----------|--------|---------|------|
95
+ | `{baseUrl}/repo` | GET | Team-repo snapshot (skills + rules/docs) | **fixed** |
96
+ | `{baseUrl}/api/local-agent/report` | POST | Session start: upsert agent + installed skills | default, configurable |
97
+ | `{baseUrl}/api/local-agent/sync` | POST | Report status + return pending skill commands | default, configurable |
98
+ | `{baseUrl}/api/local-agent/commands/ack` | POST | Ack one command (`{ id, status, error }`) | default, configurable |
99
+
100
+ `GET /repo` returns JSON (a 404 or non-JSON 200 ⇒ the client enters reporting-only mode):
101
+
102
+ ```json
103
+ {
104
+ "version": "<opaque cache key, e.g. a commit hash>",
105
+ "files": [{ "path": "rules/foo.md", "content": "..." }],
106
+ "commands":[{ "type": "install_skill", "skill_slug": "x", "skill_version": "1.0.0", "download_url": "https://signed-url/..." }]
107
+ }
108
+ ```
109
+
110
+ - `files[]` are written verbatim into the local repo tree (path-traversal guarded); `commands[]` install/update/uninstall skills.
111
+ - A skill `download_url` is fetched **directly** — it carries its own signed auth in the query string, so no `Bearer` header is sent. It must resolve to a `.zip` whose root is either `<slug>/SKILL.md …` or a flat `SKILL.md …`.
112
+
113
+ **Fixed vs configurable.** The `/repo` path is fixed; the three reporter paths are defaults you can override. The JSON shapes above are the contract. Knobs (env vars):
114
+
115
+ | Variable | Effect |
116
+ |----------|--------|
117
+ | `TEAMAI_API_TOKEN` | API key (alternative to `--token`) |
118
+ | `TEAMAI_REPORT_ENDPOINT` | Reporter base URL (defaults to the `--http` URL) |
119
+ | `TEAMAI_REPORT_PATHS` | JSON `{ "report", "sync", "ack" }` to override the three reporter paths |
120
+ | `TEAMAI_REPORT_AGENTS` | Comma-separated agents that report (default `workbuddy,codebuddy`) |
121
+ | `TEAMAI_SKILL_DOWNLOAD_HOSTS` | Comma-separated host allowlist for skill `download_url` (empty = allow all) |
122
+
123
+ </details>
124
+
70
125
  ## Commands
71
126
 
72
127
  | Command | Description |
73
128
  |---------|-------------|
74
- | `teamai init [--scope <user\|project>] [--role <id>] [--force]` | Initialize (auto-installs gf CLI, OAuth login, links repo, registers member, configures reviewers, injects hooks) |
75
- | `teamai push [--all] [--role <id>]` | Push local new resources to a dedicated branch and open a Merge Request; new skills prompt interactively for a target namespace (override with `--role`) |
76
- | `teamai pull [--silent]` | Pull team resources and inject them into local AI tools (both scopes pulled sequentially) |
77
- | `teamai status` | Show the diff between local and the team repo |
78
- | `teamai list [type] [--source repo\|local\|all] [--agent <id>]` | List resources (skills\|rules\|docs\|env\|wiki). With `--source local` or `all`, scans skills directories of installed AI agents and tags each skill's origin (`[team]` / `[builtin]` / `[source:<name>]` / `[local-only]`) |
79
- | `teamai skill [list\|show <name>]` | List all skills by default; `show <name>` prints the skill's origin, contributors, installed-agent list, and description summary |
80
- | `teamai members` | List registered team members |
81
- | `teamai remove <type> <name>` | Remove a resource from both the team repo and local, then open an MR (skills\|rules\|wiki) |
82
- | `teamai roles` | Manage team roles (`init`/`list`/`set`/`add`/`remove`/`update`) |
83
- | `teamai source` | Manage cross-team skill subscription sources (`add`/`remove`/`list`/`browse`) |
84
- | `teamai contribute --file <path> [--scope <user\|project>]` | Push an AI-generated experience document to the team repo |
85
- | `teamai recall <query>` | Search the team knowledge base, automatically merging user + project scope results |
86
- | `teamai import --from-repo <url>` | Clone a remote repo and generate a per-repo summary under `docs/team-codebase/repos/<slug>.md`; AI recommends a business domain and persists the assignment to `.teamai/domains.yaml` |
87
- | `teamai import --from-repo-list <yaml>` | Batch import a whitelist of repos with concurrency control, then aggregate the results into per-domain views |
88
- | `teamai import --from-org <org> --bootstrap` | List every repo under an organization (GitHub or TGit), AI-cluster them into business domains, and run an interactive review before the first full sync |
89
- | `teamai import --from-iwiki <id> [--iwiki-dual]` | Import iWiki documents as learnings; in dual mode also extract business-API / external-knowledge / glossary sections into `docs/team-codebase/external-knowledge.md` |
90
- | `teamai cache --status \| --gc` | Inspect or garbage-collect the shallow-clone cache at `~/.teamai/cache/repos/` (LRU + size cap, default 5GB) |
91
- | `teamai codebase --lint [--fix]` | Cross-file consistency lint over `docs/team-codebase` and `.teamai/`; reports anchor / orphan / source-invalid / sync-stale issues; `--fix` applies low-risk mechanical fixes |
92
- | `teamai review [id] [--apply \| --reject \| --all-apply]` | Inspect and process pending codebase changes from `.teamai/pending-review.jsonl`; `--apply` patches in place via section anchors |
93
- | `teamai domains drift [url] [--apply \| --lock \| --apply-all]` | Inspect and resolve domain-drift signals; `--apply` reassigns the repo to the recommended domain and refreshes the aggregate views |
94
- | `teamai digest` | Generate a team AI usage weekly digest (skill leaderboard, new/updated skills, session summaries) |
95
- | `teamai hooks` | Manage AI-tool hooks (list / inject / remove) |
96
- | `teamai ci extract-mr --url <url> [--mode comment\|write\|both] [--individual-comments]` | CI pipeline integration: extract knowledge from MR/PR, post as comments, and write to team repo after merge. With `--individual-comments`, each suggestion is posted separately with reaction/reject support (GitHub 👎 / TGit ☝️) |
97
- | `teamai uninstall [--force]` | Uninstall teamai: remove hooks, rules, skills, env, docs, and `~/.teamai/` |
98
- | `teamai doctor` | Diagnose configuration problems |
99
-
100
- Global options:
101
- - `--dry-run` — preview mode, no real changes
102
- - `--verbose, -v` verbose output
129
+ | `teamai init` | Initialize (OAuth login, link repo, register member, inject hooks) |
130
+ | `teamai push` | Push local resources to a branch and open a Merge Request |
131
+ | `teamai pull` | Pull team resources and inject into local AI tools |
132
+ | `teamai status` | Show local vs team repo diff |
133
+ | `teamai recall <query>` | Search the team knowledge base (BM25 + graph-boost) |
134
+ | `teamai recall enable/disable/status` | Toggle or check recall state (controls auto-recall hooks + subagent deployment) |
135
+ | `teamai import --dir <path>` | Extract code knowledge graph from a local directory |
136
+ | `teamai import --from-repo <url>` | Import a repo's code knowledge graph (`teamwiki/`) |
137
+ | `teamai import --from-org <org>` | Batch import all repos under an organization |
138
+ | `teamai import --from-repo-list <yaml>` | Batch import repos from a whitelist |
139
+ | `teamai import --from-mr <url>` | Extract learning from a merged MR/PR |
140
+ | `teamai import --from-iwiki <id>` | Import iWiki documents as learnings |
141
+ | `teamai codebase --lint` | Knowledge graph health check |
142
+ | `teamai contribute` | Share session experience to team repo |
143
+ | `teamai members` | List team members |
144
+ | `teamai roles` | Manage team roles and namespaces |
145
+ | `teamai remove <type> <name>` | Remove a resource and open MR |
146
+ | `teamai digest` | Generate weekly team usage digest |
147
+ | `teamai doctor` | Diagnose configuration issues |
148
+ | `teamai uninstall` | Remove all teamai resources and hooks |
149
+
150
+ Global options: `--dry-run`, `--verbose`
151
+
152
+ Import options: `--incremental`, `--skip-enrich` (skip AI calls, only extract + graph)
153
+
154
+ <details>
155
+ <summary>More commands (management, CI, analytics)</summary>
156
+
157
+ | Command | Description |
158
+ |---------|-------------|
159
+ | `teamai list [type]` | List resources (skills\|rules\|docs\|env\|wiki) |
160
+ | `teamai skill [show <name>]` | Inspect skill metadata and contributors |
161
+ | `teamai source` | Manage cross-team skill subscriptions |
162
+ | `teamai tags` | Manage tag-based resource filtering |
163
+ | `teamai env` | Manage team environment variables |
164
+ | `teamai hooks` | Manage AI-tool hooks |
165
+ | `teamai cache --gc` | Garbage-collect clone cache |
166
+ | `teamai ci extract-mr --url <url>` | CI: extract knowledge from MR, post comments, write after merge |
167
+
168
+ </details>
103
169
 
104
170
  ## How It Works
105
171
 
@@ -316,6 +382,60 @@ Author: alice | Score: 12.0 | Tags: fuse, deploy
316
382
 
317
383
  The index is rebuilt automatically on every `teamai pull`. Indexes built by older versions (no `version` field or missing `type`) are detected and rebuilt transparently on first use.
318
384
 
385
+ ### Recall Enable / Disable
386
+
387
+ Recall is controlled at two levels — team admin sets the default, individual users can override:
388
+
389
+ | Layer | File | Field | Effect |
390
+ |-------|------|-------|--------|
391
+ | Team default | `teamai.yaml` | `sharing.recall.enabled` | `true` / `false` (default: `false`) |
392
+ | User override | `~/.teamai/config.yaml` | `recallEnabled` | `true` / `false` — wins over team default |
393
+ | Env var | shell | `TEAMAI_RECALL_DISABLED=1` | Force-disable all recall hooks (quick kill-switch) |
394
+
395
+ ```bash
396
+ teamai recall enable # enable recall + deploy subagent & rules
397
+ teamai recall disable # disable recall + remove subagent & rules
398
+ teamai recall status # show effective state (team default + user override)
399
+ ```
400
+
401
+ When recall is disabled, `teamai pull` skips deploying the recall subagent, recall rules block, and TodoWrite reminder hook. The `teamai recall <query>` manual search command still works regardless of this setting.
402
+
403
+ ### Codebase Knowledge Graph (teamwiki/)
404
+
405
+ `teamai codebase --extract` (or `teamai import --from-repo`) parses your source repos and writes a structured knowledge graph under `teamwiki/`:
406
+
407
+ ```
408
+ teamwiki/
409
+ ├── router.md # Navigation hub — lists every imported repo
410
+ ├── index.md # Global index (auto-generated, with timestamp)
411
+ ├── hot.md # Active working memory (reserved for Phase 4)
412
+ ├── source-manifest.json # Per-file hash manifest for incremental extraction
413
+ ├── .indices/
414
+ │ └── graph-index.json # Knowledge graph: nodes + edges (JSON)
415
+ ├── evidence/
416
+ │ └── code/
417
+ │ └── <project>/ # One directory per imported repo
418
+ │ ├── index.md # Project summary (fact count + page list)
419
+ │ ├── component.md # Functions / classes / components
420
+ │ ├── interface.md # Interface and type definitions
421
+ │ ├── config.md # Config keys (env vars, TOML keys, etc.)
422
+ │ ├── error.md # Error-handling patterns
423
+ │ └── relation-<dir>.md # Import relationships grouped by top-level dir
424
+ └── gaps/
425
+ └── detected.md # Detected knowledge gaps (IMPL_MISSING, LOW_CONNECTIVITY, …)
426
+ ```
427
+
428
+ **graph-index.json** stores the extracted graph. A real example: 11 HAI team repos → **2 218 nodes, 852 edges**.
429
+
430
+ | Field | Description |
431
+ |-------|-------------|
432
+ | `nodes[].kind` | `component` (function/class) or `config` (config key) |
433
+ | `edges[].relation` | `imports` — cross-file and cross-repo dependency |
434
+
435
+ Cross-repo edges are detected automatically by PascalCase label matching.
436
+
437
+ `teamai recall` uses this graph for **BM25 + graph-boost** retrieval: keyword hits are re-ranked by graph proximity, so you get structurally relevant results, not just textual matches.
438
+
319
439
  ### TodoWrite reminder hook
320
440
 
321
441
  `teamai pull` registers a PostToolUse hook on the `TodoWrite` tool. The first time a session writes a TODO list, the hook injects a one-time reminder asking the agent to invoke `teamai-recall` if it has not already done so. Per-session deduplication uses `~/.teamai/sessions/<sid>-todowrite-hint.json` (24 h TTL).
@@ -326,7 +446,7 @@ To disable the reminder globally, set:
326
446
  export TEAMAI_RECALL_DISABLED=1
327
447
  ```
328
448
 
329
- The same env var also disables the auto-recall hook.
449
+ The same env var also disables `teamai recall`'s quality tracking (used by contribute-check's knowledge-gap detection).
330
450
 
331
451
  ### `agents` resource type
332
452
 
@@ -341,6 +461,45 @@ team-repo/
341
461
 
342
462
  `teamai pull` copies them into every Tier-1 tool's `agents/` directory (e.g. `~/.claude/agents/`). The CLI built-in `teamai-recall.md` is deployed alongside team agents and is **excluded** from `teamai push` (it is CLI-managed, not team-managed).
343
463
 
464
+ ### `hooks` resource type (team-declared hooks)
465
+
466
+ Beyond the built-in operational hooks the CLI injects, a team can declare its **own** hooks once in the repo and have `teamai pull` adapt and deliver them to every AI tool (Claude Code, CodeBuddy, Cursor, …). Declare them in `hooks/hooks.yaml`:
467
+
468
+ ```yaml
469
+ hooks:
470
+ - id: block-secret # unique, ^[a-z0-9-]+$ — used for the marker + manifest
471
+ description: 提交前扫描密钥 # written into the hook description
472
+ event: PreToolUse # Claude PascalCase event name (the cross-tool lingua franca)
473
+ matcher: Bash # optional tool matcher
474
+ command: 'bash -lc "~/.teamai/team-scripts/scan-secret.sh" || true'
475
+ timeout: 15 # optional, seconds
476
+ tools: [claude, cursor] # optional; default = all hook-capable tools
477
+
478
+ # Optional: tune the CLI's own built-in hooks (whitelisted fields only)
479
+ builtin:
480
+ disabled: [Hook dispatch post-tool-use TodoWrite] # drop a built-in hook
481
+ overrides:
482
+ Hook dispatch stop: { timeout: 20 } # only `timeout` may be overridden
483
+ ```
484
+
485
+ - `teamai pull` reconciles built-in (A) + team (B) hooks into each tool on every session start (it bypasses the "already synced" fast-path, so new/changed hooks self-heal automatically).
486
+ - Team hooks are isolated from built-in hooks by a `[teamai:hook:<id>]` marker and tracked in `~/.teamai/managed-hooks.json`, so removing one from `hooks.yaml` cleanly removes it from every tool on the next pull — built-in hooks are never disturbed.
487
+ - Disk format is unchanged and byte-identical for built-in hooks, so upgrading the CLI is a zero-diff, zero-regression operation for already-installed machines.
488
+
489
+ Audit, force-apply, or strip the effective hooks:
490
+
491
+ ```bash
492
+ teamai hooks list # list effective built-in (A) + team (B) hooks
493
+ teamai hooks inject # force-reconcile A + B into all tools
494
+ teamai hooks remove # remove all teamai-managed hooks (A + B)
495
+ ```
496
+
497
+ > **Security.** Team hooks are arbitrary shell commands that run automatically on session events — treat the repo's write access as an execution surface (governed by MR review, same as `env.yaml`). Guards:
498
+ > - Commands are printed for transparency when applied (unless `--silent`).
499
+ > - `sharing.hooks.autoApply: false` (in `teamai.yaml`) holds team hooks during `pull` and only hints — the user must run `teamai hooks inject` to consent.
500
+ > - `sharing.hooks.requireTeamScripts: true` rejects any team hook whose command is not under `~/.teamai/team-scripts/`.
501
+ > - Set `TEAMAI_HOOKS_DISABLED=1` to veto all team hooks locally (built-in hooks still apply).
502
+
344
503
  ## Update
345
504
 
346
505
  ```bash
package/README.zh-CN.md CHANGED
@@ -67,39 +67,105 @@ CLI 会根据用户传入的 repo URL 自动选择 provider:
67
67
  - `yourorg/yourrepo` 或 `https://github.com/yourorg/yourrepo` → GitHub
68
68
  - `https://git.woa.com/yourteam/yourrepo` → TGit
69
69
 
70
+ ### 只读消费者(HTTP 团队仓库,免 git)
71
+
72
+ 有些用户或 agent 只需要*消费*团队的 skills/rules——不需要 git clone,也不需要 push。用一个 API key 即可通过纯 HTTP 接入:
73
+
74
+ ```bash
75
+ teamai init --http https://your-team-host/api --token <api-key>
76
+ ```
77
+
78
+ - **只读**:HTTP 仓库下 `push` / `contribute` / `remove` 均被禁用。
79
+ - API key 以 `0600` 权限保存(不写入 config,也不会被提交);同时支持 `TEAMAI_API_TOKEN` 环境变量。
80
+ - 如果团队仓库端点(`/repo`)尚未上线,init 会回落到 **reporting-only 模式**——hooks 和状态上报立即生效,待端点可用后 skills/rules 会自动开始同步。
81
+
82
+ #### Agent 状态上报
83
+
84
+ 初始化后,受支持的 agent(CodeBuddy / WorkBuddy)会在 session 启动时上报本地已安装 skill 的状态,并拉取服务端下发的 skill 安装 / 更新 / 卸载命令,全部挂在既有 hook dispatch 上(`session-start` → report + sync,`prompt-submit` → sync)。下发失败会进离线队列,下次重试。
85
+
86
+ > **隐私**:install path 和 machine id 仅在*本地*哈希以派生稳定的 `local_agent_id`,二者都不会上报。
87
+
88
+ <details>
89
+ <summary><b>HTTP 契约</b>(面向后端实现者)—— <code>--http</code> 端点需要提供哪些接口</summary>
90
+
91
+ `--http <baseUrl>` 传入的是基础地址,所有端点都相对于它,并统一用 `Authorization: Bearer <api-key>` 鉴权。
92
+
93
+ | 端点 | 方法 | 用途 | 路径 |
94
+ |------|------|------|------|
95
+ | `{baseUrl}/repo` | GET | 团队仓库快照(skills + rules/docs) | **固定** |
96
+ | `{baseUrl}/api/local-agent/report` | POST | session 启动:upsert agent + 已装 skill | 默认,可配置 |
97
+ | `{baseUrl}/api/local-agent/sync` | POST | 上报状态 + 返回待执行的 skill 命令 | 默认,可配置 |
98
+ | `{baseUrl}/api/local-agent/commands/ack` | POST | 回执单条命令(`{ id, status, error }`) | 默认,可配置 |
99
+
100
+ `GET /repo` 返回 JSON(返回 404 或非 JSON 的 200 ⇒ 客户端进入 reporting-only 模式):
101
+
102
+ ```json
103
+ {
104
+ "version": "<不透明的缓存 key,例如 commit hash>",
105
+ "files": [{ "path": "rules/foo.md", "content": "..." }],
106
+ "commands":[{ "type": "install_skill", "skill_slug": "x", "skill_version": "1.0.0", "download_url": "https://signed-url/..." }]
107
+ }
108
+ ```
109
+
110
+ - `files[]` 原样写入本地仓库树(带路径穿越防护);`commands[]` 负责 skill 的安装/更新/卸载。
111
+ - skill 的 `download_url` 是**直连**拉取——它在 query string 里自带签名鉴权,因此不附带 `Bearer` 头。它必须指向一个 `.zip`,其根目录为 `<slug>/SKILL.md …` 或扁平的 `SKILL.md …`。
112
+
113
+ **固定 vs 可配置**:`/repo` 路径固定;reporter 三个路径是可覆盖的默认值;上面的 JSON 结构是契约。可调项(环境变量):
114
+
115
+ | 变量 | 作用 |
116
+ |------|------|
117
+ | `TEAMAI_API_TOKEN` | API key(`--token` 的替代) |
118
+ | `TEAMAI_REPORT_ENDPOINT` | reporter 基础 URL(默认 = `--http` 地址) |
119
+ | `TEAMAI_REPORT_PATHS` | JSON `{ "report", "sync", "ack" }`,覆盖 reporter 三个路径 |
120
+ | `TEAMAI_REPORT_AGENTS` | 参与上报的 agent,逗号分隔(默认 `workbuddy,codebuddy`) |
121
+ | `TEAMAI_SKILL_DOWNLOAD_HOSTS` | skill `download_url` 的 host 白名单,逗号分隔(空 = 全部放行) |
122
+
123
+ </details>
124
+
70
125
  ## 命令
71
126
 
72
127
  | 命令 | 说明 |
73
128
  |------|------|
74
- | `teamai init [--scope <user\|project>] [--role <id>] [--force]` | 初始化(自动安装 gf CLI、OAuth 登录、关联仓库、注册成员、配置 reviewers、注入 hooks) |
75
- | `teamai push [--all] [--role <id>]` | 推送本地新资源到独立分支并创建 Merge Request;新 skill 交互式选择目标命名空间,可用 `--role` 覆盖 |
76
- | `teamai pull [--silent]` | 拉取团队资源并注入到本地 AI 工具(支持双 scope 依次拉取) |
129
+ | `teamai init` | 初始化(OAuth 登录、关联仓库、注册成员、注入 hooks) |
130
+ | `teamai push` | 推送本地资源到独立分支并创建 MR |
131
+ | `teamai pull` | 拉取团队资源并注入到本地 AI 工具 |
77
132
  | `teamai status` | 查看本地 vs 团队仓库差异 |
78
- | `teamai list [type] [--source repo\|local\|all] [--agent <id>]` | 列出资源(skills\|rules\|docs\|env\|wiki);`--source local` `all` 时会扫描已安装 AI agent 下的 skills 目录,并标注每个 skill 的来源 (`[team]` / `[builtin]` / `[source:<name>]` / `[local-only]`) |
79
- | `teamai skill [list\|show <name>]` | 默认列出全部 skill;`show <name>` 输出指定 skill 的来源、贡献者、已安装的 agent 列表与描述摘要 |
80
- | `teamai members` | 列出已注册的团队成员 |
81
- | `teamai remove <type> <name>` | 从团队仓库和本地删除资源并创建 MR(skills\|rules\|wiki) |
82
- | `teamai roles` | 管理团队角色(`init`/`list`/`set`/`add`/`remove`/`update`) |
83
- | `teamai source` | 管理跨团队 skill 订阅源(`add`/`remove`/`list`/`browse`) |
84
- | `teamai contribute --file <path> [--scope <user\|project>]` | AI 生成的经验文档推送到团队仓库 |
85
- | `teamai recall <query>` | 搜索团队知识库,自动合并 user + project 双 scope 结果 |
86
- | `teamai import --from-repo <url>` | 拉取远端仓库并生成单仓视图 `docs/team-codebase/repos/<slug>.md`;AI 推荐业务域并写入 `.teamai/domains.yaml` |
87
- | `teamai import --from-repo-list <yaml>` | 按白名单批量导入多个仓库(支持并发),并按业务域聚合产出 |
88
- | `teamai import --from-org <org> --bootstrap` | 列出组织/group 下所有仓库(GitHub / TGit),AI 聚类为业务域,交互式 review 后完成首次全量同步 |
89
- | `teamai import --from-iwiki <id> [--iwiki-dual]` | iWiki 文档导入为 learnings;dual 模式同时把业务接口 / 外部知识源 / 术语表抽取到 `docs/team-codebase/external-knowledge.md` |
90
- | `teamai cache --status \| --gc` | 查看或回收 shallow-clone 缓存目录 `~/.teamai/cache/repos/`(LRU + 容量上限,默认 5GB) |
91
- | `teamai codebase --lint [--fix]` | `docs/team-codebase` 与 `.teamai/` 做跨文件一致性 lint;报告锚点 / 孤儿 / 源失效 / 同步陈旧等问题;`--fix` 应用低风险机械修复 |
92
- | `teamai review [id] [--apply \| --reject \| --all-apply]` | 浏览并处理 `.teamai/pending-review.jsonl` 中的待审 codebase 变更;`--apply` 通过章节锚点原地写入 |
93
- | `teamai domains drift [url] [--apply \| --lock \| --apply-all]` | 浏览并处理域漂移信号;`--apply` 把仓库重新归类到推荐域并刷新聚合视图 |
94
- | `teamai digest` | 生成团队 AI 使用周报(skill 排行、新增/更新 skill、session 摘要) |
95
- | `teamai hooks` | 管理 AI 工具 hooks(list / inject / remove) |
96
- | `teamai ci extract-mr --url <url> [--mode comment\|write\|both] [--individual-comments]` | CI 流水线集成:从 MR/PR 中提取知识,发布为评论,合并后写入团队知识仓库。使用 `--individual-comments` 时每条建议单独发布,支持 reaction/reject 交互(GitHub 👎 / TGit ☝️) |
97
- | `teamai uninstall [--force]` | 卸载 teamai:移除 hooks、rules、skills、env、docs、~/.teamai/ |
133
+ | `teamai recall <query>` | 搜索团队知识库(BM25 + 图谱加权) |
134
+ | `teamai recall enable/disable/status` | 开启/关闭/查看 recall 状态(控制 auto-recall hooks subagent 部署) |
135
+ | `teamai import --dir <path>` | 从本地目录提取代码知识图谱 |
136
+ | `teamai import --from-repo <url>` | 导入仓库代码知识图谱(`teamwiki/`) |
137
+ | `teamai import --from-org <org>` | 批量导入组织下所有仓库 |
138
+ | `teamai import --from-repo-list <yaml>` | 按白名单批量导入 |
139
+ | `teamai import --from-mr <url>` | 从已合并 MR 提取 learning |
140
+ | `teamai import --from-iwiki <id>` | iWiki 导入文档为 learnings |
141
+ | `teamai codebase --lint` | 知识图谱健康度检查 |
142
+ | `teamai contribute` | 分享本次 session 经验到团队仓库 |
143
+ | `teamai members` | 列出团队成员 |
144
+ | `teamai roles` | 管理团队角色和命名空间 |
145
+ | `teamai remove <type> <name>` | 删除资源并创建 MR |
146
+ | `teamai digest` | 生成团队使用周报 |
98
147
  | `teamai doctor` | 诊断配置问题 |
148
+ | `teamai uninstall` | 卸载所有 teamai 资源和 hooks |
149
+
150
+ 全局选项:`--dry-run`、`--verbose`
151
+
152
+ Import 选项:`--incremental`、`--skip-enrich`(跳过 AI 调用,仅做代码提取 + 图谱构建)
153
+
154
+ <details>
155
+ <summary>更多命令(管理、CI、分析)</summary>
156
+
157
+ | 命令 | 说明 |
158
+ |------|------|
159
+ | `teamai list [type]` | 列出资源(skills\|rules\|docs\|env\|wiki) |
160
+ | `teamai skill [show <name>]` | 查看 skill 元数据和贡献者 |
161
+ | `teamai source` | 管理跨团队 skill 订阅 |
162
+ | `teamai tags` | 管理基于标签的资源过滤 |
163
+ | `teamai env` | 管理团队环境变量 |
164
+ | `teamai hooks` | 管理 AI 工具 hooks |
165
+ | `teamai cache --gc` | 回收 clone 缓存 |
166
+ | `teamai ci extract-mr --url <url>` | CI:从 MR 提取知识,发布评论,合并后写入团队仓库 |
99
167
 
100
- 全局选项:
101
- - `--dry-run` — 预览模式,不做实际变更
102
- - `--verbose, -v` — 详细输出
168
+ </details>
103
169
 
104
170
  ## 工作原理
105
171
 
@@ -316,6 +382,60 @@ Author: alice | Score: 12.0 | Tags: fuse, deploy
316
382
 
317
383
  索引在每次 `teamai pull` 时自动重建。旧版索引(无 `version` 字段或缺少 `type`)会在首次使用时被自动检测并重建,对调用方透明
318
384
 
385
+ ### 开启 / 关闭 Recall
386
+
387
+ Recall 功能通过两级配置控制——管理员设置团队默认值,成员可在本地覆盖:
388
+
389
+ | 层级 | 配置文件 | 字段 | 说明 |
390
+ |------|----------|------|------|
391
+ | 团队默认 | `teamai.yaml` | `sharing.recall.enabled` | `true` / `false`(默认 `false`) |
392
+ | 用户覆盖 | `~/.teamai/config.yaml` | `recallEnabled` | `true` / `false`,优先级高于团队默认 |
393
+ | 环境变量 | shell | `TEAMAI_RECALL_DISABLED=1` | 强制禁用所有 recall hooks(应急开关) |
394
+
395
+ ```bash
396
+ teamai recall enable # 开启 recall,部署 subagent 和 rules
397
+ teamai recall disable # 关闭 recall,移除 subagent 和 rules
398
+ teamai recall status # 查看当前生效状态(团队默认 + 用户覆盖)
399
+ ```
400
+
401
+ 关闭后,`teamai pull` 将跳过部署 recall subagent、recall rules 注入块和 TodoWrite 提醒 hook。手动执行 `teamai recall <query>` 搜索不受此开关影响。
402
+
403
+ ### 代码库知识图谱(teamwiki/)
404
+
405
+ `teamai codebase --extract`(或 `teamai import --from-repo`)解析源码仓库,将结构化知识图谱写入 `teamwiki/` 目录:
406
+
407
+ ```
408
+ teamwiki/
409
+ ├── router.md # 导航枢纽,列出所有已导入仓库
410
+ ├── index.md # 全局索引(自动生成,含时间戳)
411
+ ├── hot.md # 活跃工作记忆(Phase 4 hot/cold 预留)
412
+ ├── source-manifest.json # 源文件哈希清单(增量提取用)
413
+ ├── .indices/
414
+ │ └── graph-index.json # 知识图谱:nodes + edges(JSON 格式)
415
+ ├── evidence/
416
+ │ └── code/
417
+ │ └── <project>/ # 每个导入的仓库一个目录
418
+ │ ├── index.md # 项目摘要(facts 总数 + 页面列表)
419
+ │ ├── component.md # 函数 / 类 / 组件
420
+ │ ├── interface.md # 接口和类型定义
421
+ │ ├── config.md # 配置项(环境变量、TOML key 等)
422
+ │ ├── error.md # 错误处理模式
423
+ │ └── relation-<dir>.md # 按顶级目录分组的 import 依赖关系
424
+ └── gaps/
425
+ └── detected.md # 知识缺口检测结果(IMPL_MISSING / LOW_CONNECTIVITY / …)
426
+ ```
427
+
428
+ **graph-index.json** 存储提取出的知识图谱。真实数据参考:HAI 团队 11 个仓库 → **2 218 个节点,852 条边**。
429
+
430
+ | 字段 | 说明 |
431
+ |------|------|
432
+ | `nodes[].kind` | `component`(函数/类)或 `config`(配置项) |
433
+ | `edges[].relation` | `imports` —— 跨文件或跨仓库依赖关系 |
434
+
435
+ 跨仓 edge 通过 PascalCase 标签匹配自动检测,无需手动配置。
436
+
437
+ `teamai recall` 利用此图谱进行 **BM25 + graph-boost** 检索:关键词命中后按图结构邻近度重排序,结果兼具文本相关性和结构相关性。
438
+
319
439
  ### TodoWrite 提醒 hook
320
440
 
321
441
  `teamai pull` 会在 `TodoWrite` 工具上注册一个 PostToolUse hook。当 session 第一次写 TODO 列表时,hook 会注入一次性提醒,要求 agent 在尚未调用 `teamai-recall` 时先调用一次。session 级去重通过 `~/.teamai/sessions/<sid>-todowrite-hint.json` 实现(TTL 24 小时)
@@ -326,7 +446,7 @@ Author: alice | Score: 12.0 | Tags: fuse, deploy
326
446
  export TEAMAI_RECALL_DISABLED=1
327
447
  ```
328
448
 
329
- 该环境变量同时也会关闭 auto-recall hook
449
+ 该环境变量同时也会关闭 `teamai recall` 的召回质量记录(用于 contribute-check 知识空白检测)
330
450
 
331
451
  ### `agents` 资源类型
332
452
 
@@ -341,6 +461,45 @@ team-repo/
341
461
 
342
462
  `teamai pull` 会把它们复制到每个 Tier-1 工具的 `agents/` 目录(例如 `~/.claude/agents/`)。CLI 内置的 `teamai-recall.md` 会与团队 agents 一起部署,并在 `teamai push` 时被自动排除(由 CLI 管理,不归团队仓库)
343
463
 
464
+ ### `hooks` 资源类型(团队自定义 hooks)
465
+
466
+ 除了 CLI 内置的运维 hooks,团队还可以在仓库里**声明一次自己的 hooks**,由 `teamai pull` 自动适配下发到各 AI 工具(Claude Code、CodeBuddy、Cursor……)。在 `hooks/hooks.yaml` 中声明:
467
+
468
+ ```yaml
469
+ hooks:
470
+ - id: block-secret # 唯一,^[a-z0-9-]+$,用于 marker 与清单索引
471
+ description: 提交前扫描密钥 # 写进 hook 的 description
472
+ event: PreToolUse # Claude 规范事件名(跨工具中立语言)
473
+ matcher: Bash # 可选,工具 matcher
474
+ command: 'bash -lc "~/.teamai/team-scripts/scan-secret.sh" || true'
475
+ timeout: 15 # 可选,秒
476
+ tools: [claude, cursor] # 可选,缺省 = 所有支持 hooks 的工具
477
+
478
+ # 可选:有限度地调整 CLI 自身的内置 hooks(仅白名单字段)
479
+ builtin:
480
+ disabled: [Hook dispatch post-tool-use TodoWrite] # 关闭某条内置 hook
481
+ overrides:
482
+ Hook dispatch stop: { timeout: 20 } # 仅允许覆盖 timeout
483
+ ```
484
+
485
+ - `teamai pull` 每次会话开始都会把内置(A)+ 团队(B)hooks 对齐注入到各工具(绕过「已同步」快路径,新增/变更的 hook 自动自愈生效)。
486
+ - 团队 hooks 通过 `[teamai:hook:<id>]` marker 与内置 hooks 隔离,并记录在 `~/.teamai/managed-hooks.json` 中;从 `hooks.yaml` 删除某条后,下次 pull 会从所有工具干净移除,且**绝不误伤内置 hooks**。
487
+ - 写到磁盘的内容对内置 hooks **逐字节不变**,老机器升级 CLI 是零 diff、零回归。
488
+
489
+ 审计、强制注入或清除当前生效的 hooks:
490
+
491
+ ```bash
492
+ teamai hooks list # 列出生效的内置(A)+ 团队(B)hooks
493
+ teamai hooks inject # 强制对齐注入 A + B
494
+ teamai hooks remove # 移除所有 teamai 托管的 hooks(A + B)
495
+ ```
496
+
497
+ > **安全提示**:团队 hooks 是会随会话事件自动执行的任意 shell 命令——请把仓库写权限视为一个执行面(同 `env.yaml`,受 MR review 治理)。护栏:
498
+ > - 注入时逐条打印将执行的命令(`--silent` 时静默)。
499
+ > - `teamai.yaml` 中 `sharing.hooks.autoApply: false`:`pull` 时只提示、不自动应用,需用户手动 `teamai hooks inject` 同意。
500
+ > - `sharing.hooks.requireTeamScripts: true`:拒绝命令不在 `~/.teamai/team-scripts/` 下的团队 hook。
501
+ > - 设置 `TEAMAI_HOOKS_DISABLED=1` 可在本机否决所有团队 hooks(内置 hooks 仍生效)。
502
+
344
503
  ## 更新
345
504
 
346
505
  ```bash