Skip to content

🤖 feat: make mux agent routable from Auto in project workspaces#2768

Open
ethanndickson wants to merge 12 commits intomainfrom
chat-mux-j85r
Open

🤖 feat: make mux agent routable from Auto in project workspaces#2768
ethanndickson wants to merge 12 commits intomainfrom
chat-mux-j85r

Conversation

@ethanndickson
Copy link
Member

@ethanndickson ethanndickson commented Mar 4, 2026

Summary

Make the mux agent (skills, AGENTS.md, config tools) reachable in any project workspace via Auto routing. In project context, tools operate on project-scoped resources (.mux/skills/, project AGENTS.md); in the system workspace they continue to operate globally. Also eliminates a wasteful throwaway runtime assembly used for sentinel tool-name computation.

Follow-up commits harden the runtime path resolver (dangling symlink rejection, portable containment), remove workspace-gated tool restrictions that blocked the mux agent from using skills_catalog tools outside the system workspace, validate SKILL.md symlink targets stay within containment roots during skill listing, and enforce project-root containment in the shared skill resolver for read/read_file flows.

Background

The mux agent was previously confined to the singleton "Chat with Mux" system workspace. All its tools derived scope from workspaceSessionDir (navigating up ~/.mux/sessions/<id> to find ~/.mux/), hardcoding them to global scope. This meant project workspaces couldn't manage their own skills or AGENTS.md via mux.

Separately, resolveAgentForStream created a throwaway runtime and instantiated every tool object just to compute tool names for the agent-transition sentinel message. This was slow and caused analytics_query to be missing from the handoff message (the stub config lacked analyticsService).

Implementation

1. MuxToolScope type + wiring (toolScope.ts, aiService.ts, tools.ts)

  • New discriminated union MuxToolScope:
    • { type: "global", muxHome } — system workspace
    • { type: "project", muxHome, projectRoot } — project workspace (projectRoot = worktree path)
  • Added muxScope?: MuxToolScope to ToolConfiguration
  • Resolved once at tool-construction time in aiService.ts based on workspaceId === MUX_HELP_CHAT_WORKSPACE_ID
  • Shifted MCP/secrets gates from workspaceId !== MUX_HELP_CHAT_WORKSPACE_ID to effectiveAgentId !== MUX_HELP_CHAT_AGENT_ID so mux running in project scope gets the right capability set

2. Scope-aware skill tools (agent_skill_{write,delete,list}.ts, skillFileUtils.ts)

  • All three skill mutation tools derive their skills root from config.muxScope:
    • Project scope → <projectRoot>/.mux/skills/
    • Global scope → <muxHome>/skills/
  • validateLocalSkillDirectory generalized: takes a containmentRoot parameter instead of hardcoded muxHomeReal
  • agent_skill_list scans both project and global roots when in project scope, tagging each entry with its scope. Global-only listing retained for system workspace.
  • Removed getMuxHomeFromWorkspaceSessionDir from muxHome.ts (file deleted) — all callers use muxScope directly

3. Renamed + scope-aware AGENTS.md tools (mux_agents_{read,write}.ts)

  • mux_global_agents_read/writemux_agents_read/write via git mv
  • Tools read config.muxScope to determine target:
    • Project scope → <projectRoot>/AGENTS.md
    • Global scope → <muxHome>/AGENTS.md
  • Replaced symlink rejection (lstat + reject-if-symlink) with realpath() + containment validation (isPathInsideRoot). In-root symlinks (e.g., AGENTS.md → docs/AGENTS.md) now work; escaping symlinks are rejected.

4. Simplified config tools (mux_config_{read,write}.ts)

  • Use config.muxScope!.muxHome directly instead of getMuxHomeFromWorkspaceSessionDir
  • Removed the duplicate getMuxHomeFromWorkspaceSessionDir from configToolUtils.ts

5. Agent prompt updates (mux.md, auto.md, exec.md, plan.md)

  • mux.md: Rewritten for dual-scope behavior with clear context-aware documentation and safety rules
  • auto.md: Added mux routing criteria for config/skills/AGENTS.md management requests
  • exec.md / plan.md: Updated tool policy regex mux_global_agents_.*mux_agents_.*
  • Regenerated builtInAgentContent.generated.ts

6. Sentinel tool-name computation without throwaway runtime (agentResolution.ts, toolPolicy.ts, toolDefinitions.ts)

  • New applyToolPolicyToNames(names, policy) — name-only policy filtering that shares matching logic with applyToolPolicy (single source of truth for regex/order semantics)
  • applyToolPolicy refactored to delegate to applyToolPolicyToNames
  • getAvailableTools() gained enableAnalyticsQuery?: boolean flag (defaults true)
  • resolveAgentForStream replaced throwaway block with getAvailableTools(model, flags) → applyToolPolicyToNames(names, policy) — no tool objects instantiated
  • Removed initStateManager from ResolveAgentOptions, added hasAnalyticsService: boolean

7. Runtime AGENTS.md path resolution with security hardening (mux_agents_path.ts, mux_agents_storage_context.ts)

  • MuxAgentsStorageContext discriminated union: global-local | project-local | project-runtime with resolver
  • resolveAgentsPathOnRuntime() — typed state machine for SSH/remote workspaces:
    • probeRuntimePathState() classifies paths as dangling | existing | missing via explicit POSIX shell probe ([ -L ... ] && [ ! -e ... ])
    • Dangling symlinks → hard reject (not silently treated as missing)
    • Existing paths → portable containment via inspectContainmentOnRuntime() (reuses runtimeSkillPathUtils.ts POSIX-only primitives: cd && pwd -P, bare readlink)
    • Missing paths → allowed (write creates the file)
  • No dependency on GNU-specific readlink -f — works on BSD/macOS SSH targets

