Repo-native memory and continuous learning for AI coding agents.
Skillver is a single agent skill that makes an agent remember two different kinds of things:
- What each feature of this project actually is right now — status, current behavior, decisions, risks, and which documents are still the source of truth.
- What the agent learned the hard way — non-obvious fixes, project-specific gotchas, and tool quirks, promoted into new reusable skills.
Both live as plain Markdown inside your repository, so the memory survives new sessions, new chats, and switching between agents.
Spec frameworks help an agent plan the next change. Skillver helps an agent remember the project and get better at working on it.
AI coding agents are good at making changes and bad at remembering:
- Feature knowledge is scattered across PRDs, API notes, plans, old chats, and commits.
- Agents redo the same discovery work every session because there is no current feature index.
- Stale plans keep looking authoritative long after reality moved on.
- The same non-obvious bug gets re-debugged from scratch, because nothing captured the root cause.
- Switching tools or starting a new session resets everything.
Skillver fixes this with two durable layers in the repo, and nothing else. No database, no chat-history search, no new development lifecycle.
A global index plus one small living track per feature, all under .agent-memory/:
.agent-memory/
└── features/
├── README.md # global feature index
└── <feature-id>/
├── README.md # current feature memory
├── prd/
├── api/
├── plans/
└── archive/
Each feature track answers: What is true now? Which docs are still the source of truth? Which decisions must future work preserve? What risks and rollout constraints matter? What changed recently?
Tracks link to your existing docs instead of replacing them, so brownfield projects can adopt this in minutes. Memory stays out of docs/, which remains yours to write for human readers.
.agent-memory/ is hidden but it is not scratch space. Commit it: a gitignored memory is no memory at all.
When a task produces knowledge that is reusable, non-obvious, and verified, the agent writes a new skill:
.agents/skills/<skill-name>/SKILL.md
Extraction is deliberately selective. Routine work produces no skill. A misleading error message whose real cause took thirty minutes to find produces one, with the exact trigger conditions, the fix, the dead ends, and how to verify it.
flowchart LR
sessionStart[Session start] --> readIndex["Read feature index"]
readIndex --> readTrack["Read relevant feature track"]
readTrack --> work[Do the work]
work --> updateTrack["Update feature track"]
work --> evaluate{"Reusable, non-obvious,<br/>verified knowledge?"}
evaluate -->|yes| extract["Extract or update a skill"]
evaluate -->|no| skip["Skip extraction"]
updateTrack --> done[Session end]
extract --> done
skip --> done
Feature memory is project state: it changes as the product changes. Extracted skills are transferable technique: they stay useful even when the feature is gone.
npx skills add jbsanf/skillverThe skills CLI discovers skills/skillver/ and installs the whole directory (SKILL.md, references/, and templates/) into the agents you choose. Without -a, it prompts for which agents to install into. A project install typically lands in .agents/skills/skillver/, which OpenCode, Cursor, Codex, and several other agents already read.
# every project (user-level)
npx skills add jbsanf/skillver -g
# a specific agent (claude-code, cursor, opencode, codex, ...)
npx skills add jbsanf/skillver -a claude-code
# copy files instead of symlinking
npx skills add jbsanf/skillver --copyIf you prefer not to use Node, copy skills/skillver/ yourself. The directory is self-contained: the reference files and the templates travel with it, so copy it whole rather than SKILL.md alone.
OpenCode, per project or globally:
# per project
mkdir -p .opencode/skills
cp -r skills/skillver .opencode/skills/
# or globally, for every project
mkdir -p ~/.config/opencode/skills
cp -r skills/skillver ~/.config/opencode/skills/Or clone this repository somewhere and copy from there:
git clone https://github.com/jbsanf/skillver /tmp/skillver
cp -r /tmp/skillver/skills/skillver ~/.config/opencode/skills/OpenCode discovers the skill from the SKILL.md frontmatter and loads it on demand through its native skill tool. Nothing else is required.
To confirm it loaded, ask the agent to list its available skills, or call it explicitly:
skill({ name: "skillver" })
The same copy works in the other agents' skill directories:
| Agent | Path |
|---|---|
| OpenCode | .opencode/skills/skillver/ or ~/.config/opencode/skills/skillver/ |
| Claude Code | .claude/skills/skillver/ or ~/.claude/skills/skillver/ |
| Codex | .codex/skills/skillver/ or ~/.codex/skills/skillver/ |
| Cursor | .cursor/skills/skillver/ or ~/.cursor/skills/skillver/ |
| Any agent reading the neutral path | .agents/skills/skillver/ or ~/.agents/skills/skillver/ |
OpenCode and Cursor both also read .claude/skills/ and .agents/skills/, so a single install in the neutral path can serve several agents at once. Install into one location per agent: the same skill name found twice is a collision.
Skillver is meant to run without being asked. Once installed, the agent should read the feature index before starting work, update the relevant track before finishing, and extract a skill when a session produced something worth keeping.
You can also drive it explicitly:
| Say this | The agent does this |
|---|---|
| "Set up Skillver in this repo" | Creates .agent-memory/features/README.md and the first tracks |
| "What do we know about the billing feature?" | Reads the index and the billing track before answering |
| "Track this as a feature" | Creates a feature track and indexes it |
| "What did we learn?" | Reviews the session and proposes skills to extract |
| "Save this as a skill" | Writes a new skill under .agents/skills/ |
| "Check the feature docs" | Validates index drift, required sections, and broken local links |
The global index at .agent-memory/features/README.md:
| Feature | Status | Track | Source Of Truth | Updated | Notes |
|---|---|---|---|---|---|
| Skillver Skill | active | [README](skillver-skill/README.md) | [SKILL.md](../../skills/skillver/SKILL.md), [README](../../README.md) | 2026-08-15 | Canonical skill package plus references and templates; install via `npx skills add jbsanf/skillver` |
| Agent Compatibility | active | [README](agent-compatibility/README.md) | [README install section](../../README.md#install) | 2026-08-15 | Recommended install is `npx skills add jbsanf/skillver`; OpenCode, Claude Code, Codex, and Cursor load the same copy unchanged |A feature track keeps the current truth next to the files that prove it:
## Current Status
Billing runs on Stripe Checkout for new customers; legacy invoicing is read-only.
## Source Of Truth
- Product behavior: [prd/billing.md](prd/billing.md)
- Webhook contract: [api/webhooks.md](api/webhooks.md)
## Decisions
- Webhooks are the only trusted source for subscription state.
- Never trust the client-side success redirect to grant entitlements.An extracted skill records the trigger and the real cause:
---
name: stripe-webhook-signature-failures
description: |
Fix "No signatures found matching the expected signature" from Stripe webhooks.
Use when: (1) webhook verification fails only in staging, (2) the payload works
in the Stripe CLI but not in the deployed app, (3) a body parser runs before
verification. Covers raw body handling in Express and Next.js route handlers.
---This repository uses Skillver on itself. See .agent-memory/features/README.md.
skills/skillver/ # discovered by `npx skills add jbsanf/skillver`
├── SKILL.md # the skill an agent loads
├── references/
│ ├── feature-memory.md # feature index and track format, validation rules
│ └── skill-extraction.md # extraction criteria, quality gates, versioning
└── templates/
├── feature-index.md # copy for a new global index
├── feature-track.md # copy for a new feature track
└── extracted-skill.md # copy for a newly extracted skill
.agent-memory/features/ # Skillver applied to this repo
.github/workflows/links.yml # CI: broken local links and anchors
SKILL.md stays short on purpose. The agent loads a reference file only when it is about to do that specific job.
- Memory, not ceremony. Small files, no mandated process, no gates on every change.
- Current truth over stale specs. A track records what is true now and links to the rest.
- Link first, migrate later. Point at the docs you already have.
- Selective learning. Fewer, high-signal skills beat broad coverage.
- Agent-neutral by default. Plain Markdown in plain paths; the repo is the memory.
Skillver combines the goals of two excellent projects, and would not exist without them:
- feature-track by @JunsW — repo-native shared feature memory for AI coding agents. The feature index and track structure follow its spec so tracks stay compatible.
- Skiller by @markdav-is — autonomous skill extraction and continuous learning. The extraction criteria, quality gates, and skill lifecycle come from its approach.
napkin by @blader was also part of the original inspiration for keeping agent knowledge in a repo-local Markdown file. Skillver deliberately leaves the per-session runbook out of scope; use napkin alongside Skillver if you want it.
Skillver is an independent project and is not affiliated with or endorsed by the projects above.
Issues and pull requests are welcome. Keep the format portable, keep SKILL.md short, and keep validation friendly to existing projects.