Tencent / Tencent/teamai-cli

[feat] Extend the delivery check to rules, agents and MCP

Open
#624 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4.8k
Forks
342
Avg merge
13h 48m
Merged PRs (30d)
211

Description

Problem

#598 phase 3 gave doctor its first checks that look at the payload rather than the plumbing, and #625 implements them for two of the seven resource primitives:

skills   ✅ Skills delivered to <tool>     one destination per tool
docs     ✅ Team docs delivered            one destination, tree compare
env      ✅ (pre-existing env check)
hooks    ✅ (pre-existing hook check)
rules    ❌ nothing verifies what landed
agents   ❌ nothing verifies what landed
mcp      ❌ nothing verifies what landed

The three that are left are the same class of bug the issue opens with: the command reports success, the tool receives nothing. #598 said "skills first, because the destination resolver already exists" and predicted rules and agents would be "the same check with a different toolPath field". Implementing it showed that prediction is wrong in two places.

Why it is not just another toolPath field

Rules need their own destination resolver. The filename and the content change per tool:

rules/coding-style.md  (team repo)
  ├─ claude   → .claude/rules/coding-style.md          verbatim copy
  ├─ cursor   → .cursor/rules/coding-style.mdc         derived frontmatter
  └─ copilot  → .github/instructions/coding-style.md   rewritten body

ruleFileExtensionForTool and the two rewriters already exist (src/resources/rules.ts:195-215); nothing exposes "where would this rule land for this tool" as a read-only answer.

Agents break the "list × tools" shape. A skill is desired for every enabled tool. An agent carries spec.targets, so the desired set is a relation, not a product:

 skills:  desired[]        × tools[]        → every pair must exist
-agents:  desired[]        × tools[]
+agents:  desired[].targets                 → per item, and rendered per format

Plus each agent renders into one of three formats (renderForTool, .md / .toml / .json), so validity is format-dependent.

MCP is a different shape entirely, closer to the existing hook check: servers land as an entry inside each tool's native config file, not as a file of their own.

Proposed shape

Rather than teaching doctor about each resource type, give the handlers the seam and let one generic check loop them:

 abstract class ResourceHandler {
   abstract scanTeamForPull(...): Promise<ResourceItem[]>
   abstract pullItem(...): Promise<void>
+  /** Where `item` lands for each tool that can receive it. Read-only. */
+  deliveryTargets(teamConfig, localConfig, item): Promise<{ tool, dest }[]>
 }
flowchart LR
  subgraph today["today (#598)"]
    D1[buildChecks] --> S1["skillTargetForTool<br>doctor knows skills"]
    D1 --> S2["resolveDocsDestination<br>doctor knows docs"]
  end
  subgraph proposed
    D2[buildChecks] --> G["one delivery check"]
    G --> H1[SkillsHandler.deliveryTargets]
    G --> H2[RulesHandler.deliveryTargets]
    G --> H3[AgentsHandler.deliveryTargets]
    G --> H4[DocsHandler.deliveryTargets]
  end

skillTargetForTool (src/resources/skills.ts) and resolveDocsDestination (src/resources/docs.ts) are already that function under another name. This turns them into the first two implementations of a contract, and pullItem keeps using them so the write path and the check can never disagree.

The open decision

These checks now run at the end of every interactive teamai pull, not only in doctor. Skills and docs cost a stat per item. Rules and agents do not:

cost per pull
skills stat per skill per tool
docs stat per file in the bundle
rules read + stat per rule per tool (.mdc needs its frontmatter parsed)
agents parse every agent YAML to learn its targets and render extension

Since #625 that cost has a ceiling. The post-pull pass runs under a 5 second budget that covers building the registry as well as running it, and going over is all or nothing:

teamai pull
  buildChecks + runChecks
    within 5s  ->  print each failure with its fix
    over 5s    ->  "Post-pull checks did not run."
                   the member gets no check at all, not even the cheap ones

An agents check that parses every YAML therefore spends the budget the skills and docs checks need, and those are the ones that catch the bug this work started from. The pass also skips a scope another process has locked, so the concurrent case pays nothing either way.

The question to settle before implementing is whether rules and agents run in the post-pull pass at all, or only in teamai doctor. Check is where that would be expressed, and it now carries two independent axes rather than the one #598 left:

interface Check {
  source: 'local' | 'provider'   // #598: where the answer comes from
  reportedByPull?: string        // #625: the pull already said this itself
  // a third one for cost?
}

Three optional flags on one object is the point where it stops reading. Worth deciding whether cost is a third axis, another value on source, or something the registry says by building two lists instead.

Scope

  • ResourceHandler.deliveryTargets seam, with skills and docs migrated onto it, including the installed gate it subsumes: doctor and the sync answer "can this tool receive X" three different ways today (see comment below)
  • rules delivery check (per tool, per extension, .mdc frontmatter validity)
  • agents delivery check (spec.targets relation, three render formats)
  • mcp check in the hook-check shape (entry present in each tool's native config)
  • decide which of these run post-pull vs doctor-only

Related: #598, #574, #525, #342, #372.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the existing delivery logic in src/resources/skills.ts and src/resources/docs.ts, then read the ResourceHandler seam and Check definition described in the issue. Trace how post-pull checks and doctor are built and run, including the five-second budget. Done means resolving the open execution-scope decision and covering rules, agents, and MCP without duplicating delivery logic.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.