🤖 fix: include universal skill roots in project-runtime discovery#3170
🤖 fix: include universal skill roots in project-runtime discovery#3170
Conversation
Use the shared default roots helper so project-runtime discovery includes legacy .agents skill roots, and update split-root tests to cover visible and hidden skills from both universal roots.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d7acfa8a72
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Addressed the feedback: expanded the |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2403977775
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fixed: now using |
|
Codex Review: Didn't find any major issues. Swish! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Broadens
project-runtimeskill discovery soagent_skill_listdiscovers skills from all four standard roots —.mux/skills,.agents/skills,~/.mux/skills, and~/.agents/skills— instead of only the two.mux/skillsroots. Hidden (advertise: false) skills from the newly-included legacy roots follow the same filter: omitted by default, included withincludeUnadvertised: true.Background
The
project-runtimebranch inagent_skill_list.tsconstructed a custom root object containing only.mux/skillsand~/.mux/skills, deliberately excluding the legacy/universal.agents/skillsand~/.agents/skillsroots. This meant skills placed under those legacy roots were invisible toagent_skill_listin runtime mode, even withincludeUnadvertised: true. The shared root model (getDefaultAgentSkillsRoots()) already included all four roots, so the runtime branch was an undocumented narrower fork.Implementation
Production code (
agent_skill_list.ts): Replaced the hand-built runtime root object withgetDefaultAgentSkillsRoots(skillCtx.runtime, skillCtx.workspacePath)(~net -6 LoC). This aligns runtime discovery with the shared root contract while keepingdedupeByName: falseand containment unchanged.Tests (
agent_skill_list.test.ts):.agents/skillsand~/.agents/skillsskills are now present with correct scope tags.includeUnadvertised: true).Tool description (
toolDefinitions.ts): Updated to document all four discovery roots.Validation
agent_skill_listtests pass (82 expect() calls)make typecheck✅make lint✅make test— 87 pre-existing failures in unrelated files (HeartbeatSection, GeneralSection, RetryBarrier, BrowserToolbar, etc.), none in changed filesRisks
Low risk. The change unifies an already-divergent code path with the shared root model. All existing containment, deduplication, and scope-tagging behavior is preserved. The only behavioral change is that skills under
.agents/skillsand~/.agents/skillsare now visible in runtime mode.📋 Implementation Plan
Plan: Make
agent_skill_list({ includeUnadvertised: true })discover legacy project and global universal skillsObjective
Broaden
project-runtimediscovery so hidden legacy skills from both:.agents/skills~/.agents/skillsare discovered and then filtered consistently alongside
.mux/skillsand~/.mux/skills, while keeping the tool description and tests aligned with that broader contract.Verified current state
src/node/services/tools/agent_skill_list.ts:166-183has a specialproject-runtimebranch that constructs a custom root set containing only:projectRoot = .mux/skillsglobalRoot = ~/.mux/skillsprojectUniversalRoot = .agents/skillsoruniversalRoot = ~/.agents/skills, even thoughsrc/node/services/agentSkills/agentSkillsService.ts:39-52defines both as standard discovery roots.src/node/services/tools/agent_skill_list.test.ts:664-717currently codifies exclusion of~/.agents/skillsinproject-runtimeby expecting the legacy tilde global skill to be missing.src/node/services/tools/agent_skill_list.test.ts:779-815currently codifies exclusion of.agents/skillsinproject-runtimeby expecting the legacy project-universal skill to be missing.src/node/services/tools/agent_skill_list.ts:182advertise: falseskills are filtered out..mux/skills/deep-review/SKILL.md, and local invocation returns it whenincludeUnadvertised: true, which confirms the issue is about discovery scope, not theadvertisefilter.Why the current behavior is surprising
The tool description in
src/common/utils/tools/toolDefinitions.ts:1189-1198says:.mux/skills/and global skills from~/.mux/skills/includeUnadvertised: trueincludes skills withadvertise: falseA caller can reasonably infer that hidden project and global legacy skills should appear whenever they are part of the runtime-visible skill surface. In practice,
project-runtimehas an additional, undocumented root restriction, so.agents/skillsand~/.agents/skillsentries never reach the filter stage.Recommended approach
Approach B — Broader compatibility fix (recommended per requested scope)
Net product-code estimate: ~-2 to +4 LoC
Expected test-only delta: ~35-65 LoC
Replace the hand-built runtime root object with
getDefaultAgentSkillsRoots(skillCtx.runtime, skillCtx.workspacePath)soproject-runtimediscovers the full standard set of roots:.mux/skills.agents/skills~/.mux/skills~/.agents/skillsWhy this is now the right tradeoff
includeUnadvertisedbehavior easier to explain: it affects all discovered roots, including both universal roots.Concrete code change
In
src/node/services/tools/agent_skill_list.ts:169-177, remove the custom runtime-only root object and instead call:Then pass
rootsintodiscoverAgentSkills(...).Required comment update
Update the nearby comment so it no longer claims runtime mode excludes
.agents/skills/~/.agents/skills. The comment should say runtime mode now aligns with the shared discovery root model while paired mutation tools may still target a narrower subset of those roots.Alternative approaches
Approach A — Smaller project-only fix
Net product-code estimate: ~4-8 LoC
Expected test-only delta: ~25-45 LoC
Keep the runtime-specific root object, but add only
projectUniversalRoot = .agents/skillsand continue excluding~/.agents/skills.Pros
Cons
Approach C — Doc-only clarification
Net product-code estimate: ~1-4 LoC
Expected test-only delta: 0-10 LoC
Leave behavior unchanged and only update
src/common/utils/tools/toolDefinitions.tsto clarify that:includeUnadvertisedaffects only discovered skills, andproject-runtimemay exclude legacy read-only roots.Pros
Cons
Implementation plan
Phase 1 — Unify
project-runtimewith the shared root modelFiles:
src/node/services/tools/agent_skill_list.tsSteps:
getDefaultAgentSkillsRoots(skillCtx.runtime, skillCtx.workspacePath).dedupeByName: falseunchanged so same-name skills from different scopes/roots continue surfacing as separate descriptors.discoverAgentSkills(...)plus the shared root helper.Phase gate:
Phase 2 — Recast tests around the broader runtime contract
Files:
src/node/services/tools/agent_skill_list.test.tsSteps:
:664-717so~/.agents/skillsis intentionally included inproject-runtimerather than excluded.:779-815so.agents/skillsis intentionally included inproject-runtimerather than excluded.project-runtimehidden-skill case for.agents/skills:.agents/skills/<name>/SKILL.mdwithadvertise: falseagent_skill_list({})and assert the skill is absentagent_skill_list({ includeUnadvertised: true })and assert the skill is present withadvertise: falseproject-runtimehidden-skill case for~/.agents/skillswith the same default-hidden / include-when-requested assertions.Phase gate:
Phase 3 — Update the tool description to match the broader discovery surface
Files:
src/common/utils/tools/toolDefinitions.tsSteps:
agent_skill_listdescription so project workspaces mention both modern and legacy roots:.mux/skills/,.agents/skills/~/.mux/skills/,~/.agents/skills/includeUnadvertisedwording explicit that it applies to discovered skills withadvertise: false.Phase gate:
Acceptance criteria
For the recommended Approach B
project-runtime, a visible skill located at.agents/skills/<name>/SKILL.mdis listed withscope: "project".project-runtime, a visible skill located at~/.agents/skills/<name>/SKILL.mdis listed withscope: "global"..agents/skillsand~/.agents/skillsare omitted by default.includeUnadvertised: trueis passed..mux/skillsand~/.mux/skillsbehavior remains unchanged.If Approach A is chosen instead
.agents/skillsis newly included and~/.agents/skillsremains intentionally excluded.If Approach C is chosen instead
includeUnadvertisedbroadens which roots are scanned.Validation plan
Fast feedback loop
bun test src/node/services/tools/agent_skill_list.test.tsRequired local validation before calling the work complete
make static-checkmake testIf runtime-root behavior or shared discovery code is refactored more broadly than planned
make typecheckmake linttoolDefinitions.tschanges, keepmake static-checkin the required set.Dogfooding and reviewer-verifiable evidence
Setup
dev-desktop-sandboxskill or an equivalent isolatedmake devsetup).project-runtime..mux/skills.agents/skills(advertise: false)~/.agents/skills(advertise: false)~/.agents/skillsto prove the broader root is actually scannedManual dogfood flow
agent_skill_list({})and confirm both hidden legacy skills are absent.agent_skill_list({ includeUnadvertised: true })and confirm the hidden.agents/skillsproject skill is present.~/.agents/skillsglobal skill is also present.Evidence to capture
includeUnadvertised, showing both hidden universal-root skills absent.includeUnadvertised: true, showing the hidden.agents/skillsproject skill present.includeUnadvertised: true, highlighting the hidden~/.agents/skillsglobal skill present.Risks and watchpoints
~/.agents/skillsis intentional in this plan; verify that remote/runtime sessions still present a sensible skill list and do not regress existing host-global behavior.Recommended execution order
agent_skill_list.tsby switching the runtime branch togetDefaultAgentSkillsRoots(...).toolDefinitions.tsso the public description matches the broader behavior.make static-checkandmake test.project-runtimenow treats both.agents/skillsand~/.agents/skillsas part of its discovery surface.Generated with
mux• Model:anthropic:claude-opus-4-6• Thinking:xhigh• Cost:$6.20