mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-14 01:50:39 +09:00
feat: add paperclip-dev skill with optional bundled skill support (#3854)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Agents working on the Paperclip codebase itself need guidance on dev workflows: server lifecycle, worktrees, builds, database ops, diagnostics > - There was no bundled skill covering these workflows — agents had to figure it out from scratch each time > - Additionally, not every skill should be force-installed on every agent — a dev-focused skill should be opt-in > - This PR adds a `paperclip-dev` skill with `required: false` frontmatter so it ships with Paperclip but isn't auto-installed > - The skill's PR section references canonical files (`.github/PULL_REQUEST_TEMPLATE.md`, `CONTRIBUTING.md`) instead of duplicating their content, with gated instructions that force agents to read those files before creating any PR > - The benefit is that developers (human or agent) can opt in to structured dev guidance without polluting the default agent skill set or creating drift between duplicated docs ## What Changed - Added `skills/paperclip-dev/SKILL.md` covering server management, worktree lifecycle, builds, database ops, diagnostics, agent operations, and common mistakes - The Pull Requests section uses gated, reference-based instructions — agents MUST read `.github/PULL_REQUEST_TEMPLATE.md` and `CONTRIBUTING.md` before running `gh pr create`, with a brief checklist of required section names (no content duplication) - Updated `packages/adapter-utils/src/server-utils.ts` to respect `required: false` frontmatter — optional skills are bundled but not auto-installed on agents - Added test in `server/src/__tests__/paperclip-skill-utils.test.ts` verifying that optional skills are excluded from the default install set ## Verification ```bash # Run tests pnpm test # Manual verification: create a fresh worktree without seeding npx paperclipai worktree:make test-optional-skill --no-seed cd ~/paperclip-test-optional-skill eval "$(npx paperclipai worktree env)" npx paperclipai run # Verify paperclip-dev appears in company skill library but is NOT auto-assigned # Call listPaperclipSkillEntries() — paperclip-dev should show required: false # Call resolvePaperclipDesiredSkillNames() — paperclip-dev should NOT be in the default set # Cleanup npx paperclipai worktree:cleanup test-optional-skill ``` ## Risks - Low risk. The `required` field defaults to `true` when absent, so all existing skills behave identically. Only the new `paperclip-dev` skill sets `required: false`. ## Model Used Claude Opus 4.6 (`claude-opus-4-6`) via Claude Code, with tool use and extended context. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
c036bbfa98
commit
91333ec86f
3 changed files with 275 additions and 7 deletions
|
|
@ -43,6 +43,34 @@ describe("paperclip skill utils", () => {
|
|||
expect(entries[1]?.source).toBe(path.join(root, "skills", "paperclip-create-agent"));
|
||||
});
|
||||
|
||||
it("marks skills with required: false in SKILL.md frontmatter as optional", async () => {
|
||||
const root = await makeTempDir("paperclip-skill-optional-");
|
||||
cleanupDirs.add(root);
|
||||
|
||||
const moduleDir = path.join(root, "a", "b", "c", "d", "e");
|
||||
await fs.mkdir(moduleDir, { recursive: true });
|
||||
|
||||
// Required skill (no frontmatter flag)
|
||||
const requiredDir = path.join(root, "skills", "paperclip");
|
||||
await fs.mkdir(requiredDir, { recursive: true });
|
||||
await fs.writeFile(path.join(requiredDir, "SKILL.md"), "---\nname: paperclip\n---\n\n# Paperclip\n");
|
||||
|
||||
// Optional skill (required: false)
|
||||
const optionalDir = path.join(root, "skills", "paperclip-dev");
|
||||
await fs.mkdir(optionalDir, { recursive: true });
|
||||
await fs.writeFile(path.join(optionalDir, "SKILL.md"), "---\nname: paperclip-dev\nrequired: false\n---\n\n# Dev\n");
|
||||
|
||||
const entries = await listPaperclipSkillEntries(moduleDir);
|
||||
entries.sort((a, b) => a.runtimeName.localeCompare(b.runtimeName));
|
||||
|
||||
expect(entries).toHaveLength(2);
|
||||
expect(entries[0]?.runtimeName).toBe("paperclip");
|
||||
expect(entries[0]?.required).toBe(true);
|
||||
expect(entries[1]?.runtimeName).toBe("paperclip-dev");
|
||||
expect(entries[1]?.required).toBe(false);
|
||||
expect(entries[1]?.requiredReason).toBeNull();
|
||||
});
|
||||
|
||||
it("removes stale maintainer-only symlinks from a shared skills home", async () => {
|
||||
const root = await makeTempDir("paperclip-skill-cleanup-");
|
||||
cleanupDirs.add(root);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue