Skip to content

Mount the host's Agent Skills into the container, read-only - #258

Merged
blooop merged 1 commit into
mainfrom
feat/mount-claude-skills
Aug 18, 2026
Merged

blooop merged 1 commit into
mainfrom
feat/mount-claude-skills

Conversation

@blooop

@blooop blooop commented Aug 18, 2026 •

Copy link
Copy Markdown
Owner

What was wrong

The claude-code feature mounts ~/.claude a path at a time, and skills/ was not on the list. A workspace this devcontainer builds therefore comes up with no ~/.claude/skills at all:

$ ls ~/.claude/skills
ls: cannot access '/home/vscode/.claude/skills': No such file or directory

Measured in two live blooop/devlaunch node containers today. Every skill installed on the host is invisible in there.

Where that bites hardest is wf: it execs dl <ws> -- claude … to carry an agent into a node, and the session it lands in cannot see the /wf skill it was launched to run — nor /wf-tdd or /wf-review. On the host the install is healthy (wf skills reports all five links ok), and wayfinder 0.18's launch-time link healing runs host-side, so nothing on that end can fix it. A repo whose devcontainer binds ~/.claude as one directory — blooop/wayfinder's own — never sees this, which is what makes it look repo-specific.

The change

Two read-only mounts, plus the mkdir -p the pre-create hook needs so the bind sources exist:

~/.claude/skills     → /home/vscode/.claude/skills     (readonly)
~/.claude/wf-skills  → /home/vscode/.claude/wf-skills  (readonly)

Two paths and not one, because wf skills install leaves relative links — skills/wf -> ../wf-skills/wf — with the prompt bodies in the sibling directory. Mounting skills/ alone delivers a directory of dangling links, which is no skills rather than stale ones.

Read-only, like commands/ and hooks/: a skill is executable instructions, and this way the allow-list gains no new write path onto the host. The security property tested in test_claude_config_protection.py is untouched.

This reverses something the README argued for

The feature's README named skills/ in What Is Not Mounted and stated the cost plainly — "the skills and plugins installed on your host are not visible in there". So this is a deliberate decision being changed, not an omission being filled. The argument for changing it: the allow-list exists to stop a container writing to host config, and a read-only mount does not write. Skills are the same kind of thing as commands/ and hooks/, which are already mounted on exactly those terms. plugins/ stays out.

One cost comes with it, and it is a warning rather than a failure: wf refreshes its own links on every launch, so a wf run from inside a container prints that it could not refresh them (EROFS) and carries on — its refresh_skills is best-effort by design.

Verification

  • pixi run pytest — 1834 passed, 24 deselected. The README↔manifest agreement tests in test_claude_code_feature_mounts.py cover the new mounts without needing a third copy of the list; the pre-create-hook tests derive file-vs-directory from the README's trailing slash, and both new entries are directories.
  • pixi run prek — clean.
  • Feature version 0.3.0 → 0.4.0.
  • Not exercised here: the e2e read-only proof (pixi run test-e2e), which needs a real Docker daemon and devpod.

Existing containers need a rebuild to pick the mounts up.

🤖 Generated with Claude Code

Summary by Sourcery

Mount the host's Agent Skills and linked skill bodies into the claude-code container as read-only configuration.

New Features:

  • Expose host Agent Skills inside the claude-code devcontainer through read-only mounts for both skill links and their linked bodies.

Bug Fixes:

  • Make host-installed skills, including Wayfinder workflows, available to sessions running inside the container.

Enhancements:

  • Document the expanded Claude configuration mount allow-list and its read-only behavior.

Documentation:

  • Update the claude-code feature documentation to describe the Agent Skills mounts and their link-refresh limitation.

Tests:

  • Extend feature mount and pre-create-hook coverage to include the new skill directories.

Chores:

  • Bump the claude-code feature version from 0.3.0 to 0.4.0.

The claude-code feature's allow-list had no skills in it, so a workspace
came up with no ~/.claude/skills at all and every skill installed on the
host was invisible inside. That lands hardest on a wf launch: wf execs
`dl <ws> -- claude` into a node and the session it lands in cannot see
the /wf skill it was launched to run.

Two paths, because wf skills install leaves *relative* links -
skills/wf -> ../wf-skills/wf - with the prompt bodies in the sibling
directory. Mounting skills/ alone hands the container a directory of
dangling links, which is no skills rather than stale ones.

Read-only, like commands/ and hooks/: a skill is executable
instructions, and the allow-list gains no write path onto the host. The
one cost is a warning, not a failure - wf refreshes its links on every
launch, so a wf run from inside a container says it could not and
carries on.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @blooop, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@sourcery-ai

sourcery-ai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR updates the claude-code devcontainer feature to mount the host’s Agent Skills into the container as read-only, adjusts the init script to pre-create the corresponding host directories, and refreshes documentation and changelog to reflect the new behavior and version bump.

File-Level Changes

Change Details Files
Mount host Agent Skills directories into the devcontainer read-only so skills installed on the host are visible inside containers.
  • Document new read-only mounts for ~/.claude/skills/ and ~/.claude/wf-skills/ in the claude-code feature README, including rationale for two mounts and read-only behavior.
  • Remove skills/ from the "What Is Not Mounted" section and clarify that only plugins remain invisible in containers.
  • Update changelog Unreleased section to describe the fix, behavior, and constraints around wf skills and read-only mounts.
.devcontainer/claude-code/README.md
CHANGELOG.md
Ensure bind mount source directories for skills exist on the host before container creation.
  • Extend init-host script mkdir -p call to also create ~/.claude/skills and ~/.claude/wf-skills alongside existing agents, commands, and hooks.
  • Update explanatory comment to include skills and wf-skills as read-only executable-instructions sources whose absence would break container creation.
.devcontainer/claude-code/init-host.sh
Update devcontainer feature metadata to reflect new mounts and version bump.
  • Increment claude-code feature version from 0.3.0 to 0.4.0 in the feature manifest.
  • Add or adjust mount configuration entries so ~/.claude/skills/ and ~/.claude/wf-skills/ are exposed read-only in the container path mapping.
.devcontainer/claude-code/devcontainer-feature.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@blooop
blooop merged commit cffb9ff into main Aug 18, 2026
10 checks passed
@blooop
blooop deleted the feat/mount-claude-skills branch August 18, 2026 18:21
@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.26%. Comparing base (2bd67e2) to head (f3a7e4f).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #258   +/-   ##
=======================================
  Coverage   93.26%   93.26%           
=======================================
  Files          25       25           
  Lines        3771     3771           
=======================================
  Hits         3517     3517           
  Misses        254      254           

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@blooop blooop mentioned this pull request Aug 18, 2026
blooop added a commit that referenced this pull request Aug 18, 2026
Ships two merges that landed after 0.0.28 was cut.

#258: the claude-code feature mounts ~/.claude/skills and
~/.claude/wf-skills read-only. The allow-list had neither, so a
workspace this repo's devcontainer built had no ~/.claude/skills at all
and every skill installed on the host was invisible inside — a wf launch
into a node landing in a session that could not see the /wf skill it was
launched to run. Repo content rather than package content, so the fix
arrives with a checkout of main and a container recreate, not with this
version bump; the release is here so main and the published package
agree.

#257: prepare_cold names both arms of the base answer and refuses an
unhandled one, closing the silent launch-from-stale-cache a third arm
would have reintroduced behind #245's report.

Goes out through Auto-publish → Conda Publish, the same way 0.0.28 did:
no tag or GitHub release is created by hand.
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