Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ All notable changes to this project will be documented in this file. See [standa

### 💥 Breaking Changes

- An env variable, hook or MCP server with a key its schema does not know, such as a misspelled `role:` or a hand-added `notes:`, is no longer delivered to anyone: the key used to be dropped silently, so a misspelled restriction shipped the entry to every member. `teamai pull` and `teamai doctor` name the file, the entry and the key. `teamai env add`, `teamai env remove` and `teamai remove mcp` keep the key when they rewrite the file. A key that a later version adds to these entries is unknown to this one too, so an entry that uses it is not delivered to a member still on this version: upgrade every member before the team uses a new entry key, as for a new `resources:` key (for [#822](https://github.com/Tencent/teamai-cli/issues/822)).
- An env variable, hook or MCP server with a key its schema does not know, such as a misspelled `role:` or a hand-added `notes:`, is no longer delivered to anyone: the key used to be dropped silently, so a misspelled restriction shipped the entry to every member. `teamai pull`, the list commands, `teamai status` and `teamai doctor` name the file, the entry and the key. `teamai env add` also warns when it updates a variable carrying the unknown key; it, `teamai env remove` and `teamai remove mcp` keep the key when they rewrite the file. A key that a later version adds to these entries is unknown to this one too, so an entry that uses it is not delivered to a member still on this version: upgrade every member before the team uses a new entry key, as for a new `resources:` key (for [#822](https://github.com/Tencent/teamai-cli/issues/822)).
- `manifest/projects.yaml` and `manifest/roles.yaml` now reject a resource namespace that is not a single path segment, as a project id already had to be (the id keeps its own narrower ASCII rule). A namespace becomes a directory component (`skills/<namespace>/`, `agents/<namespace>/`, `learnings/<namespace>/`), so `../evil`, `a/b`, `C:evil`, a bare `..`, any name with a trailing `.` or space — which Win32 strips, making `.. ` arrive as `..` and `frontend.` as `frontend` — and a Windows device name such as `CON` or `COM1` under `resources:` no longer parse; the error names the offending entry. Nothing else is rejected: a namespace that is a plain directory name still parses, non-ASCII names and names with a space included. A manifest that fails to parse now reports the offending entry on one line (`Invalid projects manifest: projects.0.resources.skills.1: ...`) instead of dumping a raw validation object. Two namespaces of one resource type that differ only by case (`frontend`, `Frontend`) are rejected too, within a manifest and between the two, since they name one directory on Windows and macOS. A manifest that ships any of these — a device name, a trailing `.`, a case-only pair — parsed before and fails every pull now; rename the directory and the entry together.
- **Upgrade every member before a team declares a new axis.** `resources:` in `manifest/roles.yaml` and `manifest/projects.yaml` accepts `env`, `hooks`, `mcp`, `models` and `docs`, but teamai 0.25.0 and the 0.26.0 betas reject a `resources:` key they do not know, so a team that declares one breaks pull for every member still on those versions. From this version on, an unknown `resources:` key prints one warning naming the role or project and the key, and the scope syncs as if the key were absent; `teamai roles` and `teamai projects` keep the key when they save the manifest. `teamai roles|projects add/update --namespaces` never write the new keys, so nothing declares them until an admin does by hand (for [#707](https://github.com/Tencent/teamai-cli/issues/707)).
- Per-entry scoping of env variables, hooks and MCP servers gives way to namespace files (see Features). `projects:` on an `env/env.yaml` variable, a `hooks/hooks.yaml` hook or an `mcp/mcp.yaml` server, and `roles:` on an env variable, existed only in the 0.26.0 betas and are removed: such an entry now reaches nobody, and each pull warns with the namespace file to move it to, one per listed id, so a project-only value never falls through to the whole team. `roles:` on hooks and MCP servers, which 0.25.0 shipped, is deprecated: it keeps filtering for one more minor release as 0.25.0 did, a name repeated in one file under different `roles:` included, pull warns once per run and `teamai doctor` has a check, both naming every target file. There is no automatic migration; move each entry into the file the warning names and drop the key. A member with no role in a team with `roles.yaml` received every `roles:`-scoped hook and server; once they move into `hooks/<ns>/` or `mcp/<ns>/`, that member no longer does (for [#707](https://github.com/Tencent/teamai-cli/issues/707)).
- Per-entry scoping of env variables, hooks and MCP servers gives way to namespace files (see Features). `projects:` on an `env/env.yaml` variable, a `hooks/hooks.yaml` hook or an `mcp/mcp.yaml` server, and `roles:` on an env variable, existed only in the 0.26.0 betas and are removed: such an entry now reaches nobody, and pull, the list commands and status warn with the namespace file to move it to, one per listed id, so a project-only value never falls through to the whole team. `teamai env add` also warns when it updates an existing variable carrying either removed key, and preserves the key. `roles:` on hooks and MCP servers, which 0.25.0 shipped, is deprecated: it keeps filtering for one more minor release as 0.25.0 did, a name repeated in one file under different `roles:` included, pull warns once per run and `teamai doctor` has a check, both naming every target file. There is no automatic migration; move each entry into the file the warning names and drop the key. A member with no role in a team with `roles.yaml` received every `roles:`-scoped hook and server; once they move into `hooks/<ns>/` or `mcp/<ns>/`, that member no longer does (for [#707](https://github.com/Tencent/teamai-cli/issues/707)).

### ✨ Features

Expand Down
10 changes: 8 additions & 2 deletions docs/designs/multi-project-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,12 +416,18 @@ declares one of the new axes.

The per-entry keys go away. `projects:` on env, hooks and MCP, and `roles:` on
env, existed only in the 0.26.0 betas: an entry that carries one reaches nobody,
and pull warns with the namespace file to move it to, one per listed id.
and pull, `status`, `env list`, `mcp list`, `hooks list` and
`list <env|hooks|mcp> --source repo` warn with the namespace file to move it to,
one per listed id.
When `teamai env add` updates a variable still carrying one of these removed
keys, it preserves the key and warns that pull will not deliver the variable,
naming the namespace file to move it to.
`roles:` on hooks and MCP shipped in 0.25.0 and keeps filtering for one more
minor release; pull warns once per run and `doctor` has an informational check,
both naming every target file. Model profiles are strict, so a per-entry key
fails the file. An env, hook or MCP entry with any other key its schema does not
know, such as a mistyped `role:`, reaches nobody too, and pull and `doctor` name
know, such as a mistyped `role:`, reaches nobody too. Pull, `status`, `env list`,
`mcp list`, `hooks list`, `list <env|hooks|mcp> --source repo` and `doctor` name
the file, the entry and the key (#822); `env add`, `env remove` and `remove mcp`
keep such a key when they rewrite the file. A key that a later version adds is
unknown to this one as well, so an entry that uses it is not delivered to a member
Expand Down
18 changes: 11 additions & 7 deletions docs/usage-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -976,8 +976,9 @@ projects:
repeats.
- **Where a value comes from.** `teamai env list`, `teamai mcp list`,
`teamai hooks list` and `teamai list <env|hooks|mcp> --source repo` show each
entry's namespace and whether it overrides the root; `teamai status` counts per
namespace; `teamai doctor` lists each override as a note.
entry's namespace and whether it overrides the root, and name every entry that
is not delivered, with why; `teamai status` counts per namespace and names
them too; `teamai doctor` lists each override as a note.
- **Upgrade every member first.** teamai 0.25.0 and the 0.26.0 betas reject a
`resources:` key they do not know, so declaring `env`, `hooks` or `mcp` breaks
their pull. From this version on, an unknown `resources:` key only warns, and
Expand All @@ -987,18 +988,21 @@ The per-entry keys these files replace:

| Key | On | Now |
|---|---|---|
| `projects:` | env, hooks, MCP | removed: the entry reaches nobody, and each pull warns with the file to move it to |
| `projects:` | env, hooks, MCP | removed: the entry reaches nobody; pull, the list commands and status warn with the file to move it to |
| `roles:` | env | removed, the same way |
| `roles:` | hooks, MCP | deprecated: still filters for one minor release, as in 0.25.0, including a name the root file repeats under different `roles:`; pull warns and `teamai doctor` has a check, both naming every target file |

There is no automatic migration: move each entry into the namespace file the
warning names, and drop the key.
When `teamai env add` updates an existing variable that still carries a removed
per-entry `projects:` or `roles:` key, it keeps that key and warns that pull
will not deliver the variable, naming the namespace file to move it to.

An entry with any other key its schema does not know, such as a mistyped `role:`,
reaches nobody as well, and pull and `teamai doctor` name the file, the entry and
the key. Correct the key or remove it. A key that a later teamai version adds is
unknown to an older one too, so upgrade every member before the team uses a new
entry key.
reaches nobody as well, and pull, the list commands, status and `teamai doctor` name the
file, the entry and the key. Correct the key or remove it. A key that a later
teamai version adds is unknown to an older one too, so upgrade every member
before the team uses a new entry key.

A hooks or MCP file that has none of its top-level keys, such as `server:` for
`servers:`, is treated like a file that does not parse: pull keeps the installed
Expand Down
11 changes: 7 additions & 4 deletions docs/usage-guide.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -897,8 +897,9 @@ projects:
- **旧模式**(成员没有角色,且团队没有 `projects.yaml`)只读取根目录文件,行为不变;
`teamai doctor` 会列出根文件中重复的名字。
- **值从哪里来。** `teamai env list`、`teamai mcp list`、`teamai hooks list` 与
`teamai list <env|hooks|mcp> --source repo` 会给出每个条目的 namespace 以及是否覆盖了
根条目;`teamai status` 按 namespace 计数;`teamai doctor` 以提示信息列出每一处覆盖。
`teamai list <env|hooks|mcp> --source repo` 会给出每个条目的 namespace、是否覆盖了
根条目,并指出每个未下发的条目及其原因;`teamai status` 按 namespace 计数并同样
指出它们;`teamai doctor` 以提示信息列出每一处覆盖。
- **先让所有成员升级。** teamai 0.25.0 与 0.26.0 beta 会拒绝不认识的 `resources:` key,
声明 `env`、`hooks` 或 `mcp` 会让这些版本的 pull 失败。从本版本起,未知的
`resources:` key 只会给出警告,`teamai roles` 与 `teamai projects` 保存 manifest 时也会保留它。
Expand All @@ -907,14 +908,16 @@ projects:

| Key | 适用于 | 现在 |
|---|---|---|
| `projects:` | env、hooks、MCP | 已移除:该条目不再下发给任何人,每次 pull 都会警告并给出应迁往的文件 |
| `projects:` | env、hooks、MCP | 已移除:该条目不再下发给任何人;pull、各 list 命令和 status 都会警告并给出应迁往的文件 |
| `roles:` | env | 已移除,处理方式相同 |
| `roles:` | hooks、MCP | 已弃用:在一个次版本内仍像 0.25.0 一样按角色过滤,根文件中以不同 `roles:` 重复的名字也照旧生效;pull 会警告,`teamai doctor` 有一项检查,两者都会列出每个目标文件 |

没有自动迁移:把每个条目移到警告给出的 namespace 文件中,并删掉该 key。
如果 `teamai env add` 更新的已有变量仍带有已移除的按条目 `projects:` 或 `roles:` key,
命令会保留该 key,并警告 pull 不会下发这个变量,同时指出应迁往的 namespace 文件。

条目若带有其 schema 不认识的其他 key(例如拼错的 `role:`),同样不会下发给任何人;
pull 与 `teamai doctor` 会指出文件、条目和该 key。请改正或删除这个 key。
pull、各 list 命令、status 与 `teamai doctor` 会指出文件、条目和该 key。请改正或删除这个 key。
较新版本 teamai 新增的 key 对旧版本同样是未知 key,因此团队使用新的条目 key 之前,
请先让所有成员升级。

Expand Down
15 changes: 10 additions & 5 deletions skill-data/setup/references/manage-admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,17 @@ and push it with git. `teamai doctor` lists each override.
state is kept. Fix the file the warning names. A hooks or MCP file with none of
its top-level keys (`server:` for `servers:`) counts as one that does not parse.
- Per-entry `projects:` (and `roles:` on env) no longer works: such an entry reaches
nobody. `roles:` on hooks and MCP still filters for one more minor release. Pull
and `teamai doctor` name the namespace file each entry belongs in; move it there.
nobody. `roles:` on hooks and MCP still filters for one more minor release. Pull,
the list commands (`teamai env list`, `teamai mcp list`, `teamai hooks list`,
`teamai list <env|hooks|mcp> --source repo`), `teamai status` and
`teamai doctor` name the namespace file each entry belongs in; move it there.
When `teamai env add` updates a variable carrying either removed key, it keeps
the key and warns that pull will not deliver the variable, naming that file.
- An env, hook or MCP entry with a key its schema does not know (a mistyped `role:`)
also reaches nobody. Pull and `teamai doctor` name the file, entry and key; correct
the key or remove it. A key a later teamai version adds is unknown to an older one,
so upgrade every member before the team uses a new entry key.
also reaches nobody. Pull, the list commands, `teamai status` and
`teamai doctor` name the file, entry and key; correct the key or remove it.
A key a later teamai version adds is unknown to an older one, so upgrade every
member before the team uses a new entry key.
- Team model profiles work the same way: `models/<ns>/models.yaml`, declared under
`resources.models`, replaces the root profile with the same `id` for members who
have `<ns>` active. A member's API key is bound to the profile's gateway origin:
Expand Down
5 changes: 4 additions & 1 deletion src/__tests__/e2e/project-scoped-delivery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,10 @@ describe('project-scoped hooks, MCP servers and env variables via the real CLI (
const envList = await runCLI(['env', 'list'], projectRoot, home);
expect(envList.code, envList.output).toBe(0);
expect(envList.output).toMatch(/BILLING_URL=\S+ {2}\(billing\)/);
expect(envList.output).not.toContain('DEVOPS_ONLY');
// The delivery notice for the withheld per-entry `roles:` key names
// DEVOPS_ONLY in its warning; the variable itself must stay out of the
// delivered list, where it would print as `DEVOPS_ONLY=<masked>`.
expect(envList.output).not.toMatch(/DEVOPS_ONLY=/);
}, 60_000);

it('warns about per-entry projects:, naming the namespace file to move the entry to', async () => {
Expand Down
Loading
Loading