Skip to content

fix(config): merge custom toolPaths tool by tool over defaults (#1185) - #1204

Merged
jeff-r2026 merged 4 commits into
Tencent:mainfrom
legend91019:fix/issue-1185-toolpaths-merge
Oct 21, 2026
Merged

jeff-r2026 merged 4 commits into
Tencent:mainfrom
legend91019:fix/issue-1185-toolpaths-merge

Conversation

@legend91019

@legend91019 legend91019 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Extracts DEFAULT_TOOL_PATHS into an exported constant and updates TeamaiConfigBaseSchema.toolPaths to merge user-provided toolPaths tool-by-tool over defaults, preventing partial tool definitions from discarding default configurations for all other built-in tools (such as Claude Code, Cursor, Codex, and CodeBuddy).

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature causing existing behavior to change)
  • Documentation only
  • Refactor / internal cleanup

Test Plan

  • npx tsc --noEmit passes
  • npm run lint passes (oxlint 0 errors, 0 warnings)
  • npx vitest run passes for affected test suites (types.test.ts, tool-roots.test.ts)
  • Added/updated unit tests for the change:
    • Added unit test in src/__tests__/types.test.ts verifying DEFAULT_TOOL_PATHS export and default parse equivalence
    • Added unit test in src/__tests__/types.test.ts verifying tool-by-tool merging preserves unmentioned built-in tools
    • Added unit test in src/__tests__/types.test.ts verifying third-party custom agents can be declared alongside default tools
    • Added unit test in src/__tests__/tool-roots.test.ts verifying sparse declarations override only the named tool while retaining default paths for other tools
  • Real-CLI verification (npm run build -> node dist/index.js):
    • Added end-to-end test in src/__tests__/e2e/toolpaths-sparse-merge-1185.test.ts exercising compiled CLI (dist/index.js) against a local Git bare remote fixture with sparse toolPaths definition (zcode: { skills: '.zcode/skills', rules: '.zcode/rules' }).
    • Verified representative real-CLI run (init --provider git --agent claude,zcode and pull):
      === Real-CLI: teamai init ===
      ℹ Scope: workspace (...)
      ℹ Clone path: .../team-repo
      ✔ Registered as team member: ci
      ✔ Local config saved
      ✔ teamai initialized successfully!
      
      === Real-CLI: teamai pull ===
      ℹ workspace scope detected, skipped user scope
      ✔ [workspace] Synced 1 skills (1 new, 0 updated)
          new: hello-skill
      
      === Verification: delivered file locations ===
      .claude/skills/hello-skill/SKILL.md exists: true
      .zcode/skills/hello-skill/SKILL.md exists: true
      
    • npm run test:e2e -- toolpaths-sparse-merge-1185.test.ts passes:
      ✓ src/__tests__/e2e/toolpaths-sparse-merge-1185.test.ts (2 tests)
        ✓ sparse toolPaths merge over built-in defaults (issue #1185) > delivers skills to default Claude path even when teamai.yaml only declared zcode
        ✓ sparse toolPaths merge over built-in defaults (issue #1185) > also supports custom tool zcode alongside the default tools
      Test Files  1 passed (1)
      

Related Issues

Fixes #1185

Notes for Reviewers

  • In src/types.ts, toolPaths previously relied on .default({...}) on the whole record. Supplying any toolPaths in teamai.yaml bypassed .default(), wiping out all unmentioned tools.
  • We extracted DEFAULT_TOOL_PATHS and used .default({}).transform((custom) => ({ ...DEFAULT_TOOL_PATHS, ...custom })) so that:
    1. An override for a specific tool replaces that tool's entry whole (preserving intentional omission-as-opt-out for that tool's surfaces).
    2. Tools not named by the team retain their built-in defaults (e.g. CodeBuddy keeping its default mcpProject: .mcp.json).

@github-actions

Copy link
Copy Markdown
  • [P1 blocking] Missing real-CLI verification record — PR description, Test Plan. This changes runtime configuration parsing, but the description records only type checking, linting, and unit tests. The first ## Code Review Rules item requires an end-to-end / real-CLI record for runtime changes. Document one representative real-CLI run after npm run build, verifying that a single-tool override preserves other tools’ default paths.

No other confident findings in the specified diff. No PR code was run, built, or installed.

@legend91019

Copy link
Copy Markdown
Contributor Author

Resolved in commit 7a7cc4f.

Added a dedicated real-CLI end-to-end test in src/tests/e2e/toolpaths-sparse-merge-1185.test.ts exercising the compiled CLI artifact (dist/index.js) against a local Git bare remote fixture configured with sparse oolPaths (zcode: { skills: '.zcode/skills', rules: '.zcode/rules' }).

Representative real-CLI execution verifies that:

  1. Running eamai init and eamai pull with --agent claude,zcode delivers skills to both .claude/skills/hello-skill/SKILL.md (default built-in path preserved) and .zcode/skills/hello-skill/SKILL.md (custom path honored).
  2. The PR description Test Plan section has been updated with the full real-CLI verification record.

@STiFLeR7

Copy link
Copy Markdown
Collaborator

Flagging a possible conflict with maintainer direction before this merges (Triage access only, not weighing in on which approach is right — that's a call for @jeff-r2026).

This PR's fix for #1185 changes TeamaiConfigBaseSchema.toolPaths to merge user-provided entries tool-by-tool over the defaults, replacing the current "a custom entry replaces the whole table" behavior.

On #1115 — the same root mechanism, different symptom — @jeff-r2026 was explicit:

Skip the docs. Don't change the replace-whole behavior. When the team yaml sets toolPaths and drops a built-in tool or key, teamai doctor and teamai pull should say that surface is off... Informational only — don't fail the check.

PR #1119 (for #1115) follows that: doctor-only warning, no schema change. This PR goes the other way at the schema level. If both land, #1119's "replace-whole, just warn about it" premise and this PR's "merge tool-by-tool so nothing is silently dropped" premise would be solving overlapping problems with opposite designs — worth a maintainer call on which one should actually ship before either merges, rather than discovering the conflict after the fact.

@github-actions

Copy link
Copy Markdown

No confident findings in the specified diff.

The earlier [P1 blocking] Missing real-CLI verification record finding is resolved: the PR description now documents a build followed by representative init and pull runs, verifying delivery to both the retained default Claude path and the overridden ZCode path. This satisfies the testing requirement.

No PR code was run, built, or installed.

@SaulMoro

SaulMoro commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

@STiFLeR7 I see the conflict with Jeff's earlier direction. My preference as a contributor is the tool-by-tool merge proposed here.

A team that customizes CodeBuddy's paths should still retain the default paths for Claude, Codex, and other tools. Otherwise, customizing one tool requires the team to copy and maintain the entire default table.

This PR preserves whole-entry replacement for the named tool. Omitting settings from a custom CodeBuddy entry still disables that integration. The change only preserves defaults for tools the team has not customized.

If a team wants to block init or pull for specific tools, that should use an explicit tool-selection setting. Missing entries in toolPaths should not carry that policy implicitly.

This changes existing behavior for teams that used toolPaths as an allowlist. @jeff-r2026, would you consider this approach given that compatibility impact?

@SaulMoro

SaulMoro commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

@legend91019 CI is failing on the test suite (Node 20/22/24). Mind taking a look?

@legend91019

Copy link
Copy Markdown
Contributor Author

ok,i will do that

@github-actions

Copy link
Copy Markdown

No confident findings in the specified diff.

The earlier [P1 blocking] Missing real-CLI verification record finding is resolved: the PR description documents a build followed by representative init and pull runs, verifying delivery to both the retained default Claude path and the overridden ZCode path. This satisfies the testing requirement.

No PR code was run, built, or installed.

@SaulMoro

Copy link
Copy Markdown
Collaborator

@legend91019 CI is failing on the test suite (Node 20/22/24). Mind taking a look?

@legend91019

Copy link
Copy Markdown
Contributor Author

yeah,i am testing

@github-actions

Copy link
Copy Markdown

No confident findings in the specified diff.

The earlier [P1 blocking] Missing real-CLI verification record finding is resolved: the PR description documents a build followed by representative init and pull runs, verifying delivery to both the retained default Claude path and the custom ZCode path. This satisfies the testing requirement.

Only the specified diff was read. No PR code was run, built, or installed.

@legend91019

Copy link
Copy Markdown
Contributor Author

@SaulMoro I think the pr is ready, anyway, the thing need you to talk with @jeff-r2026 .

@SaulMoro
SaulMoro self-requested a review October 20, 2026 08:35

@SaulMoro SaulMoro left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not approving yet.

Merge gate. On #1115, @jeff-r2026 asked us not to change the replace-whole behavior, and this PR changes it. I still prefer the tool-by-tool merge, but it needs Jeff's go-ahead before merge.

[P2 non-blocking] A trae-only override now fails to parse. With toolPaths: { trae: { mcpProject: .trae/team-mcp.json } }, the merged default trae-cn.mcpProject: .trae/mcp.json trips the #904 refine. loadTeamConfig then returns null for the whole file. Reproduced with the built CLI on bc91228 (teamai init prints ✖ Invalid teamai.yaml: toolPaths.trae-cn.mcpProject: ...). The same fixture parses on main. Suggested fix: when the team names only one of trae or trae-cn, carry its mcp and mcpProject over to the other before validation.

@jeff-r2026
jeff-r2026 merged commit c6bd126 into Tencent:main Oct 21, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

codebuddy: project-scope MCP written to .codebuddy/mcp.json instead of .mcp.json (mcpProject unused)

4 participants