feat(skills): add Trae CN as a supported skill host#142
Conversation
Summary by CodeRabbit
WalkthroughAdds a new bundled skill host "Trae CN" (agent name "trae-cn") across the repo. Changes include docs (README, docs/commands), a new home-directory resolver, registration in bundled-skill registries, additions to available agent names and host ordering, i18n keys and messages, publication mode updates (symlink-capable), host label and error-key handling, and extensive test coverage for install/publish/list/init flows targeting Trae CN. Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant Registry
participant PathResolver
participant Publication
participant FS
User->>CLI: run "oo install/publish --agent trae-cn"
CLI->>PathResolver: resolveTraeCnHomeDirectory(env)
PathResolver-->>CLI: trae-cn home path
CLI->>Registry: getBundledSkillFiles("oo", "trae-cn")
Registry-->>CLI: list of asset files
CLI->>Publication: resolveManagedSkillPublicationMode("trae-cn")
Publication-->>CLI: symlink-or-copy
CLI->>FS: ensure canonical store (create if missing)
FS-->>CLI: canonical path confirmed
CLI->>FS: create symlink at trae-cn host target -> canonical path
FS-->>CLI: symlink created
CLI-->>User: success output (includes host label via i18n)
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
Comment |
Trae CN ships under a separate `~/.trae-cn` home directory, so users of that variant could not receive oo-managed skills through any of the existing host code paths. Register `trae-cn` as a first-class agent across path resolution, bundled skill assets, host labels and errors, the i18n catalog, and the preflight, list, install, publish, and remove commands, reusing the CodeBuddy-derived SKILL content already embedded for Trae. Documentation and tests are updated to match. Signed-off-by: Kevin Cui <bh@bugs.cc>
2d874ed to
83ad5ae
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (3)
src/application/commands/skills/managed-skill-host-labels.ts (1)
10-31: 🏗️ Heavy liftConsolidate host metadata mappings into one shared config object.
Line 10 maintains one of several parallel host-key mappings; adding
trae-cnrequired synchronized edits in multiple files, which is drift-prone. Consider a single host config (e.g.,labelKey,missingErrorKey,homeResolver) consumed by all host-specific helpers.As per coding guidelines, "Consolidate multiple switch/map structures that share the same keys into a single configuration object (data-driven over parallel mappings)" and "Extract shared utilities when identical logic appears in 2+ files".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/application/commands/skills/managed-skill-host-labels.ts` around lines 10 - 31, The switch on agentName in managed-skill-host-labels.ts should be replaced by a single shared host configuration object (mapping agent keys to a small config with properties like labelKey, missingErrorKey, and homeResolver) and have this file lookup translator.t(config.labelKey) rather than hardcoding cases; create the shared config (e.g., HOST_CONFIG with entries for "claude","codebuddy","codex","hermes","openclaw","qoderwork","trae","trae-cn","workbuddy") and update other host-specific helpers to consume the same HOST_CONFIG so adding "trae-cn" is a single edit across the codebase. Ensure the default branch throws or narrows using the config lookup (instead of `agentName satisfies never`) and export the config for reuse by functions that previously used parallel switch/map logic.src/application/commands/skills/list.cli.test.ts (1)
387-414: ⚡ Quick winPrefer a table-driven host matrix instead of adding another copy-pasted host test.
Line 387 onward repeats the same setup/assertion flow used by adjacent host cases. Converting these host-specific tests into one parameterized loop will reduce drift and make future host additions cheaper.
As per coding guidelines, "Extract repeated setup (mocks, stubs, setup objects) into local factory functions in test files; avoid copy-pasting test setup".♻️ Suggested refactor shape
+const startupSynchronizedHostCases = [ + ["OpenClaw", resolveOpenClawHomeDirectory], + ["QoderWork", resolveQoderWorkHomeDirectory], + ["CodeBuddy", resolveCodeBuddyHomeDirectory], + ["WorkBuddy", resolveWorkBuddyHomeDirectory], + ["Trae", resolveTraeHomeDirectory], + ["Trae CN", resolveTraeCnHomeDirectory], + ["Hermes", resolveHermesHomeDirectory], +] as const; + +for (const [hostLabel, resolveHomeDirectory] of startupSynchronizedHostCases) { + test(`lists startup-synchronized ${hostLabel} bundled installs when Codex is not installed`, async () => { + const sandbox = await createCliSandbox(); + const homeDirectory = resolveHomeDirectory(sandbox.env); + try { + await mkdir(homeDirectory, { recursive: true }); + await sandbox.run(["skills", "install", "oo"], { version: "9.9.9" }); + const result = await sandbox.run(["skills", "list"], { version: "9.9.9" }); + expect(result.exitCode).toBe(0); + expect(result.stderr).toBe(""); + expect(result.stdout).toBe(["✓ Found 4 skills.", "", ...createExpectedBundledSkillLines(hostLabel)].join("\n")); + } finally { + await sandbox.cleanup(); + } + }); +}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/application/commands/skills/list.cli.test.ts` around lines 387 - 414, The test "lists startup-synchronized Trae CN bundled installs when Codex is not installed" duplicates setup/assertion used by other host-specific tests; refactor into a table-driven matrix test that iterates hosts (e.g., "Trae CN", other hosts) and runs the same flow using the existing helpers createCliSandbox, resolveTraeCnHomeDirectory (or a generic resolveHomeDirectory factory), sandbox.run(["skills","install","oo"], {version:"9.9.9"}), sandbox.run(["skills","list"], {version:"9.9.9"}), and assertions against createExpectedBundledSkillLines; extract common setup/cleanup into a local factory function and replace the repeated test with a single parameterized test that supplies host names and expected lines.src/application/commands/skills/check.test.ts (1)
252-284: ⚡ Quick winExtract repeated preflight-agent test setup into a shared local helper.
This new case repeats the same sandbox/setup/assert/cleanup shape already duplicated across multiple agent tests; please route this through a local factory/helper to keep future host additions cheaper and less error-prone.
♻️ Suggested direction
- test("checks Trae CN as a requested agent", async () => { - const sandbox = await createCliSandbox(); - const traeCnHomeDirectory = resolveTraeCnHomeDirectory(sandbox.env); - const storePaths = resolveStorePaths({ - appName: APP_NAME, - env: sandbox.env, - platform: process.platform, - }); - const canonicalRootDirectoryPath = resolveLocalSkillCanonicalRootDirectoryPath( - storePaths.settingsFilePath, - ); - - try { - await mkdir(traeCnHomeDirectory, { recursive: true }); - - const result = await sandbox.run([ - "skills", - "preflight", - "--agent", - "trae-cn", - ]); - - expect(result.exitCode).toBe(0); - expect(result.stderr).toBe(""); - expect(result.stdout).toBe( - `Local skill editing is ready. Writable storage: ${canonicalRootDirectoryPath}. Supported hosts: 1.\n`, - ); - expect(await readdir(canonicalRootDirectoryPath)).toEqual([]); - } - finally { - await sandbox.cleanup(); - } - }); + test("checks Trae CN as a requested agent", async () => { + await expectRequestedAgentPreflightSuccess({ + agentName: "trae-cn", + resolveHomeDirectory: resolveTraeCnHomeDirectory, + }); + });As per coding guidelines, "Extract repeated setup (mocks, stubs, setup objects) into local factory functions in test files; avoid copy-pasting test setup."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/application/commands/skills/check.test.ts` around lines 252 - 284, Extract the repeated preflight-agent test setup into a local helper factory (e.g., a function in this test file like createPreflightAgentSandbox) that encapsulates createCliSandbox(), resolving traeCnHomeDirectory via resolveTraeCnHomeDirectory(env), computing storePaths with resolveStorePaths({ appName: APP_NAME, env, platform: process.platform }), deriving canonicalRootDirectoryPath via resolveLocalSkillCanonicalRootDirectoryPath(storePaths.settingsFilePath), creating the directory (mkdir(..., { recursive: true })), running sandbox.run(["skills","preflight","--agent","trae-cn"]) and returning the sandbox plus result and canonicalRootDirectoryPath; then update this test to call that helper and keep only the asserts (expect exitCode/stderr/stdout and readdir check) and finally call sandbox.cleanup() from the helper or test as appropriate to avoid duplication across agent tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/application/commands/skills/check.test.ts`:
- Around line 252-284: Extract the repeated preflight-agent test setup into a
local helper factory (e.g., a function in this test file like
createPreflightAgentSandbox) that encapsulates createCliSandbox(), resolving
traeCnHomeDirectory via resolveTraeCnHomeDirectory(env), computing storePaths
with resolveStorePaths({ appName: APP_NAME, env, platform: process.platform }),
deriving canonicalRootDirectoryPath via
resolveLocalSkillCanonicalRootDirectoryPath(storePaths.settingsFilePath),
creating the directory (mkdir(..., { recursive: true })), running
sandbox.run(["skills","preflight","--agent","trae-cn"]) and returning the
sandbox plus result and canonicalRootDirectoryPath; then update this test to
call that helper and keep only the asserts (expect exitCode/stderr/stdout and
readdir check) and finally call sandbox.cleanup() from the helper or test as
appropriate to avoid duplication across agent tests.
In `@src/application/commands/skills/list.cli.test.ts`:
- Around line 387-414: The test "lists startup-synchronized Trae CN bundled
installs when Codex is not installed" duplicates setup/assertion used by other
host-specific tests; refactor into a table-driven matrix test that iterates
hosts (e.g., "Trae CN", other hosts) and runs the same flow using the existing
helpers createCliSandbox, resolveTraeCnHomeDirectory (or a generic
resolveHomeDirectory factory), sandbox.run(["skills","install","oo"],
{version:"9.9.9"}), sandbox.run(["skills","list"], {version:"9.9.9"}), and
assertions against createExpectedBundledSkillLines; extract common setup/cleanup
into a local factory function and replace the repeated test with a single
parameterized test that supplies host names and expected lines.
In `@src/application/commands/skills/managed-skill-host-labels.ts`:
- Around line 10-31: The switch on agentName in managed-skill-host-labels.ts
should be replaced by a single shared host configuration object (mapping agent
keys to a small config with properties like labelKey, missingErrorKey, and
homeResolver) and have this file lookup translator.t(config.labelKey) rather
than hardcoding cases; create the shared config (e.g., HOST_CONFIG with entries
for
"claude","codebuddy","codex","hermes","openclaw","qoderwork","trae","trae-cn","workbuddy")
and update other host-specific helpers to consume the same HOST_CONFIG so adding
"trae-cn" is a single edit across the codebase. Ensure the default branch throws
or narrows using the config lookup (instead of `agentName satisfies never`) and
export the config for reuse by functions that previously used parallel
switch/map logic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8076ee28-3281-4958-8ee4-dfd72599fe91
📒 Files selected for processing (19)
README-ZH_CN.mdREADME.mddocs/commands.mddocs/commands.zh-CN.mdsrc/application/commands/skills/bundled-skill-observation.test.tssrc/application/commands/skills/bundled-skill-paths.tssrc/application/commands/skills/check.test.tssrc/application/commands/skills/embedded-assets.test.tssrc/application/commands/skills/embedded-assets.tssrc/application/commands/skills/index.test.tssrc/application/commands/skills/init.test.tssrc/application/commands/skills/list.cli.test.tssrc/application/commands/skills/list.tssrc/application/commands/skills/managed-skill-host-errors.tssrc/application/commands/skills/managed-skill-host-labels.tssrc/application/commands/skills/managed-skill-publication.test.tssrc/application/commands/skills/managed-skill-publication.tssrc/application/commands/skills/publish.test.tssrc/i18n/catalog.ts
Trae CN ships under a separate
~/.trae-cnhome directory, so users of that variant could not receive oo-managed skills through any of the existing host code paths. Registertrae-cnas a first-class agent across path resolution, bundled skill assets, host labels and errors, the i18n catalog, and the preflight, list, install, publish, and remove commands, reusing the CodeBuddy-derived SKILL content already embedded for Trae. Documentation and tests are updated to match.