Skip to main content
← Back to list
01Issue
BugShippedSwamp CLITeam
Assigneesstack72

Relationships

#943 swamp update syncs global skills to default agent directories instead of configured custom Pi skillsDir

Opened by evrardjp · 7/3/2026· Shipped 7/3/2026

Summary

After updating swamp from 20260702.214253.0-sha.8411d6d9 to 20260702.230118.0-sha.3ad6e1e2, swamp update synced bundled global skills into several default agent directories and created ~/.agents/skills, even though this repository is configured to use a custom pi agent with skills stored in ~/.pi/agent/skills.

This caused a skill conflict/noise for a repo whose .swamp.yaml enrolls only pi.

Observed output

16:03:44.024   info    update               "20260702.214253.0-sha.8411d6d9" → "20260702.230118.0-sha.3ad6e1e2"
16:03:44.025   info    update               SHA-256 integrity check passed
16:03:44.025   info    update               The swamp binary has been updated globally.
16:03:44.025   info    update               Run `swamp repo upgrade` in your repositories to update settings and instructions.
⠋ Syncing global skills...16:03:44.035   info    update               Synced global skills to "/var/home/evrardjp/.claude/skills"
16:03:44.041   info    update               Synced global skills to "/var/home/evrardjp/.agents/skills"
16:03:44.048   info    update               Synced global skills to "/var/home/evrardjp/.kiro/skills"

Repository configuration

Current repo: /var/home/evrardjp/git/evrardjp/local-infra

.swamp.yaml:

swampVersion: 20260702.230118.0
initializedAt: '2026-06-16T15:47:57.475Z'
repoId: 7ca027d4-3ead-462e-a076-0aa275fe6c30
tools:
  - pi
gitignoreManaged: true
upgradedAt: '2026-07-03T16:04:07.396Z'

.swamp-custom-tools.yaml:

tools:
  - name: pi
    skillsDir: ~/.pi/agent/skills
    instructionsFile: AGENTS.md
    instructionsMode: shared
    skillReferenceStyle: path
    gitignoreEntries: |-
      # Pi skills (managed by swamp)
      ~/.pi/agent/skills/

Actual filesystem state after update

The update created/synced global skills into these directories:

~/.agents/skills/swamp/SKILL.md
~/.agents/skills/swamp-getting-started/SKILL.md
~/.claude/skills/swamp/SKILL.md
~/.claude/skills/swamp-getting-started/SKILL.md
~/.kiro/skills/swamp/SKILL.md
~/.kiro/skills/swamp-getting-started/SKILL.md

~/.pi/agent/skills exists and is the configured custom destination for this repo, but swamp update did not report syncing there.

Why this appears to happen

From the behavior, swamp update seems to run a global skill synchronization step that targets built-in/default agent locations (~/.claude/skills, ~/.agents/skills, ~/.kiro/skills) independently of repository enrollment and independently of .swamp-custom-tools.yaml custom tool definitions. In other words, the update-time global skill sync appears to use a hard-coded/default tool list rather than the configured/enrolled tool list or custom skillsDir.

This is especially surprising because swamp repo upgrade --help documents the enrolled tool list behavior (--tool replaces enrolled tools, omit preserves existing list), and this repo's enrolled list is only pi.

Expected behavior

One of:

  1. swamp update should only sync global skills to configured/enrolled agent skill directories, including custom tools like pi with skillsDir: ~/.pi/agent/skills; or
  2. it should not create/sync any agent skill directory unless the user/repo has explicitly enrolled that agent; or
  3. if update intentionally manages a separate global default agent set, that should be configurable and clearly documented, and it should include a way to opt out of default locations.

At minimum, swamp update should not silently create ~/.agents/skills on a machine/repo configured only for a custom pi agent.

Environment

swamp 20260702.230118.0-sha.3ad6e1e2
binary: /var/home/evrardjp/.local/bin/swamp
repo: /var/home/evrardjp/git/evrardjp/local-infra
enrolled repo tools: pi
custom pi skillsDir: ~/.pi/agent/skills
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 14 MOREREVIEW+ 4 MOREPR_MERGED+ 1 MORECONTRIBUTOR_NOTIFIED

Shipped

7/3/2026, 8:33:46 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack727/3/2026, 4:09:23 PM
Editable. Press Enter to edit.

evrardjp commented 7/3/2026, 4:08:42 PM

Additional source-level confirmation from the compiled binary/source-map strings:

  • runs whenever is true.

  • does:

  • defines for the built-ins only:

So the root cause is not just inferred behavior: update-time sync explicitly enumerates all built-in keys, deduplicates them, and writes to those global paths. It does not read the repo's enrolled list and cannot include custom tool definitions such as / .

evrardjp commented 7/3/2026, 4:08:55 PM

Correction/clarification to previous ripple: source-level confirmation from the compiled binary/source-map strings:

  • update.ts runs syncGlobalSkills(ctx.logger) whenever renderer.updated is true.
  • syncGlobalSkills does:
const allTools = Object.keys(GLOBAL_SKILL_DIRS);
globalDirs = resolveUniqueGlobalSkillsDirs(allTools);
// then copySkillsTo(dir) for each resolved dir
  • skill_dirs.ts defines GLOBAL_SKILL_DIRS for the built-ins only:
{
  claude: ".claude/skills",
  cursor: ".agents/skills",
  opencode: ".agents/skills",
  codex: ".agents/skills",
  copilot: ".agents/skills",
  kiro: ".kiro/skills"
}

So the root cause is not just inferred behavior: update-time sync explicitly enumerates all built-in GLOBAL_SKILL_DIRS keys, deduplicates them, and writes to those global paths. It does not read the repo's enrolled tools: list and cannot include custom tool definitions such as pi / ~/.pi/agent/skills.

stack72 commented 7/3/2026, 8:33:53 PM

Thanks @evrardjp for reporting this! The fix has been merged and a release is on its way. We appreciate your contribution to swamp.

Sign in to post a ripple.