Files
market/skills/manage-teams/SKILL.md
Yige e77c658958 feat: 市场支持团队条目类型并上架合同审查团队 (#110)
## 变更 / What

市场此前只有 `agents` 与 `skills` 两类条目。本 PR 加入**团队(teams)**条目类型,并上架第一条真实团队
listing。

The market supported only `agents` and `skills`. This PR adds a
**teams** entry type and lists the first real team.

## 一、支持团队条目类型

「支持一种新条目类型」实际涉及 4 组共 11 个文件,比表面看到的多:

**客户端契约快照**
- 新增 `schemas/market-team-entry.client.schema.json`,用 esbuild 打包客户端
`packages/schemas/src/market.ts` 后导出生成。用同样方法重新生成
`market-agent-entry.client.schema.json` 验证过管线——字节完全一致(含属性顺序),确认不是手工誊抄。

**Sidecar schema**
- `identity.kind` 枚举加 `team`;新增 `$defs.teamSpec`;接入 `spec.oneOf` 与
kind→spec 派发

**校验器(工作量主要在这里)**
- `scripts/catalog/validate_catalog_metadata.py`:`load_legacy`
原先硬编码只认两个根目录。抽出 `CATALOG_ROOTS` 常量同时驱动允许的父目录集合与错误文案;按 kind 分派客户端 schema
校验;`teams` 进 stats 与 `--require-complete` 覆盖统计;把**严格 provenance
比对**与「可安装 pointer 必须自带不可变 ref」两道门禁扩展到团队
- `scripts/i18n/validate-i18n.py`:**它独立重算计数并逐个校验 `entry.json`**,不接团队会漏校
- `.github/workflows/i18n-validate.yml`:变更检测的 grep 不含 `teams/`——**一个只改
teams 的 PR 会报「无 i18n 相关变更,跳过校验」然后零校验通过**
- 测试:`test_validate_catalog_metadata.py` 29→47,`test_validate_i18n.py`
9→17

**顺带修正一条本就不对的规则**:`icon` 此前被要求「每个 entry.json 都必须有非空内联 SVG」,但运行时 schema 里
`marketAgentSchema` 与 `marketTeamSchema` **都没有 `icon` 字段**(只有 skill
有)。也就是说这条规则对 Agent pointer 同样在强加死重量,只因本仓库暂无 agent pointer 条目而未暴露。改为
`ICON_RENDERED_KINDS = {"skill"}`,agent/team 声明 icon
时给**警告**而非错误,文案说明「下一个维护者会以为改它能改变卡片」。

## 二、上架合同审查团队

`teams/contract-review-team/`(`entry.json` + sidecar)。

**团队条目是 fork 指针卡,不分发正文**:市场只存展示元数据 + git-only `source`,真实定义(`team.json`
/ `members.json` / `shared/`)在 `source.repoUrl` 指向的仓库里。安装即
`forkTeam`,更新即 `git pull`——组合固定,因此**没有** `installPolicy` /
`updatePolicy`。

| 字段 | 值 | 依据 |
|---|---|---|
| `source.ref` | `73cd87a9901cc548871927e9d5dbec8e4cc6c2b1` | v0.1.1
的**完整 SHA**。tag 不是可复现 pin,validator 有测试专门拒绝 |
| `latestVersion` | `0.1.1` | 上游真实 tag,与 `release.version` 交叉校验 |
| `license` | `MIT` | 上游仓库真有 LICENSE,已在 pinned ref 的快照中复验 |
| `redistribution` | `source-pointer-only` |
市场从不打包团队正文,只给指针——这是交付形态,与许可证宽松与否无关 |
| `requiredClientVersion` | `10.0.137` | 六个成员都声明了 `FileDigest`
内置工具,它随该版本发布 |
| `memberCount` / `memberNames` | 6 / 5 名 | schema 规定前者**含**组长、后者**不含**
|
| `availability` | `listing-only` | 见下 |

**`availability` 为什么不是 `installable`**:四项证据满足两项(不可变 pin ✓、已知 license
✓),缺的 `reviewedAt` 与 `governance.compliance`
本质是**一次尚未发生的治理审查**——需要具名方在具体日期针对这个确切 ref 审过许可合规、第三方内容与商标使用。没发生的事不能写进目录。

补充一个事实:本仓库**零个 sidecar 有 `compliance` 块,29 个 pointer 条目全是
listing-only**,`installable` 路径从未在任何真实条目上走过。这不阻止安装——fork 由 `source` 驱动。

**`license.evidencePath` 的基准此前是未定义的**:schema 只说
`safeRelativePath`,没规定相对谁。仓库里仅有的两个先例(`guizang-ppt`、`presentation-forge`)都是
vendored 技能,LICENSE 物理上在条目目录里。按那个读法,pointer 条目写 `evidencePath`
断言的是市场目录下有该文件——对 pointer 永远不成立。新增 `license-evidence` 规则按条目形态分派:vendored
要求文件存在(error),pointer 要求条目已 pin(warning),两种读法写进 README。

## 校验 / Validation

```
test_validate_catalog_metadata.py    47 tests  OK
test_validate_i18n.py                17 tests  OK
test_collection_generator.py         exit 0
validate_catalog_metadata.py --require-complete
  0 error, 116 warning   (agents=1, teams=1, publishableSkills=62, sidecars=64)
validate-i18n.py / --online          0 error, 116 warning
translate.py --check                 exit 0
gen-collection-children.py --check   exit 0
```

116 warnings 即加入团队之前的基线——**本条 listing 贡献 0 个警告**。

真实条目上的反向控制(跑在 rsync 副本上,仓库保持干净):

```
source.kind=zip                 → team-entry-schema (error)
install/updatePolicy 出现       → team-entry-schema (error)
requiredClientVersion 漂移      → legacy-consistency (error)
memberCount 漂移                → legacy-consistency (error)
provenance ref 漂移             → legacy-consistency (error)
可安装但无不可变 ref            → installable-evidence (error)
evidencePath 在未 pin 的 pointer → license-evidence (warning)
```

另用**客户端真实校验器**(`parseMarketTeamEntry`,不是快照)验证条目通过,且多写一个字段会被拒。

## 公开信息边界 / Public information boundary

全树扫描无新增命中。团队内容使用「某某科技(北京)有限公司」这类标准中文占位。

---------

Co-authored-by: yi-ge <mizan57533@gmail.com>
2026-09-01 04:15:45 -04:00

12 KiB

name, description, version, type, risk_level, status, disable-model-invocation, tags, metadata, market
name description version type risk_level status disable-model-invocation tags metadata market
manage-teams 创建和管理 Agent 团队,组织多 Agent 协作。Use when 需要多个 Agent 持续协作、建立组织架构,或发布、安装和同步团队仓库时。 1.3.0 procedural medium enabled true
group
collaboration
organization
author updated_at i18n
desirecore 2026-08-25
default_locale source_locale locales zh-CN en-US
en-US zh-CN
zh-CN
en-US
name short_desc description body source_hash translated_by
团队管理 创建团队、管理成员、组织多 Agent 协作 创建和管理 Agent 团队,组织多 Agent 协作。Use when 需要多个 Agent 持续协作、建立组织架构,或发布、安装和同步团队仓库时。 ./SKILL.zh-CN.md sha256:f6d361c54642cb4d human
name short_desc description body source_hash translated_by
Team Management Create teams, manage members, and organize multi-Agent collaboration Create and govern Agent teams. Use when multiple Agents need sustained collaboration, an organizational hierarchy, or a team repository must be published, installed, or synchronized. ./SKILL.md sha256:f6d361c54642cb4d human
icon category required_client_version
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><defs><linearGradient id="mt-a" x1="1" y1="7" x2="16" y2="21" gradientUnits="userSpaceOnUse"><stop stop-color="#007AFF"/><stop offset="1" stop-color="#34C759"/></linearGradient></defs><circle cx="9" cy="7" r="4" fill="url(#mt-a)" fill-opacity="0.15" stroke="url(#mt-a)" stroke-width="1.5"/><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" fill="url(#mt-a)" fill-opacity="0.1" stroke="url(#mt-a)" stroke-width="1.5"/><circle cx="17" cy="8" r="3" fill="url(#mt-a)" fill-opacity="0.2" stroke="url(#mt-a)" stroke-width="1.3"/><path d="M23 21v-1.5a3 3 0 0 0-3-3h-2" stroke="url(#mt-a)" stroke-width="1.3" stroke-linecap="round"/><path d="M19.5 1.2L17.5 4M19.5 1.2L21.5 4M17.5 4h4" stroke="#34C759" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="19.5" cy="1.2" r="1" fill="#34C759"/><circle cx="17.5" cy="4" r="0.9" fill="#34C759" fill-opacity="0.7"/><circle cx="21.5" cy="4" r="0.9" fill="#34C759" fill-opacity="0.7"/></svg> productivity 10.0.108

manage-teams Skill

L0: One-line Summary

Use ManageTeam to inspect, create, and govern Agent teams, with the required checks before organizational changes or remote synchronization.

L1: When to Use

Use a team when:

  • multiple Agents need sustained collaboration around one task and a shared team workdir;
  • a stable supervisor, membership, or parent-child organizational structure is required;
  • a team repository must be published, installed, or synchronized.

Do not create a team when:

  • one expert is needed once: use Delegate(mode="sync" | "async");
  • several experts only need to provide one-off opinions: use Delegate(mode="fan-out");
  • the work is temporary file exploration: use a Worker instead of creating a lasting organization.

A team defines organization, shared directories, and governance. Actual work is still dispatched to members with Delegate.

L2: Execution Specification

1. Inspect Before Mutating

  • If teamId is unknown, call ManageTeam(action="list") first.
  • Before modifying, disbanding, or synchronizing a team, call ManageTeam(action="get", teamId=...) and verify its name, type, supervisor, members, local repository directory, and remote state.
  • Never guess a path under ~/.desirecore; use only the absolute repository path returned by get.
  • list can filter by parentTeamId. With tree=true, teamId selects the subtree root and parentTeamId is ignored.

2. Action Reference

action Purpose Key parameters and notes
list List teams or an organization tree parentTeamId?, tree?, teamId?
get Inspect one team and its repository path teamId
create Create an ephemeral team name or task; supervisor?, members?, memberRouting?, parentTeamId?, workdirMode?
add_member Add one member teamId, agentId
add_members Add members in a batch teamId, members
remove_member Remove one member teamId, agentId
remove_members Remove members in a batch teamId, members
set_supervisor Replace the supervisor teamId, agentId
set_member_source Declare where a member Agent comes from teamId, agentId, memberSource; git needs url (https, will be cloned) and ref (defaults to main), registry needs id+version, core/local need nothing else
update Partially update team configuration teamId; supports name/type/isolation/parentTeamId/description/avatar/avatarImage
promote Promote an ephemeral team to persistent teamId; one-way and never implicit
disband Disband a team teamId; explain impact and confirm unless explicitly requested
fork_team Install a team from a remote repository url; name?, installMembers?; enters approval
push Push a local team to its connected remote teamId; enters approval
pull Pull and validate a team from its connected remote teamId; enters approval

3. Create a Team

Before creation:

  1. Every Agent in supervisor and members must already exist. Verify IDs with ManageAgent(action="list" | "get"); create or install a missing Agent through its corresponding Agent Skill before creating the team.
  2. The DesireCore core Agent, desirecore, cannot be a supervisor. When the core Agent initiates creation, it must explicitly choose a regular Agent as supervisor.
  3. Normally do not add desirecore as a member. Reach core capabilities through Delegate instead.
  4. One Agent may supervise only one team. If the intended supervisor already leads another team, assign a successor there first.

Choose the workdir mode deliberately:

  • merged (default): the shared team directory is primary while member and global workdirs remain available;
  • team_only: exposes only the shared team directory, for high-reliability work where every member must operate on the same project. It does not delete member workdir configuration.

Use memberRouting to express routing intent without pinning a Provider or model:

{
  "supervisor-agent": {
    "tier": "flagship",
    "requiredCapabilities": ["reasoning"],
    "reasoning": "high"
  },
  "member-agent": {
    "tier": "balanced"
  }
}
  • keys must belong to the selected supervisor or members;
  • Agents using a fixed model must not appear in memberRouting;
  • omitted Smart members retain their current routing profile; the concrete Provider/model is resolved when that member executes work.

Example:

{
  "action": "create",
  "name": "Contract Review Project",
  "supervisor": "legal-lead",
  "members": ["contract-reviewer", "risk-analyst"],
  "task": "Review contracts continuously and consolidate risks",
  "workdirMode": "team_only"
}

4. Change Organization and Configuration

  • Prefer batch member actions to avoid observable intermediate states.
  • set_supervisor uses agentId; first verify that the Agent does not already supervise another team.
  • set_member_source declares provenance, it does not move files. A team whose roster still contains a local member is not distributablemembers.lock.json cannot pin an ID that exists only on this machine, so a fork elsewhere would silently come up short a member. Switch each member to git or registry before publishing, then resolve to write the lock. It cannot change a member's role; use set_supervisor for that.
  • update is a patch: omitted fields remain unchanged.
  • parentTeamId: null detaches the team and makes it top-level; an empty string is invalid.
  • type only allows ephemeral → persistent. Repeating the current value is idempotent; use promote for an explicit upgrade.
  • isolation: soft uses shared session isolation; hard uses independent Agent copies.
  • description is the marketplace-facing team description, not the task supplied at creation.

Use a declared avatar with:

{
  "action": "update",
  "teamId": "team-id",
  "avatar": { "char": "CR", "color": "purple" }
}

For an image avatar, use avatarImage.source with dc-media://<mediaId>, a bare mediaId, or an image path inside the workdir. PNG/JPEG/WebP are supported. Do not pass an HTTP(S) URL or base64. Remove the image with { "remove": true }; remove and source are mutually exclusive.

5. Team Lifecycle

  • Disband an ephemeral team after its project is complete so the organization does not accumulate stale teams.
  • Use promote only for an explicit long-term collaboration requirement; promotion is one-way.
  • disband removes the team organization and repository. Execute directly when the user explicitly requested it; otherwise show the get result and confirm the intended target first.

6. Team Repository and Remote Synchronization

The team directory is a Git repository containing governance data such as team.json, member locks, and shared/rules.md.

For local Git work:

  1. obtain the absolute repository path with get;
  2. run status/log/diff/add/commit/tag with Bash in that directory;
  3. after the local commit is complete, call ManageTeam(action="push").

Remote fork_team/push/pull must go through ManageTeam because it enforces team Schema validation, roster consistency, the core-Agent supervisor prohibition, workspace types, out-of-bounds symlink checks, and approval. Do not bypass those controls with raw git push/pull. This rule is not based on an assumption that Agents can never access credentials.

  • push/pull require a remote connected through the client. If none is configured, ask the user to connect or publish the team in team settings.
  • Locally created and forked teams do not inherit a directly pushable remote configuration by default.
  • fork_team defaults to installMembers=true; a same-ID local Agent that has diverged from its lock is protected and skipped rather than overwritten.
  • pull may replace local team configuration. Inspect local state first and identify the target remote in the approval card.

7. Dispatch and Finish

After team creation, dispatch work to the supervisor or members with Delegate:

  • one member: Delegate(target=..., mode="sync" | "async", teamId=...);
  • several members: Delegate(targets=[...], mode="fan-out", teamId=...);
  • prefer team members for sustained collaboration; a one-off outside opinion does not require membership.

Report the team name and ID, type, supervisor and members, workdir mode, organizational changes, and whether remote operations completed. Never expose credentials or a remote URL containing a token.

8. Failure Recovery

  • Agent does not exist: verify the ID; create or install the Agent, then retry.
  • Core Agent cannot supervise: explicitly choose a regular Agent as supervisor.
  • Supervisor already leads another team: run set_supervisor on the existing team before retrying.
  • Remote not configured: ask the user to connect a remote in client team settings; do not guess a hidden API.
  • Local content changed or conflicts exist: obtain the directory with get, inspect Git state, preserve user changes, and only then decide whether to commit, pull, or retry.
  • If this Skill is missing or disabled, the minimal operation may still be executed from the ManageTeam action/parameter Schema and tool error messages. Never bypass the tool by editing AgentFS directly.