teamai-cli 0.26.0-beta.2 → 0.26.0-beta.4
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 +22 -5
- package/agents/teamai-recall.md +13 -5
- package/dist/index.js +19559 -14437
- package/package.json +2 -1
- package/skill-data/core/SKILL.md +4 -0
- package/skill-data/core/references/commands.md +22 -6
- package/skill-data/core/references/contribute-member.md +22 -2
- package/skill-data/core/references/troubleshooting.md +24 -5
- package/skill-data/setup/references/join-member.md +7 -6
- package/skill-data/setup/references/manage-admin.md +73 -8
- package/skill-data/setup/references/provider-tgit.md +32 -9
- package/skill-data/setup/references/setup-admin.md +6 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teamai-cli",
|
|
3
|
-
"version": "0.26.0-beta.
|
|
3
|
+
"version": "0.26.0-beta.4",
|
|
4
4
|
"description": "TeamAI — Make Every Team AI Native (skill sync + shared knowledge base, powered by Git)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"@types/node": "^20.17.0",
|
|
81
81
|
"@types/semver": "^7.8.0",
|
|
82
82
|
"@vitest/coverage-v8": "^3.2.7",
|
|
83
|
+
"fast-check": "^4.10.2",
|
|
83
84
|
"opencode-ai": "1.18.23",
|
|
84
85
|
"standard-version": "^9.5.0",
|
|
85
86
|
"tsup": "^8.3.0",
|
package/skill-data/core/SKILL.md
CHANGED
|
@@ -105,6 +105,10 @@ teamai recall <q> # Search what the team has already learned
|
|
|
105
105
|
Every other command, every flag, and the flags `--help` hides live in the
|
|
106
106
|
generated reference below. Read it instead of guessing a flag.
|
|
107
107
|
|
|
108
|
+
`teamai pull` mirrors the non-hidden docs you receive into `sharing.docs.localDir`,
|
|
109
|
+
removing stale and local-only documents; an edited doc of a docs namespace you left
|
|
110
|
+
is kept and named. Use a dedicated directory; preview with `--dry-run`.
|
|
111
|
+
|
|
108
112
|
## References
|
|
109
113
|
|
|
110
114
|
In the files below, `{SKILL_DIR}` is the directory `teamai skill path core` prints; a reference file you open on its own writes that directory as `SKILL_DIR` in braces.
|
|
@@ -37,6 +37,7 @@ Generated: do not edit by hand. Regenerate with
|
|
|
37
37
|
- `--skill <path>` — Push a specific skill by path (e.g., ~/.claude/skills/hai/my-skill or skills/hai_dev/my-skill)
|
|
38
38
|
- `--role <id>` — Namespace for new skills, rules and agents (skills/<id>/, rules/<id>/, agents/<id>/)
|
|
39
39
|
- `--project <id>` — Target a project: each new resource goes to that project's namespace for its own type — skills, knowledge for rules, agents (from manifest/projects.yaml)
|
|
40
|
+
- `--branch <name>` — Push to this destination branch instead of a generated teamai/push branch
|
|
40
41
|
|
|
41
42
|
## pull
|
|
42
43
|
|
|
@@ -80,6 +81,8 @@ Generated: do not edit by hand. Regenerate with
|
|
|
80
81
|
|
|
81
82
|
- `teamai remove <type> <names...>` — Remove resource(s) from team repo and all local AI tools (type: skills|rules|agents|mcp)
|
|
82
83
|
- `--force` — Skip confirmation prompt
|
|
84
|
+
- `--role <ns>` — mcp: remove the server from mcp/<ns>/mcp.yaml instead of the root mcp/mcp.yaml
|
|
85
|
+
- `--project <id>` — mcp: remove the server from the project's mcp namespace instead of the root mcp/mcp.yaml
|
|
83
86
|
|
|
84
87
|
## packages
|
|
85
88
|
|
|
@@ -120,6 +123,16 @@ Generated: do not edit by hand. Regenerate with
|
|
|
120
123
|
- `teamai projects` — Manage multi-project resource distribution (orthogonal to roles)
|
|
121
124
|
- `teamai projects list` — List defined projects and the ones active in this directory
|
|
122
125
|
- `teamai projects set [ids...]` — Set the projects active in this directory (comma-separated or repeated; empty to clear)
|
|
126
|
+
- `teamai projects add <id>` — Add a project to manifest/projects.yaml, creating the file if needed (admin)
|
|
127
|
+
- `--namespaces <ns>` — Comma-separated namespaces for knowledge, skills, learnings and agents (e.g. common,checkout); env, hooks, mcp, models and docs are declared by hand
|
|
128
|
+
- `--name <name>` — Display name for the project
|
|
129
|
+
- `-d, --description <desc>` — Description for the project
|
|
130
|
+
- `teamai projects update <id>` — Update a project in manifest/projects.yaml (admin)
|
|
131
|
+
- `--add-namespaces <ns>` — Comma-separated namespaces to add to knowledge, skills, learnings and agents
|
|
132
|
+
- `--remove-namespaces <ns>` — Comma-separated namespaces to remove from knowledge, skills, learnings and agents
|
|
133
|
+
- `--name <name>` — New display name for the project
|
|
134
|
+
- `-d, --description <desc>` — New description for the project
|
|
135
|
+
- `teamai projects remove <id>` — Remove a project from manifest/projects.yaml (admin)
|
|
123
136
|
- `teamai projects members <id>` — List members registered for a project
|
|
124
137
|
|
|
125
138
|
## tags
|
|
@@ -181,7 +194,11 @@ Generated: do not edit by hand. Regenerate with
|
|
|
181
194
|
- `--reveal` — Show env variable values in plaintext (default: masked)
|
|
182
195
|
- `teamai env add <key> <value>` — Add or update a team environment variable
|
|
183
196
|
- `-d, --description <desc>` — Description for the variable
|
|
197
|
+
- `--role <ns>` — Write to env/<ns>/env.yaml instead of env/env.yaml
|
|
198
|
+
- `--project <id>` — Write to the project's env namespace (resources.env in manifest/projects.yaml)
|
|
184
199
|
- `teamai env remove <key>` — Remove a team environment variable
|
|
200
|
+
- `--role <ns>` — Remove from env/<ns>/env.yaml instead of env/env.yaml
|
|
201
|
+
- `--project <id>` — Remove from the project's env namespace (resources.env in manifest/projects.yaml)
|
|
185
202
|
|
|
186
203
|
## hooks
|
|
187
204
|
|
|
@@ -210,8 +227,7 @@ Generated: do not edit by hand. Regenerate with
|
|
|
210
227
|
## models
|
|
211
228
|
|
|
212
229
|
- `teamai models` — Share gateway model profiles and switch agents to them
|
|
213
|
-
- `teamai models list` —
|
|
214
|
-
- `teamai models show <profile>` — Show a model profile without revealing its API key
|
|
230
|
+
- `teamai models list [profile]` — Show team and personal model profiles, or one profile, and the agents using them
|
|
215
231
|
- `teamai models add <id>` — Add a personal model profile stored only on this machine
|
|
216
232
|
- `--name <name>` — Display name
|
|
217
233
|
- `--protocol <protocols>` — Comma-separated: anthropic, openai-chat-completions, openai-responses
|
|
@@ -238,8 +254,8 @@ Generated: do not edit by hand. Regenerate with
|
|
|
238
254
|
## stats
|
|
239
255
|
|
|
240
256
|
- `teamai stats` — Show local skill usage statistics
|
|
241
|
-
- `--by-repo` — Break
|
|
242
|
-
- `--by-time` — Show activity by hour of day
|
|
257
|
+
- `--by-repo` — Break the local event log down per repository
|
|
258
|
+
- `--by-time` — Show local event log activity by hour of day
|
|
243
259
|
|
|
244
260
|
## session
|
|
245
261
|
|
|
@@ -300,7 +316,7 @@ Generated: do not edit by hand. Regenerate with
|
|
|
300
316
|
|
|
301
317
|
- `teamai import` — Import knowledge from local directories, remote repos, organizations, MRs, or iWiki
|
|
302
318
|
- `--dir <path>` — Extract code knowledge from a local directory (same as --from-repo but no clone)
|
|
303
|
-
- `--from-claude` (hidden) — Scan Claude/Cursor rule directories (~/.claude
|
|
319
|
+
- `--from-claude` (hidden) — Scan Claude/Cursor rule directories (the Claude root's rules/ — ~/.claude or the recorded toolRoots.claude — and ~/.cursor/rules)
|
|
304
320
|
- `--from-mr <url>` — Extract learning from merged MR/PR and trigger incremental teamwiki update
|
|
305
321
|
- `--from-iwiki <space-id-or-url>` — Import documents from iWiki Space ID or page URL (requires TAI_PAT_TOKEN)
|
|
306
322
|
- `--resume` (hidden) — Resume an interrupted import session
|
|
@@ -332,7 +348,7 @@ Generated: do not edit by hand. Regenerate with
|
|
|
332
348
|
- `teamai codebase` — Inspect and maintain team-codebase outputs
|
|
333
349
|
- `--extract [path]` — Extract code knowledge and build graph from source
|
|
334
350
|
- `--incremental` (hidden) — Only re-extract changed files (requires prior manifest)
|
|
335
|
-
- `--project <name>` (hidden) — Project slug for --extract (defaults to directory name) and required for --deep-enrich
|
|
351
|
+
- `--project <name>` (hidden) — Project slug for --extract (defaults to the directory name; a checkout's root uses the repo's name) and required for --deep-enrich
|
|
336
352
|
- `--max-files <n>` (hidden) — Max source files to scan (default: 200)
|
|
337
353
|
- `--upgrade-wiki` (hidden) — Migrate docs/team-codebase/ to teamwiki/ graph format
|
|
338
354
|
- `--lint` — Run global consistency lint over the teamwiki knowledge graph
|
|
@@ -3,7 +3,15 @@
|
|
|
3
3
|
Goal: the user turns something they built into team knowledge everyone can pull.
|
|
4
4
|
**Any member can do this — you do not need to be an admin.** The usual entry point
|
|
5
5
|
is the user just asking in plain language, e.g. *"share this xxx skill with my
|
|
6
|
-
team"*, in whatever language they work in
|
|
6
|
+
team"*, in whatever language they work in.
|
|
7
|
+
|
|
8
|
+
**Publishing is a team-visible action — confirm before you run it.** A plain
|
|
9
|
+
worded request tells you *what* the user wants, not that they are ready to push
|
|
10
|
+
it to everyone. Before `teamai push` / `teamai contribute`, show exactly what
|
|
11
|
+
will be shared (which skill or file, and that it goes to the whole team) and get
|
|
12
|
+
an explicit go-ahead. Do not publish from an offhand mention of "sharing" in
|
|
13
|
+
ordinary conversation — only when the user has clearly asked to publish *this*
|
|
14
|
+
thing now.
|
|
7
15
|
|
|
8
16
|
## Which kind of contribution?
|
|
9
17
|
|
|
@@ -89,7 +97,19 @@ The doc lands in the team's `learnings/` and appears for teammates on their next
|
|
|
89
97
|
new rule and a new agent land in that namespace too (a project resolves each
|
|
90
98
|
from its own axis — `knowledge` for rules, `agents` for agents). Without one,
|
|
91
99
|
a new resource whose namespace cannot be resolved stays at the shared root and
|
|
92
|
-
reaches the whole team.
|
|
100
|
+
reaches the whole team. An edit of a skill, rule or agent you received from a
|
|
101
|
+
namespace goes back to that namespace, even when it replaces a shared item of
|
|
102
|
+
the same name; the shared one is left as it is. Use `--branch <name>` when a new push must target a
|
|
103
|
+
specific branch; an existing open PR keeps its recorded branch. TeamAI refuses
|
|
104
|
+
to reset a team-repo clone with user changes, so commit or stash unrelated
|
|
105
|
+
modified, staged, untracked, or conflicted files before retrying.
|
|
106
|
+
|
|
107
|
+
In single-repo mode, a skill or rule under `.teamai/` that matches an older
|
|
108
|
+
version of the team's file, as it does when the branch is behind the default
|
|
109
|
+
branch, is skipped with a warning that it "is an older version of" that file:
|
|
110
|
+
pushing it would revert a teammate's update. To publish an edit of it, bring
|
|
111
|
+
the current version in first (`git fetch origin && git merge origin/<default>`,
|
|
112
|
+
or copy the team's current file over it), redo the edit on top, and push again.
|
|
93
113
|
|
|
94
114
|
## After contributing
|
|
95
115
|
|
|
@@ -48,6 +48,21 @@ This is the #1 onboarding issue. In order:
|
|
|
48
48
|
belongs in the team repo's `manifest/roles.yaml` or `manifest/projects.yaml`,
|
|
49
49
|
which the error names by entry — tell the user to ask a team admin. Do not
|
|
50
50
|
delete the manifest or edit the local clone to get past it.
|
|
51
|
+
`recall` still searches learnings and warns once (`Recall indexed learnings
|
|
52
|
+
only…` or `Recall indexed the shared learnings only…`): what it names is
|
|
53
|
+
missing from results until the manifest is fixed and `teamai pull` rebuilds
|
|
54
|
+
the index, so do not report that the team has none of it. If recall also says
|
|
55
|
+
`Recall skips the older index at <path>…`, the smaller index could not be
|
|
56
|
+
written and that scope was not searched at all: resolve the error it names
|
|
57
|
+
(for example a read-only file or a full disk), then fix the manifest and pull.
|
|
58
|
+
7. **`pull` says `Nothing was synced: <file>: <reason>`.** The project's teamai
|
|
59
|
+
config exists but cannot be read, so no scope syncs there, not even the user
|
|
60
|
+
scope, and the session-start hook syncs nothing either. Show the user the
|
|
61
|
+
file and the reason; `teamai doctor` checks another config and can pass
|
|
62
|
+
here. Moving it aside and re-running `teamai init` replaces their settings
|
|
63
|
+
for that project: do it only with their consent.
|
|
64
|
+
`recall` refuses the same way with `Nothing was searched: <file>: <reason>`:
|
|
65
|
+
no team knowledge was searched, so do not report that the team has none.
|
|
51
66
|
|
|
52
67
|
## Permission / access denied
|
|
53
68
|
|
|
@@ -62,19 +77,23 @@ default is a common cause.
|
|
|
62
77
|
|
|
63
78
|
## GitLab host not detected
|
|
64
79
|
|
|
65
|
-
If `init` can't confirm a self-hosted GitLab instance, set both and retry
|
|
80
|
+
If `init` can't confirm a self-hosted GitLab instance, set both and retry. Use a
|
|
81
|
+
short-lived `api`-scope token via a no-echo prompt (not a literal `export`, which
|
|
82
|
+
lands in shell history), and `unset GITLAB_TOKEN` afterward:
|
|
66
83
|
|
|
67
84
|
```bash
|
|
68
85
|
export GITLAB_URL=https://git.example.com
|
|
69
|
-
export GITLAB_TOKEN
|
|
86
|
+
read -rs GITLAB_TOKEN && export GITLAB_TOKEN # paste when prompted; api scope
|
|
70
87
|
teamai init https://git.example.com/yourgroup/yourrepo
|
|
71
88
|
```
|
|
72
89
|
|
|
73
90
|
## Which tools actually get hooks
|
|
74
91
|
|
|
75
|
-
`teamai hooks inject`
|
|
76
|
-
|
|
77
|
-
|
|
92
|
+
`teamai hooks inject` prints **"Hooks injected into all AI tool settings"** even
|
|
93
|
+
for tools where it wrote nothing. **Do not take that line as proof.** (When the
|
|
94
|
+
team hooks cannot be resolved it exits 1 with the reason instead: the built-in
|
|
95
|
+
hooks are installed, the team hooks are left as they were.) Verify per-tool
|
|
96
|
+
instead:
|
|
78
97
|
|
|
79
98
|
```bash
|
|
80
99
|
teamai doctor # flags tools whose hooks are missing
|
|
@@ -39,12 +39,13 @@ If it fails, Node.js ≥ 20 is missing — have them install Node 20+ first.
|
|
|
39
39
|
|
|
40
40
|
Match the login to the URL's host (do NOT create a second repo):
|
|
41
41
|
|
|
42
|
-
- **`git.woa.com/...`** (Tencent TGit) →
|
|
43
|
-
|
|
44
|
-
`
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
- **`git.woa.com/...`** (Tencent TGit) → after telling the user this installs the
|
|
43
|
+
`gf` binary and stores a credential, and getting their OK, **you may run the
|
|
44
|
+
`gf` install and `gf … auth login` for them** (or show the commands if they
|
|
45
|
+
prefer to run them). Follow `{SKILL_DIR}/references/provider-tgit.md` ("Log in");
|
|
46
|
+
the user's only action is approving the login URL in their browser / iOA. No
|
|
47
|
+
`GITLAB_URL` needed. (No headless shortcut: `TGIT_TOKEN` is REST-API-only and
|
|
48
|
+
cannot clone, so the login has to be run once on the machine.)
|
|
48
49
|
- **`cnb.cool/...`** → install the CNB CLI, then authorize, in this order:
|
|
49
50
|
1. `npm install -g @cnbcool/cnb-cli`
|
|
50
51
|
2. `cnb login` — have the user approve it in the browser (OAuth2 device flow);
|
|
@@ -16,8 +16,13 @@ existing ones:
|
|
|
16
16
|
teamai push # review the diff, then confirm
|
|
17
17
|
teamai push --all # push everything without per-item confirmation
|
|
18
18
|
teamai push --skill <path> # push one specific skill
|
|
19
|
+
teamai push --branch <name> # use an explicit branch for a new push
|
|
19
20
|
```
|
|
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
|
+
|
|
21
26
|
Members receive it automatically the next time they open a session (or when they
|
|
22
27
|
run `teamai pull`).
|
|
23
28
|
|
|
@@ -76,20 +81,50 @@ repo per project:
|
|
|
76
81
|
teamai projects list # projects defined + the ones active in this directory
|
|
77
82
|
teamai projects set [ids...] # set the active project(s) for this directory
|
|
78
83
|
teamai projects members <id> # who is registered on a project
|
|
84
|
+
teamai projects add <id> --namespaces common,<id> # add a project (creates projects.yaml if needed)
|
|
85
|
+
teamai projects update <id> --add-namespaces <ns> # or --remove-namespaces / --name / --description
|
|
86
|
+
teamai projects remove <id> # remove a project
|
|
79
87
|
```
|
|
80
88
|
|
|
81
89
|
A member gets the union of their role resources and their active project's
|
|
82
|
-
resources. Admins declare projects in `manifest/projects.yaml
|
|
90
|
+
resources. Admins declare projects in `manifest/projects.yaml` with the commands
|
|
91
|
+
above, each of which opens a PR (`--dry-run` previews). After `projects remove`,
|
|
92
|
+
keep the project's content in the team repo until members have pulled: that is
|
|
93
|
+
what lets their next pull clean up the copies they deployed.
|
|
83
94
|
|
|
84
|
-
Every namespace that names a directory — `knowledge`, `skills
|
|
85
|
-
either manifest, and `learnings` in `projects.yaml` (a role's `learnings:` is
|
|
95
|
+
Every namespace that names a directory — `knowledge`, `skills`, `agents`, `env`,
|
|
96
|
+
`hooks`, `mcp`, `models` and `docs` in either manifest, and `learnings` in `projects.yaml` (a role's `learnings:` is
|
|
86
97
|
ignored and unchecked) — must be a single path segment: no `/`, `\`, `:` or control character, no trailing
|
|
87
|
-
`.` or space, and not a Windows device name (`CON`, `NUL`, `COM1`, …).
|
|
98
|
+
`.` or space, and not a Windows device name (`CON`, `NUL`, `COM1`, …). `team-codebase`
|
|
99
|
+
cannot be a `docs` namespace (`docs/team-codebase/` is the legacy codebase output). Two
|
|
88
100
|
namespaces of one resource type may not differ only by case, across both
|
|
89
101
|
manifests. A manifest that breaks this, does not parse, or is empty stops
|
|
90
102
|
members' pull for that scope until it is fixed; the error names the entry. Fix
|
|
91
103
|
it rather than deleting it — with no `roles.yaml`, delivery is unfiltered.
|
|
92
104
|
|
|
105
|
+
An item in an active namespace replaces the root item of the same name, whole:
|
|
106
|
+
a skill by directory name (including a root skill a member gets through a tag),
|
|
107
|
+
an agent by file stem, a rule by first-level file name (`rules/<ns>/<name>.md`
|
|
108
|
+
replaces `rules/<name>.md`), and a `claudemd/<ns>/<name>.md` file replaces
|
|
109
|
+
`claudemd/<name>.md`. Use this to give a project its own version of a shared
|
|
110
|
+
item under the same name, and keep that shared item at the root rather than in
|
|
111
|
+
a namespace every role activates: `rules/code-style.md` is replaced by
|
|
112
|
+
`rules/checkout/code-style.md` for checkout members, while a
|
|
113
|
+
`rules/common/code-style.md` would reach them alongside it. The same skill or
|
|
114
|
+
agent name in two namespaces one member has active is an error naming both
|
|
115
|
+
files; two namespace rules or claudemd files of one name are both delivered.
|
|
116
|
+
A replacement must be usable to replace anything: a skill directory needs its
|
|
117
|
+
`SKILL.md` (pull names one without it), and while an agent file does not parse
|
|
118
|
+
the root agent stays installed. `teamai doctor` lists each replacement as a note. Teams without roles or
|
|
119
|
+
projects are unaffected.
|
|
120
|
+
|
|
121
|
+
Docs have no override. A top-level `docs/<ns>/` that any role or project lists
|
|
122
|
+
under `resources.docs` reaches only members with that namespace active; a
|
|
123
|
+
`docs/<dir>/` nobody lists stays shared with everyone. When a member leaves the
|
|
124
|
+
namespace, their next pull removes its docs that still match the team copy and
|
|
125
|
+
keeps (and names) the ones they edited. Recall and `teamai doctor` follow the
|
|
126
|
+
same filter.
|
|
127
|
+
|
|
93
128
|
## Team dashboard (web UI)
|
|
94
129
|
|
|
95
130
|
```bash
|
|
@@ -111,15 +146,45 @@ teamai packages install code-review@claude-plugins-official # Claude plugin
|
|
|
111
146
|
teamai push # share the updated teamai.yaml
|
|
112
147
|
```
|
|
113
148
|
|
|
114
|
-
## Shared environment variables
|
|
149
|
+
## Shared environment variables, hooks and MCP servers
|
|
115
150
|
|
|
116
151
|
```bash
|
|
117
|
-
teamai env list #
|
|
152
|
+
teamai env list # what reaches this directory, each with its namespace (values masked)
|
|
118
153
|
teamai env list --reveal # show values in plaintext
|
|
119
|
-
teamai env add <KEY> <VALUE> # add or update
|
|
120
|
-
teamai env
|
|
154
|
+
teamai env add <KEY> <VALUE> # add or update in env/env.yaml
|
|
155
|
+
teamai env add <KEY> <VALUE> --project <id> # or --role <ns>: in that namespace's env/<ns>/env.yaml (warns if nothing declares <ns>)
|
|
156
|
+
teamai env remove <KEY> # remove (same --role / --project)
|
|
157
|
+
teamai remove mcp <name> # root mcp/mcp.yaml if it has the name, else the one namespace file; --role / --project pick a namespace
|
|
121
158
|
```
|
|
122
159
|
|
|
160
|
+
Env variables, team hooks and MCP servers are scoped like skills: the root file
|
|
161
|
+
(`env/env.yaml`, `hooks/hooks.yaml`, `mcp/mcp.yaml`) reaches everyone, and
|
|
162
|
+
`env/<ns>/env.yaml`, `hooks/<ns>/hooks.yaml`, `mcp/<ns>/mcp.yaml` reach only
|
|
163
|
+
members whose role or project lists `<ns>` under `resources.env`, `resources.hooks`
|
|
164
|
+
or `resources.mcp`. A namespace entry replaces the root entry of the same key, hook
|
|
165
|
+
id or server name. Hooks and MCP servers have no add command, and `teamai push`
|
|
166
|
+
does not pick up `hooks/` or `mcp/`: edit the file in the team repo, then commit
|
|
167
|
+
and push it with git. `teamai doctor` lists each override.
|
|
168
|
+
|
|
169
|
+
- A name twice in one file, in two active namespaces, or an active file that does
|
|
170
|
+
not parse: that type is not applied for affected members and their installed
|
|
171
|
+
state is kept. Fix the file the warning names. A hooks or MCP file with none of
|
|
172
|
+
its top-level keys (`server:` for `servers:`) counts as one that does not parse.
|
|
173
|
+
- Per-entry `projects:` (and `roles:` on env) no longer works: such an entry reaches
|
|
174
|
+
nobody. `roles:` on hooks and MCP still filters for one more minor release. Pull
|
|
175
|
+
and `teamai doctor` name the namespace file each entry belongs in; move it there.
|
|
176
|
+
- An env, hook or MCP entry with a key its schema does not know (a mistyped `role:`)
|
|
177
|
+
also reaches nobody. Pull and `teamai doctor` name the file, entry and key; correct
|
|
178
|
+
the key or remove it. A key a later teamai version adds is unknown to an older one,
|
|
179
|
+
so upgrade every member before the team uses a new entry key.
|
|
180
|
+
- Team model profiles work the same way: `models/<ns>/models.yaml`, declared under
|
|
181
|
+
`resources.models`, replaces the root profile with the same `id` for members who
|
|
182
|
+
have `<ns>` active. A member's API key is bound to the profile's gateway origin:
|
|
183
|
+
when an override points at another host, their pull leaves the agent alone and
|
|
184
|
+
asks them to run `teamai models switch team:<id>` to set the key for it.
|
|
185
|
+
- Have every member upgrade before declaring `env`, `hooks`, `mcp`, `models` or `docs` in a
|
|
186
|
+
manifest: teamai 0.25.0 and the 0.26.0 betas reject those keys and their pull stops.
|
|
187
|
+
|
|
123
188
|
## When sync fails
|
|
124
189
|
|
|
125
190
|
Run `teamai doctor` first. If it reports hook or path problems, load
|
|
@@ -22,12 +22,15 @@ is the Tencent-internal default. Choose by account + reachability only, never by
|
|
|
22
22
|
region. (A member joining an existing `git.woa.com` URL skips the probe — the URL
|
|
23
23
|
already fixes the platform.)
|
|
24
24
|
|
|
25
|
-
## Log in: install `gf`, then `gf auth login`
|
|
25
|
+
## Log in: install `gf`, then `gf auth login`
|
|
26
26
|
|
|
27
|
-
TeamAI
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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.
|
|
31
34
|
|
|
32
35
|
### 1. Install `gf` (you run this)
|
|
33
36
|
|
|
@@ -35,17 +38,37 @@ Use the **same source, path, and check teamai uses** — do not invent your own
|
|
|
35
38
|
`${TEAMAI_HOME}` is `~/.teamai` unless overridden:
|
|
36
39
|
|
|
37
40
|
```bash
|
|
41
|
+
set -eu # abort on any failure — never fall through to `gf auth login` on a bad install
|
|
42
|
+
|
|
38
43
|
# pick the tarball for this machine's OS/arch (darwin|linux × x64|arm64)
|
|
39
44
|
os=$(uname -s | tr '[:upper:]' '[:lower:]') # darwin | linux
|
|
40
45
|
arch=$(uname -m); [ "$arch" = "x86_64" ] && arch=x64; [ "$arch" = "aarch64" ] && arch=arm64
|
|
41
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"
|
|
42
48
|
|
|
43
|
-
#
|
|
49
|
+
# unique temp files per attempt so concurrent/interrupted runs never collide,
|
|
50
|
+
# cleaned up on any exit
|
|
44
51
|
mkdir -p "$dir"
|
|
45
|
-
|
|
46
|
-
|
|
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"
|
|
47
69
|
# verify exactly as teamai does: the binary exists and is executable
|
|
48
|
-
test -x "$dir/gf/bin/gf"
|
|
70
|
+
test -x "$dir/gf/bin/gf"
|
|
71
|
+
echo "gf installed OK"
|
|
49
72
|
```
|
|
50
73
|
|
|
51
74
|
Only macOS and Linux, on x64 or arm64, are supported.
|
|
@@ -138,12 +138,15 @@ with `repo` scope — instead.)
|
|
|
138
138
|
|
|
139
139
|
### GitLab (gitlab.com)
|
|
140
140
|
|
|
141
|
-
Set a Personal Access Token with `api` scope
|
|
141
|
+
Set a Personal Access Token with `api` scope. Prefer a **short-lived** token and
|
|
142
|
+
pull it from a secret manager or a no-echo prompt rather than typing the literal
|
|
143
|
+
value (a pasted `export` lands in shell history and process listings):
|
|
142
144
|
```bash
|
|
143
|
-
export GITLAB_TOKEN
|
|
145
|
+
read -rs GITLAB_TOKEN && export GITLAB_TOKEN # paste when prompted; not echoed
|
|
144
146
|
```
|
|
145
147
|
Self-hosted GitLab: also set the instance URL first —
|
|
146
|
-
`export GITLAB_URL=https://git.example.com`.
|
|
148
|
+
`export GITLAB_URL=https://git.example.com`. Run `unset GITLAB_TOKEN` when
|
|
149
|
+
`teamai init` is done.
|
|
147
150
|
|
|
148
151
|
For GitHub/GitLab, `teamai init` installs any helper CLI it needs automatically.
|
|
149
152
|
|