@team-ai/teamai-cli 0.0.0-stage → 0.22.2

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +1416 -0
  2. package/LICENSE +13 -0
  3. package/README.ja.md +177 -0
  4. package/README.ko.md +177 -0
  5. package/README.md +176 -2
  6. package/README.th.md +177 -0
  7. package/README.zh-CN.md +183 -0
  8. package/agents/teamai-recall.md +406 -0
  9. package/dist/cli.js +136359 -0
  10. package/dist/index.js +9 -0
  11. package/package.json +100 -4
  12. package/skill-data/core/SKILL.md +250 -0
  13. package/skill-data/core/references/commands.md +471 -0
  14. package/skill-data/core/references/contribute-member.md +161 -0
  15. package/skill-data/core/references/troubleshooting.md +419 -0
  16. package/skill-data/setup/SKILL.md +80 -0
  17. package/skill-data/setup/references/join-member.md +189 -0
  18. package/skill-data/setup/references/manage-admin.md +354 -0
  19. package/skill-data/setup/references/provider-tgit.md +101 -0
  20. package/skill-data/setup/references/setup-admin.md +312 -0
  21. package/skill-data/setup/references/uninstall.md +180 -0
  22. package/skill-data/share/SKILL.md +70 -0
  23. package/skill-data/share/references/doc-template.md +44 -0
  24. package/skill-data/wiki/SKILL.md +317 -0
  25. package/skill-data/wiki/references/agents/graph-rag-agent.md +344 -0
  26. package/skill-data/wiki/references/agents/kb-doc-generator.md +325 -0
  27. package/skill-data/wiki/references/methodology/phase0-collection.md +54 -0
  28. package/skill-data/wiki/references/methodology/phase1-reverse-engineering.md +89 -0
  29. package/skill-data/wiki/references/methodology/phase2-document-types.md +341 -0
  30. package/skill-data/wiki/references/methodology/phase3-ai-enhancement.md +164 -0
  31. package/skill-data/wiki/references/methodology/phase4-quality.md +232 -0
  32. package/skill-data/wiki/references/overview.md +125 -0
  33. package/skill-data/wiki/references/phases/k1-reverse-engineering.md +118 -0
  34. package/skill-data/wiki/references/phases/k2-documents.md +68 -0
  35. package/skill-data/wiki/references/phases/k3-ai-native.md +121 -0
  36. package/skill-data/wiki/references/phases/k4-quality.md +190 -0
  37. package/skill-data/wiki/references/phases/phase0-init.md +113 -0
  38. package/skill-data/wiki/references/templates/project-overview.md +149 -0
  39. package/skill-data/wiki/scripts/scan_repo.py +224 -0
  40. package/skill-data/wiki/scripts/validate_kb.py +256 -0
  41. package/skills/teamai/SKILL.md +46 -0
