Embed agent skills synced from muxinc/mux-skills - #72
Conversation
Adds a skill/ directory vendored from muxinc/skills, a codegen script that embeds the files as string constants so compiled binaries carry them, and a mux docs path command that writes the skills to the XDG data directory and prints their paths for agents. A sync-skills workflow keeps skill/ current: muxinc/skills sends a repository_dispatch on skill changes (weekly cron as backstop) and the workflow opens a PR only when content changed, recording the source commit in skill/manifest.json. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mux docs install copies the embedded agent skills into an agent skills directory (default ~/.claude/skills, which Claude Code auto-loads), so developers get skill discovery with no CLAUDE.md or AGENTS.md changes. The root help now carries an Agent support note pointing at mux docs path and mux docs install, giving any agent that runs --help a zero-config discovery path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The command locates and installs agent skills; docs themselves are never shipped, so the old name was misleading. Also matches what agents guess unprompted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| files.push(destination); | ||
| } | ||
| return { dir: targetDir, files }; | ||
| } |
There was a problem hiding this comment.
Stale skills left on disk
Medium Severity
materializeSkills and installSkills only overwrite files that still exist in the embed. They never remove skill directories or reference files that disappeared in a newer CLI build, so a refresh cannot make the on-disk copy match. For mux skills install, Claude Code would keep auto-loading those obsolete skills.
Reviewed by Cursor Bugbot for commit a2819b9. Configure here.
| The next tagged release will embed these files in the compiled | ||
| binaries via `src/lib/embedded-skills.gen.ts`. | ||
| branch: chore/sync-agent-skills | ||
| delete-branch: true |
There was a problem hiding this comment.
Sync PRs skip CI
Medium Severity
peter-evans/create-pull-request runs with the default GITHUB_TOKEN, so the opened sync PR does not trigger other workflows. Required CI checks on pull_request stay pending and block merge, leaving the automated skills sync unable to land without a manual workaround.
Reviewed by Cursor Bugbot for commit a2819b9. Configure here.
Refreshes the data-directory copy and any ~/.claude/skills install to match the installed CLI, then checks the npm registry (reusing the update-notifier helpers) and advises upgrading when a newer release is available. Skills stay release-pinned: the freshest copy always comes from upgrading the CLI, keeping skill text in lockstep with the binary whose commands it documents. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The general mux skill duplicated mux-docs routing; the CLI and clipping skills are parked upstream for now. The sync workflow copies whatever skills muxinc/mux-skills publishes, so re-adding them later requires no CLI changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
muxinc/skills is the canonical public skills repo. The sync workflow now uses an explicit allowlist (mux-docs) because that repo also publishes skills with vendored reference docs, which the CLI intentionally does not embed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| export function hasInstalledSkills( | ||
| targetDir: string = getDefaultAgentSkillsDir(), | ||
| ): boolean { | ||
| return listSkills().some((skill) => existsSync(join(targetDir, skill.path))); |
There was a problem hiding this comment.
Update misses renamed skills
Medium Severity
hasInstalledSkills only looks for paths from the current embedded skill set. After a rename or full replace in a later CLI release, mux skills update treats ~/.claude/skills as unset, skips installSkills, and tells the user no copy was found—even when the old skill directory is still there and Claude Code still loads it.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit dda5b08. Configure here.
Fetches mux.com/llms.txt, searches it CLI-side, and prints only the matching page URLs, so agents locate a docs page without reading the 206-entry index into context. llms-full.txt is excluded from results. No docs are stored locally. The embedded mux-docs skill now prescribes a cost-ordered fetch workflow that uses this command first. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
There are 5 total unresolved issues (including 3 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 355edb4. Configure here.
| .arguments('<query...:string>') | ||
| .option('--limit <n:number>', 'Maximum number of results', { default: 5 }) | ||
| .option('--json', 'Output JSON instead of pretty format') | ||
| .action(async (options: DocsFindOptions, ...query: string[]) => { |
There was a problem hiding this comment.
Variadic query args mishandled
High Severity
Cliffy passes a named variadic <query...> as one string[] argument. Capturing it with a rest parameter nests that array, so query.join(' ') turns mux docs find live streaming into the single term live,streaming and search returns no matches. The same pattern in assets create uses .flat() for this reason.
| .action(async (options: DocsFindOptions, ...query: string[]) => { | |
| .action(async (options: DocsFindOptions, query: string[]) => { |
Reviewed by Cursor Bugbot for commit 355edb4. Configure here.
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: muxinc/skills | ||
| path: .skills-src |
There was a problem hiding this comment.
Shallow clone empties skills SHA
High Severity
actions/checkout defaults to fetch-depth: 1, but the sync step runs git log with a pathspec to find the last commit that touched the allowlisted skills. In a shallow clone that returns empty whenever HEAD did not touch those paths, so skill/manifest.json gets "commit": "" and the embedded-skills test fails. Weekly cron and manual dispatch are especially exposed.
| path: .skills-src | |
| - name: Check out muxinc/skills | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: muxinc/skills | |
| path: .skills-src | |
| fetch-depth: 0 |
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 355edb4. Configure here.


What this does
Ships Mux's docs-discovery agent skill inside the CLI binary and keeps it in sync with muxinc/skills automatically.
skill/— vendored copy of themux-docsagent skill (~5KB of instruction markdown). No docs content ships — the skill routes agents to live docs at mux.com/llms.txt at answer time, so answers always reflect today's published docs.scripts/generate-embedded-skills.ts— embedsskill/as string constants (src/lib/embedded-skills.gen.ts) so compiled binaries carry the skill with zero runtime dependencies. A test fails CI if the generated module drifts fromskill/.mux skills path— writes the embedded skills to$XDG_DATA_HOME/mux/skills/and prints their paths as JSON for agents.mux skills install— copies them into~/.claude/skills/(or--dir <path>), where Claude Code auto-loads them with no per-project setup.mux skills update— refreshes all local copies to match the installed CLI and reports when a newer release is available (skills are release-pinned by design).mux docs find <query>— searches the live docs index (mux.com/llms.txt) CLI-side and prints only matching page URLs, so agents locate pages without reading the 206-entry index into context (~50 tokens instead of ~5,000). No docs stored locally; llms-full.txt excluded from results.mux --helpcarries an "Agent support" note so any agent discovers the skills unprompted..github/workflows/sync-skills.yml— onrepository_dispatchfrom muxinc/skills (plus weekly cron and manual dispatch), re-syncsskill/, regenerates, tests, and opens a PR only when content changed. It copies whatever skills the upstream repo publishes, so adding skills later requires no CLI changes. Source commit recorded inskill/manifest.json.Verification
🤖 Generated with Claude Code
Note
Low Risk
New optional commands and generated embeds; no changes to auth or Mux API behavior. CI guards keep
skill/and the generated module aligned.Overview
Adds agent-facing support to the Mux CLI: routing skills ship inside the binary, and agents can discover live docs without pulling the full
llms.txtindex into context.Embedded skills — Vendors the
mux-docsskill frommuxinc/skillsunderskill/, generatesembedded-skills.gen.tsviapnpm run generate:skills, and exposesmux skills(path,install,update) to materialize skills under XDG data or~/.claude/skills. Root help documents these entry points.Live docs search —
mux docs findfetchesmux.com/llms.txt, searches CLI-side (excludingllms-full.txt), and returns matching page URLs with optional--json/--agent.Automation —
sync-skills.ymlsyncs the allowlistedmux-docsskill on dispatch/cron, regenerates the embed, runsembedded-skills.test.ts, and opens a PR when content changes.Tests cover docs index parsing/search and embedded-skill sync with
skill/on disk.Reviewed by Cursor Bugbot for commit 355edb4. Bugbot is set up for automated code reviews on this repo. Configure here.
Note: the skills source is muxinc/skills#1, which adds the mux-docs skill and plugin marketplace to the canonical skills repo. The sync workflow uses an allowlist (
mux-docs) since that repo also publishes skills with vendored reference docs that the CLI intentionally does not embed.