@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.
- package/CHANGELOG.md +1416 -0
- package/LICENSE +13 -0
- package/README.ja.md +177 -0
- package/README.ko.md +177 -0
- package/README.md +176 -2
- package/README.th.md +177 -0
- package/README.zh-CN.md +183 -0
- package/agents/teamai-recall.md +406 -0
- package/dist/cli.js +136359 -0
- package/dist/index.js +9 -0
- package/package.json +100 -4
- package/skill-data/core/SKILL.md +250 -0
- package/skill-data/core/references/commands.md +471 -0
- package/skill-data/core/references/contribute-member.md +161 -0
- package/skill-data/core/references/troubleshooting.md +419 -0
- package/skill-data/setup/SKILL.md +80 -0
- package/skill-data/setup/references/join-member.md +189 -0
- package/skill-data/setup/references/manage-admin.md +354 -0
- package/skill-data/setup/references/provider-tgit.md +101 -0
- package/skill-data/setup/references/setup-admin.md +312 -0
- package/skill-data/setup/references/uninstall.md +180 -0
- package/skill-data/share/SKILL.md +70 -0
- package/skill-data/share/references/doc-template.md +44 -0
- package/skill-data/wiki/SKILL.md +317 -0
- package/skill-data/wiki/references/agents/graph-rag-agent.md +344 -0
- package/skill-data/wiki/references/agents/kb-doc-generator.md +325 -0
- package/skill-data/wiki/references/methodology/phase0-collection.md +54 -0
- package/skill-data/wiki/references/methodology/phase1-reverse-engineering.md +89 -0
- package/skill-data/wiki/references/methodology/phase2-document-types.md +341 -0
- package/skill-data/wiki/references/methodology/phase3-ai-enhancement.md +164 -0
- package/skill-data/wiki/references/methodology/phase4-quality.md +232 -0
- package/skill-data/wiki/references/overview.md +125 -0
- package/skill-data/wiki/references/phases/k1-reverse-engineering.md +118 -0
- package/skill-data/wiki/references/phases/k2-documents.md +68 -0
- package/skill-data/wiki/references/phases/k3-ai-native.md +121 -0
- package/skill-data/wiki/references/phases/k4-quality.md +190 -0
- package/skill-data/wiki/references/phases/phase0-init.md +113 -0
- package/skill-data/wiki/references/templates/project-overview.md +149 -0
- package/skill-data/wiki/scripts/scan_repo.py +224 -0
- package/skill-data/wiki/scripts/validate_kb.py +256 -0
- 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.
|