Skip to content

feat(skills): a user-level default directory, with precedence and provenance - #79

Merged
kemalelmizan merged 1 commit into
mainfrom
feat/skills-user-level
Oct 17, 2026
Merged

kemalelmizan merged 1 commit into
mainfrom
feat/skills-user-level

Conversation

@kemalelmizan

Copy link
Copy Markdown
Contributor

What

The discovery half of the skills gap (refs #78, slice 1): a user-level default
directory, precedence between levels, and provenance in the prompt. No network
and no trust model — that is the supply-chain half, which stays open.

  • New level: $XDG_CONFIG_HOME/agent/skills (~/.config/agent/skills), picked
    up with no flag.
  • Precedence is the search order — explicit --skills, then the project's
    ./skills, then the user default — and the first definition of a name wins, so
    a project skill overrides the user's copy rather than merging. The skipped copy
    is reported: duplicate skill "x" — already loaded from user (…); keeping that one.
  • Skill.origin records the level, and skillsPrompt groups the listing under
    "Project skills" / "User skills" so provenance is visible rather than implied.
  • skillDirs moves from src/cli.ts to src/skills.ts — where the convention
    lives — and takes cwd/env/home as options, so the rule is unit-testable.

Why

A skill that looks local but is not is a real mismatch: a shared, machine-wide
procedure and a repo's own copy of the same name are different instructions.
docs/archetypes/skills-agent.md recorded "user / project / remote" discovery as
🟡 with no user level; the user level is now done (remote remains a supply-chain
decision, not something to guess at).

Tests

  • src/skills.test.ts — userSkillsDir (XDG override, blank/absent fallback),
    skillDirs order, existence and dedup, origin recorded with the higher level
    winning a collision, and the prompt grouped by level.
  • src/cli.e2e.test.ts — the real CLI, spawned with XDG_CONFIG_HOME at a temp
    dir, loads the user skill with no flag and marks it user-level in the system
    prompt (runCli now accepts env).

Gates

  • pnpm build / pnpm typecheck / pnpm lint green.
  • pnpm test — 341 passed, 5 skipped.
  • pnpm test:coverage — 90.5 / 84.2 / 89.6 / 90.5 (thresholds 87/81/86/87).

…venance

The loader only ever searched `--skills` directories and the project's
`./skills`, so a procedure was per-repo or nowhere: there was no place to keep
one for the machine. This adds the level the archetype catalogue asks for —
`$XDG_CONFIG_HOME/agent/skills` (`~/.config/agent/skills`), found with no flag.

Order *is* the precedence. The directories are searched highest-first —
explicit, then project, then user — and the first definition of a name wins, so
a project skill overrides the user's copy instead of the two merging silently;
the skipped copy is reported along with the level it lost to. `Skill` now
carries the `origin` it was found at, and the prompt groups the listing under
"Project skills" / "User skills", so provenance is visible rather than implied
— the same reason `PlanStep` exists: a run's history should not have to guess
where its instructions came from.

`skillDirs` moves out of `src/cli.ts` into `src/skills.ts`, where the convention
lives, and takes its `cwd`/`env`/`home` as options so the rule is testable
without a process. Nothing is fetched and nothing runs at discovery time; this
is the half of the skills gap that needed no trust model (refs #78).
@kemalelmizan
kemalelmizan merged commit dea74fc into main Oct 17, 2026
2 checks passed
@kemalelmizan
kemalelmizan deleted the feat/skills-user-level branch October 17, 2026 06:30
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