AGENTS.md · diff
git:20261031.9f1b453 to git:20261104.8ab9a2a
2 added, 0 removed. Audit A to A.
# TeamAI CLI
CLI for managing a team's skills, rules, agents, learnings, models, MCP, and other AI assets in a git repo, and syncing them into AI coding tools. Package: [`teamai-cli`](https://www.npmjs.com/package/teamai-cli).
TypeScript, Node 20+ (`npm run lint` needs ^20.19 or >=22.12), tsup (ESM), Vitest. Commands: `npm run build`, `npm run typecheck`, `npm run lint`, `npx vitest run`, `npm run test:e2e`.
## Git
- Default branch: `main`. Worktrees and PRs based on `origin/main`.
- PR only to `Tencent/teamai-cli`. Before push, check `git log origin/main..HEAD`; rebase or cherry-pick if unrelated commits appear.
- **Use a worktree**: call `EnterWorktree` before changing code. Do not edit the main working directory.
## Rules
- **Occam's razor**: do not add a new CLI command early. Skip it unless it is necessary. Reuse or extend an existing command or option.
+ - **Workflow first**: a feature that orchestrates AI work is a default workflow, `workflows/<name>.yaml`, and a team replaces it with a file of the same name. What a team may change (steps, their order, prompts, thresholds) lives in that YAML. The feature's command is only a shortcut that starts the workflow, on the local driver by default. Code keeps only the invariants a team must not change. A new workflow key is generic: the engine never branches on a feature (`docs/dev/workflow-engine.md`).
+ - **Compose workflows**: before writing steps, run an existing workflow as a `workflow:` step instead of repeating it, as `teamai-share-session` runs `teamai-score`. Write a new one so another workflow can run it the same way: its inputs and outputs say what it takes and gives, and it does not assume it is the root run.
- CLI user-facing output must be English. No Chinese in production code. Tests assert English output.
- **Doc layout**: user-facing docs are bilingual. Top-level files are `name.md` / `name.zh-CN.md`. Guide pages are `docs/guide/<page>.md` (English) and `docs/guide/zh-CN/<page>.md` (Chinese). A behavior change updates both. `docs/guide/tool-support.md` and its Chinese page are generated from the tool descriptor (`src/tools.ts`): regenerate them with `node scripts/check-docs.mjs --write`; their cell text stays English on both pages. `docs/designs/` (design notes: a `> Status:` line at the top, and a status entry in `docs/designs/README.md`) and `docs/dev/` (maintainer docs) are English only. Behavior changes must update every affected doc; grep old wording before opening the PR.
- **Change docs rarely**: leave them alone when you can. A bugfix that does not change behavior a user runs into does not need a doc change. When you do edit docs, write them so you can understand them. Do not make them complicated.
- **Keep the README short**: change it as little as possible. When a change is required, update every language (`README.md` and every `README.*.md`; run `ls README*` first) and keep them consistent. `scripts/doc-checks/readme-matrix.ts` checks that the agent matrix is the same in every README, and checks its culture, models, usage and scorers cells and the ✓¹ mark against `TOOLS`.
- **Treat `skill-data/` like docs**: that is what the agent actually reads. A behavior change must update the affected skills (`core` / `setup` / `wiki` / `share`), and grep the old wording before the PR.
- `skill-data/core/references/commands.md` is generated from the Commander command table. After changing a command or flag, regenerate it with `node scripts/check-docs.mjs --write`.
- **Leave the teamai skill body alone**: the source of truth for usage and flags is the CLI help (`teamai --help`, `teamai <cmd> --help`) and the generated `commands.md`. To make an agent better at a command, clarify that command's `description` and option help, and point the skill at help, instead of copying usage into the skill. Edit the skill body only when the workflow itself changes.
- Only `skills/teamai/SKILL.md` (the discovery entry) is deployed to the agent. Keep it version-independent: a new workflow is a directory under `skill-data/` plus one line in the stub. Do not put the content in the stub.
## Testing before a PR
Import boundaries, banned APIs, and required helper calls belong in `oxlint-plugin-teamai`, with fixtures using `ruleHarness`. Do not scan source with `fs` or `web-tree-sitter` in `src/__tests__/`, or repeat helper wiring checks in per-command E2E files. For example, `teamai/remove-delivered` rejects bare deletion at pull call sites; `delivered-copies.test.ts` checks the helper's file and ledger behavior.
Documentation checks run in `npm run lint`. After changing a command or tool descriptor:
```sh
node scripts/check-docs.mjs --write
node scripts/check-docs.mjs
```
A PR that changes runtime behavior (anything other than docs-only / tests-only / lint-rule-only) must, after `npm run build`, verify the change end to end with the real CLI. Type check and unit tests are not enough. **One representative real-CLI run is enough.** Paste the record of what actually passed into the PR. A docs-only, tests-only, or lint-rule-only change (no runtime code touched) needs no real-CLI record. For a required helper call enforced by an enabled `teamai/*` rule, run `npm run lint` and the helper unit test; do not add an E2E file for each command.
Iterate with `npm run test:e2e -- <test-file>`; run the full suite only when changing the E2E runner, shared fixtures, or test isolation ([CONTRIBUTING.md](.github/CONTRIBUTING.md#testing-guidelines)).
Do not cover the full provider × agent matrix below. Leave extra providers and agents to CI, or say so when the local environment cannot run them:
- Agents: Claude, Codex, CodeBuddy, OpenCode
- Providers: `git`, `gitlab`, `github`
## Self review before push
Review the whole branch diff, not only the last change. For every piece of
shared state, list every reader and every writer.
## Code Review Rules
- The PR description must document sufficient testing. For a PR that changes
runtime behavior (anything beyond a docs-only, tests-only, or lint-rule-only
diff), that includes an end-to-end / real-CLI verification record, not only unit tests
or type checks — flag such a PR that lacks one as `[P1 blocking]`. A
docs-only, tests-only, or lint-rule-only PR (no runtime code touched) needs
no real-CLI record; do not flag it for that. An enabled
`teamai/*` rule plus its helper unit test requires lint and that test, not
a new E2E file per command; do not flag it for lacking those E2Es.
Do NOT require a full provider × agent matrix — one representative real-CLI
run is enough. Missing coverage of extra providers (`gitlab`/`github`) or
agents (`Codex`/`CodeBuddy`/`OpenCode`) is at most `[P3 nit]` when the author
has flagged it as untestable in this environment or deferred to CI, never
`[P1 blocking]`. A test record naming an older commit than the head is a
note, not a blocking finding; the body may have been edited after the review
pass started.
- Do not over-review. Report only findings you are confident are real in the
current diff. Do not cap how many findings you report: every real bug should
surface in one pass, not be deferred to a later one. Instead, gate severity
by evidence — every `[P1 blocking]` must cite either a concrete failure
scenario (the input or state that triggers it and the resulting misbehavior)
or the exact `## Code Review Rules` item it breaks. A finding that can cite
neither is at most `[P2 non-blocking]`; a speculative or theoretical risk
that needs an unlikely precondition to trigger is at most `[P3 nit]`. Never
restate a finding already resolved in the current diff.
- Reject over-engineering. Favor the smallest code that solves the problem;
flag speculative abstractions, unused flexibility or config, error handling
for cases that cannot occur, and new CLI commands added where an existing
command could be reused or extended.
- Changes must be surgical. Every changed line should trace directly to the
PR's stated goal; flag unrelated drive-by edits.
- A PR that adds a tool, changes where teamai writes for a tool, or changes
what a tool supports updates that tool's entry in `TOOLS` (`src/tools.ts`).
A missing update is at most `[P2 non-blocking]`. A cell marked `verified`
with no recorded run (tool version, date and command) in the PR is
`[P3 nit]`. `unknown` is never a finding. What the locate matrix test checks
stays out of review.
- Label every finding with an explicit severity a first-time reader can
understand — never a bare `P1`/`P2`/`P3` code. Keep the `P` marker but spell
out what it means inline on each finding, using the PR author's language:
`[P1 blocking]` for issues that must be fixed before merge,
`[P2 non-blocking]` for suggestions that do not block merge, and `[P3 nit]`
for minor or optional polish, theoretical edge cases, and coverage deferred
to CI. (In Chinese, `[P1 阻断]` / `[P2 非阻断]` / `[P3 可选]`.)