@@ -0,0 +1,189 @@
1
+ # Scenario: Member — join an existing team
2
+
3
+ Goal: the user joins a team that already has a TeamAI repo. You need the team
4
+ repo's **full URL** (the admin shares it). Do NOT create a new repo.
5
+
6
+ Run the commands yourself. Only stop to ask when a step says "ASK".
7
+
8
+ ## Step 0 — Get the repo URL (REQUIRED — stop if missing)
9
+
10
+ A member joins an **existing** repo. You need its full URL from the admin.
11
+
12
+ If the user has not given a full URL, ask for it:
13
+ *"Paste the full team repo URL your admin gave you (e.g.
14
+ https://github.com/your-org/your-repo)."* Do not proceed with `owner/repo` short
15
+ form.
16
+
17
+ **If the user does not have the URL, STOP here.** Do not guess a URL, do not probe
18
+ platforms, and — most importantly — **do not create a new repo.** Tell the user:
19
+ *"Ask your team's TeamAI admin for the repository URL, then come back and paste it
20
+ here."* A member without a repo URL cannot continue; creating one would fork the
21
+ team into a second, empty repo. (Setting up a brand-new team repo is the admin
22
+ flow — see `{SKILL_DIR}/references/setup-admin.md` — not this one.)
23
+
24
+ ## Step 1 — Install and verify
25
+
26
+ ```bash
27
+ npm install -g teamai-cli
28
+ teamai --version
29
+ ```
30
+
31
+ If it fails, Node.js ≥ 20 is missing — have them install Node 20+ first.
32
+
33
+ ## Step 2 — Choose scope (ASK)
34
+
35
+ - **This project only** (default): `cd` into the project directory first.
36
+ - **Whole machine**: add `--scope user`.
37
+ - **A folder holding several repos** (a workspace): set up each repo from
38
+ inside it, then run the same `init` in the folder. The folder also receives
39
+ what each repo inside selects; pass `--project` there only for a project the
40
+ folder itself belongs to.
41
+
42
+ ## Step 3 — Log in to the same platform as the URL
43
+
44
+ Match the login to the URL's host (do NOT create a second repo):
45
+
46
+ - **`git.woa.com/...`** (Tencent TGit) → after telling the user this installs the
47
+ `gf` binary and stores a credential, and getting their OK, **you may run the
48
+ `gf` install and `gf … auth login` for them** (or show the commands if they
49
+ prefer to run them). Follow `{SKILL_DIR}/references/provider-tgit.md` ("Log in");
50
+ the user's only action is approving the login URL in their browser / iOA. No
51
+ `GITLAB_URL` needed. (No headless shortcut: `TGIT_TOKEN` is REST-API-only and
52
+ cannot clone, so the login has to be run once on the machine.)
53
+ - **`cnb.cool/...`** → install the CNB CLI, then authorize, in this order:
54
+ 1. `npm install -g @cnbcool/cnb-cli`
55
+ 2. `cnb login` — have the user approve it in the browser (OAuth2 device flow);
56
+ wait until they confirm before continuing.
57
+ - **`github.com/...`** → **you run the login yourself; never hand the user a
58
+ command.** Log them in before `teamai init`:
59
+ `gh auth login --web --git-protocol https`. Relay the one-time code and the
60
+ `https://github.com/login/device` URL it prints, and ask the user to open that URL
61
+ and approve — that approval is their *only* action. Confirm with `gh auth status`
62
+ before continuing. (Headless/CI only: pre-set `GITHUB_TOKEN` — a token with `repo`
63
+ scope — instead.)
64
+ - **`gitlab.com/...`** or self-hosted GitLab → set `GITLAB_TOKEN` (and `GITLAB_URL`
65
+ for self-hosted, with `api` scope). **Exception:** a member who only syncs and
66
+ never needs the CLI to open merge requests (typical for non-developers) can skip
67
+ the token: add `--provider git` to the `init` in Step 4. Git then uses their
68
+ existing SSH key or credential helper, and `push` leaves the MR for them to open
69
+ on the web.
70
+ - **Other Git hosts, including Azure Repos** → use the existing Git credential
71
+ helper or SSH key. Keep the clone path as provided, including whether it ends
72
+ in `.git`; do not embed HTTPS credentials in the URL.
73
+
74
+ If they have no account on that platform, they register there, then ask the admin
75
+ to add them to the repo.
76
+
77
+ ## Step 4 — Initialize with the URL (you run it)
78
+
79
+ Before running `init`, ask whether the user wants to activate any logical
80
+ projects this team repo declares. If `init` lists **Available projects**, show
81
+ the names/IDs and ask which belong to this setup; enter the corresponding
82
+ comma-separated numbers. Press Enter for none only when the user explicitly
83
+ chooses no project. If the IDs are already known, pass `--project id1,id2` to
84
+ skip the picker. For a non-interactive run, ask first and pass `--project`:
85
+ without it, init keeps `projects: []` and prints a `teamai projects set <id>`
86
+ follow-up instead of waiting for a choice.
87
+
88
+ ```bash
89
+ # this project only (run from inside the project)
90
+ teamai init https://<platform>/<org>/<repo>
91
+
92
+ # or whole machine
93
+ teamai init https://<platform>/<org>/<repo> --scope user
94
+ ```
95
+
96
+ **Set up all their AI tools by default (global rule 9).** Don't add `--agent` to
97
+ restrict the install unless the user said to. Omitting it gives a picker — select
98
+ **every AI tool already installed**. Afterwards, **tell the user (in their
99
+ language) which agents will now auto-sync TeamAI**, and note any detected tool that
100
+ was skipped and why.
101
+
102
+ **Read-only / restricted environments (no Git access):** some sandboxed hosts
103
+ cannot use Git. If the admin provides an HTTP endpoint + API key instead, use:
104
+
105
+ ```bash
106
+ teamai init --http https://your-team-host/api --token <api-key>
107
+ ```
108
+
109
+ This is a read-only consumer mode — `push` / `contribute` are not available, but
110
+ skills and rules still sync.
111
+
112
+ **Claude Code or Codex kept in a different directory (`CLAUDE_CONFIG_DIR`,
113
+ `CODEX_HOME`):** `init` records that directory (as `toolRoots.claude` /
114
+ `toolRoots.codex` in the local config) and syncs every path of that tool there,
115
+ so run `init` from a shell that has the variable exported. Re-running `init` after
116
+ changing it moves the install (the old root's hooks and managed MCP servers are
117
+ removed, and for Claude Code its delivered model credentials; its skills and rules
118
+ are left and named in the output). To end the relocation, run `init` once with the
119
+ variable set but blank: `CLAUDE_CONFIG_DIR= teamai init …` or `CODEX_HOME= teamai init …`.
120
+
121
+ ## Step 5 — Verify with doctor
122
+
123
+ ```bash
124
+ teamai doctor
125
+ teamai hooks list # per-tool: which AI tools actually got the hooks
126
+ ```
127
+
128
+ Fix anything `doctor` reports. **Don't trust the "Hooks injected into all AI tool
129
+ settings" message alone** — it prints even for tools where nothing was written;
130
+ `teamai doctor` / `teamai hooks list` show the real per-tool status. If it flags
131
+ hook problems, load the troubleshooting reference (`"$(teamai skill path core)/references/troubleshooting.md"`),
132
+ section "Which tools actually get hooks".
133
+
134
+ ## Step 6 — Confirm the skills actually arrived
135
+
136
+ `teamai init` does not copy team skills, rules or MCP. They arrive on the next
137
+ session start, or when you run `teamai pull`. A workspace-scope init run without a
138
+ terminal and without `--agent` creates no tool directory; that directory appears
139
+ when the user first opens that tool in the project, and that session start pulls.
140
+ To confirm after a session start or a pull:
141
+
142
+ ```bash
143
+ teamai list # see the team skills / rules / docs you now have
144
+ ```
145
+
146
+ Then tell the user: from now on, **opening a new session in this AI tool
147
+ auto-syncs** the latest team resources — no manual step needed. If their tool has
148
+ no session-start hook (e.g. Gemini CLI, JoyCode), they run `teamai pull` by hand.
149
+
150
+ **Reassure them about privacy** (in their language): *"TeamAI does not send any of
151
+ your session data to third parties. The only place anything is reported is the team
152
+ repo you just joined — usage counts and knowledge you choose to contribute, never
153
+ your raw conversation content."* (Team reporting is opt-in and carries counts +
154
+ tool names only, on a separate branch of that same repo.)
155
+
156
+ ## Agent-specific note
157
+
158
+ If this conversation is running in **ChatGPT App** or **WorkBuddy**, the hooks
159
+ that drive auto-sync need an extra manual step — load the troubleshooting reference (`"$(teamai skill path core)/references/troubleshooting.md"`), section "Agent-specific caveats" and walk the user through it before finishing.
160
+
161
+ ## If something is denied
162
+
163
+ Permission errors (can't clone, can't read) usually mean the admin has not added
164
+ this user to the repo yet. Have them copy the exact error message to their admin.
165
+
166
+ ## Wrap up in the user's language, and how to leave
167
+
168
+ Summarize the outcome **in the user's own language** (global rule 1). Cover:
169
+
170
+ 1. **They're done — sync is automatic.** From now on, opening a session in this AI
171
+ tool keeps their team skills up to date; no commands needed.
172
+ 2. **Sharing a session learning is automatic — no command to remember.** When a
173
+ session produced something worth sharing, TeamAI **prompts them on its own** (at
174
+ the end of the session) and the `share` workflow (`teamai skill get share`) takes over to
175
+ summarize and contribute it. They do **not** invoke `/teamai` for this. (This
176
+ prompt only appears when recall is on — it is off by default; the admin turns it
177
+ on in `teamai.yaml` (`sharing.recall.enabled`), a member with `teamai recall enable` — and the admin has not switched the
178
+ reminder off in `teamai.yaml`. It also stays silent while their teamai config
179
+ cannot be loaded; `teamai skill get share` then names the file and the error.)
180
+ 3. **They can also contribute a skill — just ask in plain language.** A member does
181
+ not need to be an admin to publish a skill. They tell TeamAI something like
182
+ *"share this xxx skill with my team"*, in their own language, and you
183
+ run the publish for them (see `"$(teamai skill path core)/references/contribute-member.md"`;
184
+ it needs no recall).
185
+ 4. **How to leave — via the skill, not raw commands.** They can remove TeamAI any
186
+ time by re-invoking the skill; you'll run it for them:
187
+ `/teamai Uninstall TeamAI` (in their language; the `/teamai` prefix stays as-is).
188
+ One line, in their language: *"This only removes things from your machine; the
189
+ team repo stays — rejoin any time with `/teamai` and the repo URL."*
@@ -0,0 +1,354 @@
1
+ # Scenario: Admin — day-to-day management
2
+
3
+ The user already ran `teamai init`. Do NOT re-init or re-register. Before changing
4
+ anything, say what you are about to change. Pick the task below that matches.
5
+
6
+ Day-to-day management is mostly **publishing and updating team resources — skills,
7
+ rules, MCP servers, and env** — plus inviting members and checking the dashboard.
8
+
9
+ ## Publish or update a skill / rule / doc
10
+
11
+ The user (or you) creates or edits a skill, rule, or doc locally, then publishes it
12
+ to the team. The same `teamai push` handles both new resources and updates to
13
+ existing ones:
14
+
15
+ ```bash
16
+ teamai push # review the diff, then confirm
17
+ teamai push --all # push everything without per-item confirmation
18
+ teamai push --skill <path> # push one specific skill
19
+ teamai push --branch <name> # use an explicit branch for a new push
20
+ ```
21
+
22
+ An existing open PR is updated on its recorded branch. TeamAI refuses to reset a
23
+ team-repo clone with unrelated modified, staged, untracked, or conflicted files;
24
+ commit or stash those changes before retrying.
25
+
26
+ Members receive it automatically the next time they open a session (or when they
27
+ run `teamai pull`).
28
+
29
+ ## Publish or update team MCP servers
30
+
31
+ ```bash
32
+ teamai mcp list # team MCP servers + per-tool install status
33
+ teamai mcp inject # push team MCP servers into every AI tool's config
34
+ teamai mcp remove --dry-run # preview removal without changing tool configs or managed records
35
+ teamai mcp remove # remove teamai-managed MCP servers
36
+ ```
37
+
38
+ MCP definitions travel with the team repo like skills/rules — edit, then the
39
+ members pick them up on sync.
40
+
41
+ A server with a `${VAR}` the tool cannot expand itself gets the resolved value
42
+ written into its project config (`.mcp.json`, `.cursor/mcp.json`, ...). With
43
+ `sharing.gitExclude` on, Claude's (not in a single-repo team, whose worktrees
44
+ each read their own branch's servers) and CodeBuddy's servers go to their local
45
+ scopes in `~/.claude.json` and `.codebuddy.json` instead, outside the project,
46
+ and the next pull (on an HTTP-backed team, the local agent's next sync) moves
47
+ teamai's servers out of `.mcp.json`. Before
48
+ that write, teamai lists the file in the clone's `.git/info/exclude`, inside a
49
+ `# [teamai:mcp-exclude:start]` block; the committed `.gitignore` is never touched.
50
+ A file under a symlinked directory is listed and checked where the write lands
51
+ (`.cursor/` linking to `config/`: `/config/mcp.json`); a config that is itself a
52
+ symlink stays one, and its target is listed in, and checked by, its own repository.
53
+ When it cannot (git already tracks the file, a rule in the member's git ignore
54
+ files re-includes it, `.git/info` is not writable, the exclude file is held by
55
+ another teamai command, or git errors), it leaves the file as it was, warns, and
56
+ `teamai mcp list` shows `withheld: <tool> — <reason>. <fix>`. Apply the fix it
57
+ names (a tracked file: `git rm --cached <file>` and rotate the token; a
58
+ re-including rule such as `!/.mcp.json`: remove it), then run `teamai pull`. A pull or `teamai mcp remove` takes a line out
59
+ once its file no longer holds a resolved value; `teamai uninstall` does so in
60
+ every worktree. A file written under a `toolPaths.<tool>.mcpProject` the team
61
+ later changes or removes stays listed until it is deleted or holds no server;
62
+ for one an older teamai wrote, the first pull finds the path in the team repo's
63
+ history of `teamai.yaml`, or among the built-in paths teamai has since changed
64
+ (not one the same tool maps today), and lists it while it holds any server; one
65
+ git tracks is recorded instead and listed once the member runs `git rm --cached`
66
+ on it. `teamai doctor` checks those paths until that pull. A file written for a
67
+ tool the team moved elsewhere (recorded, or found in that history), that another
68
+ tool still maps, stays listed while it holds a server that tool did not write,
69
+ one of the member's own included. The built-in location of a tool the team drops
70
+ from `toolPaths` or moves elsewhere stays listed while it holds any server; one
71
+ another tool maps today (CodeBuddy's `.mcp.json`, which Claude maps) while it
72
+ holds a server that tool did not write. A file two tools map, with no pull on
73
+ this version having recorded it, needs a `managed-mcp.json` record from each of
74
+ them. While a worktree has no `managed-mcp.json` at all (lost, or before its
75
+ first pull), an untracked config holding a server no record claims is listed,
76
+ and that server noted: it keeps the line until it leaves the file. So is the
77
+ file of a tool `managed-mcp.json` has no record for, when a pull writes that
78
+ tool's first record (its record lost, or teamai's first delivery to it). While that
79
+ note cannot be written (another teamai command holds the record), the line stays
80
+ until a later pull writes it. A Copilot project config's bare top-level servers
81
+ still count once another tool writes `mcpServers` into the file. On an HTTP-backed
82
+ team the local agent's `install_mcp` lists a project config before writing a
83
+ server with any header, env value, argument or URL (only a bare stdio command is not), fails the install when it cannot, and only
84
+ `teamai uninstall` takes that line out. The next sync or `teamai pull` in the
85
+ workspace also lists a file an older local agent wrote a credential into; `teamai doctor` checks those files too.
86
+
87
+ ### Pi MCP delivery
88
+
89
+ Pi 0.99.0+ receives stdio and streamable HTTP servers through the existing MCP commands and `teamai pull`; SSE is skipped. User scope writes `~/.pi/agent/mcp.json`, workspace scope writes `.pi/mcp.json` (Pi requires project trust). TeamAI keeps Pi's default codemode exposure and converts timeout milliseconds to seconds. Relocated Pi agent directories (`PI_CODING_AGENT_DIR` / `PI_CONFIG_DIR`) are unsupported. Local exposure/enabled edits on managed servers survive until the team definition changes; doctor reports differences from the team entry. Extensions that replace `/mcp` must be removed to use Pi's built-in MCP.
90
+
91
+ ## Invite a member
92
+
93
+ There is **no CLI invite flag.** Inviting is done on the Git platform's website:
94
+
95
+ 1. On the platform (GitHub / GitLab / CNB), add the person to the team repo
96
+ (Settings → Collaborators / Members).
97
+ 2. Send them the **full repo URL** and this line to paste into their AI tool:
98
+ `/teamai Help me join my team's TeamAI, repo URL is <URL>`
99
+
100
+ (If you want to see who is already registered: `teamai members` /
101
+ `teamai members list`.)
102
+
103
+ ## See members and resources
104
+
105
+ ```bash
106
+ teamai members list # registered team members
107
+ teamai list # all resource types
108
+ teamai list skills # just skills
109
+ teamai status # local vs team differences
110
+ ```
111
+
112
+ ## Roles (skill namespaces per job function)
113
+
114
+ ```bash
115
+ teamai roles list # roles defined + your current role
116
+ teamai roles init # create the roles manifest (admin, interactive)
117
+ teamai roles add <id> # add a role
118
+ teamai roles update <id> # change a role's namespaces / description
119
+ teamai roles remove <id> # remove a role
120
+ ```
121
+
122
+ After editing roles, `teamai push` to publish the manifest. Members re-sync on
123
+ their next session.
124
+
125
+ ## Projects (manage several projects from one repo)
126
+
127
+ `project` is a second dispatch dimension alongside `role` — one team repo can serve
128
+ multiple projects, each with its own skills/rules/learnings, without a separate
129
+ repo per project:
130
+
131
+ ```bash
132
+ teamai projects list # projects defined + the ones active in this directory
133
+ teamai projects set [ids...] # set the active project(s) for this directory
134
+ teamai projects members <id> # who is registered on a project
135
+ teamai projects add <id> --namespaces common,<id> # add a project (creates projects.yaml if needed)
136
+ teamai projects update <id> --add-namespaces <ns> # or --remove-namespaces / --name / --description
137
+ teamai projects remove <id> # remove a project
138
+ ```
139
+
140
+ A workspace (a folder set up with `init`) also delivers the projects of the
141
+ repos set up inside it, up to three levels down, with no list to keep: `teamai
142
+ projects list` there shows each one and what it selects. A repo that uses
143
+ another team repo, or single-repo mode, is left out and named.
144
+
145
+ A member gets the union of their role resources and their active project's
146
+ resources. Admins declare projects in `manifest/projects.yaml` with the commands
147
+ above, each of which opens a PR. `roles init/add/update/remove` and
148
+ `projects add/update/remove` support `--dry-run` without pulling the team repo.
149
+ Clone previews use the contents after a real pull on the checked-out branch: an
150
+ ahead branch stays ahead, a behind branch advances, and a diverged branch uses
151
+ origin/current-branch. `roles init` preview checks that manifest before asking
152
+ for overwrite confirmation. After `projects remove`,
153
+ keep the project's content in the team repo until members have pulled: that is
154
+ what lets their next pull clean up the copies they deployed.
155
+
156
+ `roles init/add/update/remove` and `projects add/update/remove` previews, and resource removal
157
+ previews, refuse a team clone with uncommitted changes. Commit or stash them before retrying. Single-repo
158
+ previews still work with dirty business files because they read origin. Clone
159
+ previews refresh the configured upstream first, even when its branch or remote
160
+ name differs. A failed fast-forward or missing upstream uses origin/current-branch
161
+ for the real reset fallback. Removal refuses when that refresh also fails.
162
+
163
+ Every namespace that names a directory — `knowledge`, `skills`, `agents`, `env`,
164
+ `hooks`, `mcp`, `models`, `docs` and `wiki` in either manifest, and `learnings` in `projects.yaml` (a role's `learnings:` is
165
+ ignored and unchecked) — must be a single path segment: no `/`, `\`, `:` or control character, no trailing
166
+ `.` or space, and not a Windows device name (`CON`, `NUL`, `COM1`, …). `team-codebase`
167
+ cannot be a `docs` namespace (`docs/team-codebase/` is the legacy codebase output). Two
168
+ namespaces of one resource type may not differ only by case, across both
169
+ manifests. A manifest that breaks this, does not parse, or is empty stops
170
+ members' pull for that scope until it is fixed; the error names the entry. Fix
171
+ it rather than deleting it — with no `roles.yaml`, delivery is unfiltered.
172
+
173
+ An item in an active namespace replaces the root item of the same name, whole:
174
+ a skill by directory name (including a root skill a member gets through a tag),
175
+ an agent by file stem, a rule by first-level file name (`rules/<ns>/<name>.md`
176
+ replaces `rules/<name>.md`), and a `claudemd/<ns>/<name>.md` file replaces
177
+ `claudemd/<name>.md`. Use this to give a project its own version of a shared
178
+ item under the same name, and keep that shared item at the root rather than in
179
+ a namespace every role activates: `rules/code-style.md` is replaced by
180
+ `rules/checkout/code-style.md` for checkout members, while a
181
+ `rules/common/code-style.md` would reach them alongside it. The same skill or
182
+ agent name in two namespaces one member has active is an error naming both
183
+ files; two namespace rules or claudemd files of one name are both delivered.
184
+ A replacement must be usable to replace anything: a skill directory needs its
185
+ `SKILL.md` (pull names one without it), and while an agent file does not parse
186
+ the root agent stays installed. `teamai doctor` lists each replacement as a note. Teams without roles or
187
+ projects are unaffected.
188
+
189
+ Docs have no override. A top-level `docs/<ns>/` that any role or project lists
190
+ under `resources.docs` reaches only members with that namespace active; a
191
+ `docs/<dir>/` nobody lists stays shared with everyone. When a member leaves the
192
+ namespace, their next pull removes its docs that still match the team copy and
193
+ keeps (and names) the ones they edited. Recall and `teamai doctor` follow the
194
+ same filter.
195
+
196
+ Wiki codebase slugs follow the same rule under `resources.wiki`: once any role
197
+ or project lists a `teamwiki/evidence/code/<slug>/` slug there, `recall` only
198
+ surfaces it for members with that namespace active; an undeclared slug stays
199
+ shared. The slug is whatever `teamai codebase --project <slug>` wrote, not
200
+ necessarily the project's manifest id.
201
+
202
+ ## Keep delivered files out of git
203
+
204
+ With `sharing.gitExclude.enabled: true` in `teamai.yaml`, each member's pull lists
205
+ the skills and rules (one file per line, never a skill's directory, so a file a
206
+ member adds to a delivered skill stays visible), agents, `teamai-context` files, hook
207
+ files and team docs (one file per line) it delivered into a project, and each shared
208
+ config file (MCP, `.codex/hooks.json`, OpenCode's) while it holds only teamai's entries,
209
+ in teamai's `delivered` block in the clone's
210
+ `.git/info/exclude` (local to the clone, never committed), so `git add -A` does
211
+ not commit them; a member's own files, and copies they edited, stay visible. `init` writes it for a
212
+ new team; an existing team adds the line and commits it through the normal
213
+ review flow. A member overrides it on their machine with `gitExcludeEnabled:
214
+ true|false` in the project's `config.yaml` (`~/.teamai/projects/<slug>/config.yaml`).
215
+ Either takes effect on the next pull, no `--force`; turned off, the next pull
216
+ removes only that block. `teamai doctor` says where the setting comes from and
217
+ what git still sees; `teamai pull --dry-run` previews the block.
218
+
219
+ ## Team dashboard (web UI)
220
+
221
+ ```bash
222
+ teamai dashboard # start the AI coding session dashboard (default port 3721)
223
+ teamai dashboard --port 8080 # custom port
224
+ ```
225
+
226
+ Opens a local web UI for team coding-session activity and knowledge-base health.
227
+
228
+ ## Team packages (npm + Claude plugins)
229
+
230
+ Declare packages once; members get a prompt to install them (TeamAI never runs
231
+ third-party package code automatically):
232
+
233
+ ```bash
234
+ teamai packages install typescript # npm dependency
235
+ teamai packages install eslint@latest --global # global CLI tool
236
+ teamai packages install code-review@claude-plugins-official # Claude plugin
237
+ teamai push # share the updated teamai.yaml
238
+ ```
239
+
240
+ ## Shared environment variables, hooks and MCP servers
241
+
242
+ ```bash
243
+ teamai env list # what reaches this directory, each with its namespace (values masked)
244
+ teamai env list --reveal # show variable values in plaintext (never a secret's)
245
+ teamai env add <KEY> <VALUE> # add or update in env/env.yaml
246
+ teamai env add <KEY> <VALUE> --project <id> # or --role <ns>: in that namespace's env/<ns>/env.yaml (warns if nothing declares <ns>)
247
+ teamai env remove <KEY> # remove (same --role / --project)
248
+ teamai env add <KEY> --secret -d "<what it is for>" --url <where to get one> # declare a secret in env/secrets.yaml, no value (same --role / --project)
249
+ teamai env remove <KEY> --secret # remove a declared secret (plain `env remove` does too when env.yaml does not set <KEY>)
250
+ teamai remove mcp <name> # root mcp/mcp.yaml if it has the name, else the one namespace file; --role / --project pick a namespace
251
+ ```
252
+
253
+ Env variables, team hooks and MCP servers are scoped like skills: the root file
254
+ (`env/env.yaml`, `hooks/hooks.yaml`, `mcp/mcp.yaml`) reaches everyone, and
255
+ `env/<ns>/env.yaml`, `hooks/<ns>/hooks.yaml`, `mcp/<ns>/mcp.yaml` reach only
256
+ members whose role or project lists `<ns>` under `resources.env`, `resources.hooks`
257
+ or `resources.mcp`. A namespace entry replaces the root entry of the same key, hook
258
+ id or server name. Hooks and MCP servers have no add command, and `teamai push`
259
+ does not pick up `hooks/` or `mcp/`: edit the file in the team repo, then commit
260
+ and push it with git. `teamai doctor` lists each override.
261
+
262
+ - A name twice in one file, in two active namespaces, or an active file that does
263
+ not parse: that type is not applied for affected members and their installed
264
+ state is kept. Fix the file the warning names. A hooks or MCP file with none of
265
+ its top-level keys (`server:` for `servers:`) counts as one that does not parse.
266
+ - Per-entry `projects:` (and `roles:` on env) no longer works: such an entry reaches
267
+ nobody. `roles:` on hooks and MCP still filters for one more minor release. Pull,
268
+ the list commands (`teamai env list`, `teamai mcp list`, `teamai hooks list`,
269
+ `teamai list <env|hooks|mcp> --source repo`), `teamai status` and
270
+ `teamai doctor` name the namespace file each entry belongs in; move it there.
271
+ When `teamai env add` updates a variable carrying either removed key, it keeps
272
+ the key and warns that pull will not deliver the variable, naming that file.
273
+ - An env, hook or MCP entry with a key its schema does not know (a mistyped `role:`)
274
+ also reaches nobody. Pull, the list commands, `teamai status` and
275
+ `teamai doctor` name the file, entry and key; correct the key or remove it.
276
+ A key a later teamai version adds is unknown to an older one, so upgrade every
277
+ member before the team uses a new entry key.
278
+ - Team model profiles work the same way: `models/<ns>/models.yaml`, declared under
279
+ `resources.models`, replaces the root profile with the same `id` for members who
280
+ have `<ns>` active. A member's API key is bound to the profile's gateway origin:
281
+ when an override points at another host, their pull leaves the agent alone and
282
+ asks them to run `teamai models switch team:<id>` to set the key for it.
283
+ - Secrets are declared with no value in `env/secrets.yaml` or `env/<ns>/secrets.yaml`
284
+ (active through `resources.env`; a namespace entry replaces the root entry with the
285
+ same key): a `secrets:` list of `key`, optional `description` and optional `url`
286
+ (where a member gets one). Never put a value there: `teamai env add <KEY> --secret`
287
+ takes none and rejects one. Declare with it or edit the file in the team repo;
288
+ `teamai push` picks it up. Each member sets their own value with `teamai env set KEY`
289
+ in their terminal (`--global` for every team on their machine; a team value still
290
+ wins). That updates MCP servers for the current scope. Run `teamai pull` afterwards
291
+ only to update `env.sh`, and only when the key is an env variable. `teamai env list` shows each secret as `team`, `global`, `environment`,
292
+ `missing` or `unreadable` and never shows a value, `--reveal` included. The `description` is what
293
+ agents see: the session-start hook lists each declared key with it and tells the
294
+ agent to run the CLIs that need them through `teamai env exec --`, so say which
295
+ tool or server uses the key. As the agent, run `teamai env add <KEY> --secret`
296
+ yourself and leave the value to each member's own terminal. A key declared as a secret
297
+ and also set in `env.yaml` is a secret: its `env.yaml` value is not delivered. A
298
+ secrets file that does not parse keeps `env.sh` and MCP servers as they were, and
299
+ `teamai doctor` fails a check naming the file.
300
+ - Have every member upgrade before declaring `env`, `hooks`, `mcp`, `models`, `docs` or `wiki` in a
301
+ manifest: teamai 0.25.0 and the 0.26.0 betas reject those keys and their pull stops.
302
+
303
+ ## When sync fails
304
+
305
+ Run `teamai doctor` first. If it reports hook or path problems, load
306
+ the troubleshooting reference (`"$(teamai skill path core)/references/troubleshooting.md"`). Have the affected member reopen their session; if their tool
307
+ has no session-start hook, they run `teamai pull` manually.
308
+
309
+ ## Capture a lesson learned
310
+
311
+ Turning a tricky fix into team knowledge is **automatic** once recall is on for
312
+ the team (`sharing.recall.enabled: true` in `teamai.yaml`, then `teamai push`; it is
313
+ off by default, and `teamai recall enable` turns it on for one machine only): at the end of a session
314
+ worth sharing, TeamAI prompts the member and the dedicated
315
+ `share` workflow (`teamai skill get share`) summarizes the session and runs
316
+ `teamai contribute`. Nobody has to invoke it by hand. (A member whose teamai config
317
+ cannot be loaded gets no prompt; `teamai skill get share` names the file and the error.)
318
+
319
+ Teams that work in English set `language: en` in `teamai.yaml` and `teamai push`.
320
+ That makes the built-in teamai-recall rule, the TodoWrite hint, and the merged-MR
321
+ hint English only. Omit `language`, or set `zh`, to keep the historical bilingual
322
+ text. Each scope reads its own team repo, so a project install and a user install
323
+ can differ. Members receive the recall rule in that language on the next
324
+ `teamai pull`.
325
+
326
+ (Publishing a **reusable skill** someone authored is a different task — any member
327
+ can do it, see `"$(teamai skill path core)/references/contribute-member.md"`.)
328
+
329
+ ### Turn the sharing prompt on or off (admin)
330
+
331
+ The auto-share prompt is **on by default once recall is on**, and only shows in directories set up
332
+ with teamai (never on a read-only HTTP source, or while a member's teamai config cannot be loaded).
333
+ To disable it team-wide, set this in
334
+ `teamai.yaml` and `teamai push`:
335
+
336
+ ```yaml
337
+ sharing:
338
+ contributeHint:
339
+ enabled: false # team-wide default; members can still override locally
340
+ ```
341
+
342
+ Resolution order: `TEAMAI_CONTRIBUTE_HINT_DISABLED=1` env kill switch > a member's
343
+ local override > this team setting > default (on). Turning it off here only removes
344
+ the nudge; members can still contribute on request.
345
+
346
+ ## Don't
347
+
348
+ - Don't hand-run raw `git` commands.
349
+ - Don't create a second team repo.
350
+ - Don't use `owner/repo` short form — always the full URL.
351
+
352
+ ### Superproject worktrees
353
+
354
+ Initialize each original submodule once. After the parent initializes submodules in a new worktree, run `teamai pull --silent` in each initialized child before starting an AI session; the children inherit the original config and install their own Git hooks. Independent child clones need separate init. On Git < 2.54, if the children use the parent's versioned `core.hooksPath`, put the dispatch line once in each applicable parent hook. Follow the admin guide for the full sequence.
@@ -0,0 +1,101 @@
1
+ # Provider: Tencent TGit
2
+
3
+ git.woa.com is **Tencent-internal only**. TeamAI supports it natively as the `tgit`
4
+ provider — it recognizes the host on its own, so you **never** set `GITLAB_URL`.
5
+ Both `{SKILL_DIR}/references/setup-admin.md` and
6
+ `{SKILL_DIR}/references/join-member.md` point here for the reachability probe and
7
+ the `gf` login; follow the relevant section for whichever flow you are in.
8
+
9
+ ## Probe reachability (setup flow only)
10
+
11
+ When an admin is choosing a platform and hasn't named one, check whether this
12
+ machine can reach TGit. A request to git.woa.com that returns the header
13
+ `x-env: tgit` means TGit is reachable — plain reachability is not enough,
14
+ the header is what confirms it:
15
+
16
+ ```bash
17
+ curl -sS -m 3 -D - -o /dev/null https://git.woa.com 2>/dev/null | grep -qi '^x-env:[[:space:]]*tgit' && echo "tgit: OK" || echo "tgit: unreachable"
18
+ ```
19
+
20
+ If it prints `tgit: OK`, **prefer TGit** and list it first among the choices — it
21
+ is the Tencent-internal default. Choose by account + reachability only, never by
22
+ region. (A member joining an existing `git.woa.com` URL skips the probe — the URL
23
+ already fixes the platform.)
24
+
25
+ ## Log in: install `gf`, then `gf auth login`
26
+
27
+ TeamAI can drive the TGit CLI (`gf`) on the user's behalf. Before the first
28
+ command, **tell the user what this does** — it downloads and installs the `gf`
29
+ binary and, after login, stores an auth credential on their machine — and **get
30
+ their OK to proceed**. Once they agree, you may run the install and login steps
31
+ for them so they don't have to type `gf` commands; their remaining action is
32
+ approving the login in their browser / iOA when it opens. If the user prefers to
33
+ run the commands themselves, show them the exact commands instead.
34
+
35
+ ### 1. Install `gf` (you run this)
36
+
37
+ Use the **same source, path, and check teamai uses** — do not invent your own URL.
38
+ `${TEAMAI_HOME}` is `~/.teamai` unless overridden:
39
+
40
+ ```bash
41
+ set -eu # abort on any failure — never fall through to `gf auth login` on a bad install
42
+
43
+ # pick the tarball for this machine's OS/arch (darwin|linux × x64|arm64)
44
+ os=$(uname -s | tr '[:upper:]' '[:lower:]') # darwin | linux
45
+ arch=$(uname -m); [ "$arch" = "x86_64" ] && arch=x64; [ "$arch" = "aarch64" ] && arch=arm64
46
+ dir="${TEAMAI_HOME:-$HOME/.teamai}/gf"
47
+ url="https://mirrors.tencent.com/repository/generic/gongfeng-cli/files/channels/stable/gf-${os}-${arch}.tar.gz"
48
+
49
+ # unique temp files per attempt so concurrent/interrupted runs never collide,
50
+ # cleaned up on any exit
51
+ mkdir -p "$dir"
52
+ tmp="$dir/gf-download.$$-$RANDOM"
53
+ trap 'rm -f "$tmp.tar.gz" "$tmp.headers"' EXIT
54
+
55
+ # download over HTTPS, verify sha256, THEN extract (the same safe path teamai
56
+ # uses). Fail closed: no advertised digest, or a mismatch, aborts the install.
57
+ curl -fsSL -D "$tmp.headers" -o "$tmp.tar.gz" "$url"
58
+ # The mirror 302-redirects to a content-addressed backend whose URL path is the
59
+ # artifact's sha256; fall back to the x-checksum-sha256 header for direct serves.
60
+ expected=$(grep -i '^location:' "$tmp.headers" | grep -oiE '[0-9a-f]{64}' | tail -1 || true)
61
+ [ -n "$expected" ] || expected=$(grep -i '^x-checksum-sha256:' "$tmp.headers" | tr -d '\r' | awk '{print $2}' || true)
62
+ actual=$( (command -v sha256sum >/dev/null && sha256sum "$tmp.tar.gz" || shasum -a 256 "$tmp.tar.gz") | awk '{print $1}')
63
+ if [ -z "$expected" ] || [ "$expected" != "$actual" ]; then
64
+ echo "gf download integrity check FAILED (expected=$expected actual=$actual)" >&2
65
+ exit 1
66
+ fi
67
+
68
+ tar xz -f "$tmp.tar.gz" -C "$dir"
69
+ # verify exactly as teamai does: the binary exists and is executable
70
+ test -x "$dir/gf/bin/gf"
71
+ echo "gf installed OK"
72
+ ```
73
+
74
+ Only macOS and Linux, on x64 or arm64, are supported.
75
+
76
+ ### 2. Log in (you run this too — don't hand it to the user)
77
+
78
+ ```bash
79
+ "${TEAMAI_HOME:-$HOME/.teamai}/gf/gf/bin/gf" auth login
80
+ ```
81
+
82
+ `gf auth login` starts an interactive flow offering three ways to sign in — iOA, a
83
+ browser device code, or pasting a token. Pick the browser/iOA option, relay
84
+ whatever URL / device code it prints to the user, and ask them to approve it in
85
+ their browser — that approval is the *only* thing they do; the command finishes on
86
+ its own once they do. Confirm with
87
+ `"${TEAMAI_HOME:-$HOME/.teamai}/gf/gf/bin/gf" auth whoami` before continuing.
88
+
89
+ There is no headless substitute for this step: a `TGIT_TOKEN` Personal Access
90
+ Token reaches the git.woa.com REST API only, and the git endpoint rejects it, so
91
+ `init` cannot clone with it. Run the login once on the machine (interactively);
92
+ later unattended runs reuse the credential it stores.
93
+
94
+ ## When you `teamai init` on TGit
95
+
96
+ Because `gf` and login are already done, `init` goes straight to creating/cloning —
97
+ no browser step. When the repo doesn't exist, **accept the create prompt and init
98
+ creates it via the API.** Prefer this over sending the user to the browser first.
99
+
100
+ It only falls back to https://git.woa.com/projects/new if the group/namespace
101
+ doesn't exist or you lack create permission there. No `GITLAB_URL` is ever needed.