feat(skills): Skill Packs — reusable skill bundles + sandbox context files - #147
Merged
Conversation
…files A Skill Pack bundles a set of skills with optional AGENTS.md / CLAUDE.md context. Attach multiple packs to a harness (instead of, or alongside, loose skills). For agentic (ACP) harnesses the gateway writes the context to the sandbox root and materializes each skill's SKILL.md so Claude Code loads it. New 'Skill Packs' manage screen (sidebar icon + /skill-packs route) to create/edit/delete packs; a pack picker in the harness create + edit flows. Convex: - skillPacks table + CRUD (skillPacks.ts); harnesses carry skillPackIds (create/update/duplicate/resolveForCollab); remove() detaches harnesses. - internalQuery resolveForGateway: concatenates AGENTS.md/CLAUDE.md per pack, unions skills (de-duped), joins cached SKILL.md — owner-scoped. FastAPI: - HarnessConfig.skill_pack_ids; resolve_skill_pack_context (Convex client). - session_manager._attach_skill_pack_context writes AGENTS.md (all agentic), CLAUDE.md + optional @AGENTS.md import (claude-code), and ~/.claude/skills/<slug>/SKILL.md (claude-code), on create AND revive. Path-slug sanitized; best-effort (never blocks a session). - Re-provision PRUNES previously Harness-managed context (sentinel-marked) before writing, so removed skills / detached packs clear from persistent sandboxes without touching user-authored files. - Default OpenRouter loop (chat.py) unions pack skills into its skill manifest. Frontend: - manage-tabs Skill Packs nav; /skill-packs route (list + editor reusing the skill picker + AGENTS.md/CLAUDE.md + @import checkbox); SkillPackPicker; harness-stream sends skill_pack_ids; onboarding + harness-edit attach packs. Adversarially verified (multi-agent): cross-user access + path traversal are defended; fixed the stale-context lifecycle bug found in review. Tests: Convex 203, FastAPI 341 (incl. new skillPacks/context-injection/prune tests), frontend 235; tsc/biome/ruff clean on changed files.
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A Skill Pack is a creatable entity that bundles a set of skills with optional AGENTS.md and CLAUDE.md context. You attach packs to a harness (multiple allowed) instead of picking loose skills.
/skill-packsroute (create/edit/delete, with the existing skill catalog picker + AGENTS.md/CLAUDE.md editors + an@AGENTS.mdimport checkbox).AGENTS.md→<sandbox>/AGENTS.md(Claude Code, Codex, Cursor)CLAUDE.md→<sandbox>/CLAUDE.md(Claude Code), optionally led by@AGENTS.md~/.claude/skills/<slug>/SKILL.md(Claude Code) — this is the first time skills actually reach ACP agentsDesign decisions (confirmed)
How it flows
harness.skillPackIds→buildHarnessStreamConfig(owner) /resolveForCollab(collaborator) →HarnessConfig.skill_pack_ids→ gateway resolves viaskillPacks:resolveForGateway(owner-scoped) → context written to the sandbox. Best-effort throughout — a Convex hiccup never blocks a session.Stale-context handling
Context files are marked Harness-managed (a sentinel first line on AGENTS.md/CLAUDE.md; a
.harness-managedfile in each skills dir). On a reused sandbox (attach/revive) the gateway prunes only Harness-managed context before writing the current set — so removing a skill or detaching a pack actually clears it, while user-authored files are never touched.Verification
3-dimension adversarial multi-agent review:
resolveForGatewayis owner-keyed on every path (owner ACP, collaborator ACP, collaborator default loop); a stored foreign/nonexistent pack id is inert._skill_dir_slugcollapses separators to dashes, rejects./.., bounds length;.mdpaths are fixed constants.Tests: new
skillPacks.test.ts(Convex),test_skill_packs.py(FastAPI: context injection + slug + prune). Full suites: Convex 203, FastAPI 341, frontend 235. tsc / biome / ruff clean on changed files.Notes for review
~/.claude/skills, then remove the skill and confirm it's pruned on the next session.