8. Removed skills_catalog workspace gates

  • enableSkillsCatalogTools flag removed from toolAvailability.tsskills_catalog_search/skills_catalog_read now unconditionally in baseTools
  • Runtime workspace-ID checks removed from both tool implementations — tools no longer hard-reject non-mux-chat workspaces
  • Updated toolDefinitions.ts, tools.ts, systemMessage.ts to remove stale forwarding/option plumbing

9. SKILL.md symlink containment in agent_skill_list

  • readSkillDescriptor() now validates SKILL.md canonical path stays within the containment root via ensurePathContained() before any stat/readFile
  • Added pre-read size guard: files exceeding MAX_FILE_SIZE (1MB) are skipped without loading into memory
  • Prevents repo-controlled SKILL.md symlinks from escaping project boundaries during skill discovery

10. Project-root containment in agent_skill_read / agent_skill_read_file

  • Extended readAgentSkill(...) options with projectContainmentRoot?: string | null
  • In the candidate scan loop, project-scoped skill directories are canonicalized via ensurePathContained(projectContainmentRoot, skillDir) before runtime.stat()/readAgentSkillFromDir()
  • Containment failure → log warning + continue (global/built-in fallback preserved)
  • Both agent_skill_read.ts and agent_skill_read_file.ts now pass config.muxScope.projectRoot as containment root in project scope
  • New regression tests: project skill directory symlink escaping projectRoot is rejected in both read tools

11. Test coverage

  • testHelpers.ts: createTestToolConfig accepts optional muxScope (defaults to global scope pointing at tempDir)
  • Updated all existing tool tests to supply muxScope in configs
  • New dual-scope test cases for skill write/delete/list, AGENTS.md read/write, and config tools
  • New applyToolPolicyToNames parity tests
  • mux_global_agents.test.tsmux_agents.test.ts with expanded scope coverage
  • Dangling symlink rejection test (creates dangling symlink, asserts read/write both fail)
  • BSD portability regression test (NoReadlinkFRemoteRuntime subclass that fails on readlink -f commands, verifies split-root operations still succeed)
  • skills_catalog tests updated: "rejects outside Chat with Mux workspace" → "allows from non-mux-chat workspace"
  • agent_skill_list tests: escaping SKILL.md symlink skipped, oversized SKILL.md skipped
  • agent_skill_read / agent_skill_read_file tests: project skill directory symlink escape rejected

Risks

  • MCP/secrets gate shift: Changed from workspace-ID check to agent-ID check. If effectiveAgentId doesn't resolve to MUX_HELP_CHAT_AGENT_ID in the system workspace, MCP/secrets would incorrectly activate. Low risk — the resolution path for the system workspace always yields this agent ID.
  • Symlink containment: The new realpath + isPathInsideRoot approach is more permissive than the old blanket symlink rejection. Escaping symlinks are still rejected, but in-root symlinks are now allowed. This is intentional for repos with committed AGENTS.md symlinks.
  • skills_catalog unconditional availability: Removing the workspace gate means all workspaces can search/read the skills catalog. Low risk — these are read-only discovery tools with no mutation capability.

Generated with mux • Model: anthropic:claude-opus-4-6 • Thinking: xhigh • Cost: $76.32

@ethanndickson ethanndickson changed the title 🤖 refactor: make mux agent scope-aware for project workspaces 🤖 feat: make mux agent routable from Auto in project workspaces Mar 4, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c16c9996c8

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f14af86e2

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 62fb263f9e

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 03cf98f807

ℹ️ 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".

@ethanndickson
Copy link
Member Author

Resolved — backward-compat aliases are unnecessary here. Frontend and backend are always in sync (see AGENTS.md IPC/Compatibility section), so breaking tool renames are expected and safe. No persisted policy will reference the old names since this is a net-new feature. @codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 728534d868

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1fbe8126d9

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 165bde9a4f

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 07e4e3379a

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3437e7ebe0

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94b1554284

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f48ea4bee

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. 🚀

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66a7a62441

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee647f0249

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 06ffd7c6e8

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76b9b4c242

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

1 similar comment
@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3b39189d17

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 663000ef59

ℹ️ 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".

@ethanndickson
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2804251002

ℹ️ 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".

Comment on lines +41 to +43
normalizedProbePath === path.resolve(projectRoot) ||
normalizedProbePath === path.resolve(workspacePath)
);

Choose a reason for hiding this comment

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

P1 Badge Use project-runtime roots for Docker split-root workspaces

The split-root classifier currently treats any runtime whose getWorkspacePath() equals workspacePath as local-like, which incorrectly matches Docker (getWorkspacePath() always returns /src). In a Docker project workspace (muxScope.projectRoot is host path, cwd is /src), this returns project-local and later agent_skill_read/agent_skill_read_file call readAgentSkill with host roots while still using the Docker runtime, so runtime stat/read calls target host-only paths that do not exist in-container and skill reads fail.

Useful? React with 👍 / 👎.

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.

1 participant