SLOPSHOPPER

bun-only

Rewrites npm, npx, yarn and pnpm commands to bun and bunx before they run, and bunx biome to bun run lint:biome.

guard
★ 21v0.1.0GPL-3.0updated 2026-10-18fcsouza/agent-skills/mods/bun-only
A shopper browsing a rack in a slop shop
README

Agent Skills

Production-grade skills for AI coding agents (OpenClaw, Claude Code, and others).

Built by Fabricio Cavalcante — Software Engineer & AI Specialist.

Available Plugins

Plugins are complete workflow bundles — skills + agents + hooks working together as an integrated system. Install a plugin to get the full experience.

PluginDescriptionPlatform
game-dev26 skills, 7 commands, 3 agents, 5 hooks — complete game development workflow with engineering, design, narrative, and infrastructureGame Dev

Claude Code Mods

Mods are plugins built on function hooks: they run inside Claude Code, guard tool calls and draw above the prompt. See mods/ for install steps.

ModDescription
commit-guardBlocks commits with machine paths or .env files, git add -A, and pushes to main
prod-guardHolds Dokploy MCP writes until you press Proceed
bun-onlyRewrites npm, npx, yarn and pnpm to bun
done-gateShows edited files and the checks still owed
worktreesShows git worktrees, their changes, and the count
usage-ringsContext and plan usage, coloured by level
pr-statusThe current branch's PR: CI checks and review
sql-guardHolds writes to non-local databases until you press Proceed
pino-guardBlocks pino transports that break bundled logging

Available Skills

Skills are individual, cherry-pickable modules. Install only what you need.

Core

SkillDescriptionPlatform
claude-agent-sdkBuild production AI agents with the Claude Agent SDK — query(), hooks, subagents, custom tools, MCP servers, sessions, permissions, hostingClaude Code / API
database-performance-tuningDiagnose and fix slow databases like a DBA — pg_stat_statements, EXPLAIN plans, index design, query rewrites, vacuum and bloat, safe online rollout. Ships a read-only diagnostic scriptPostgreSQL / MySQL
foundry-vtt-module-devBuild, extend, and maintain Foundry VTT v14 modules — TypeDataModel, ApplicationV2 (detached windows), ActorSheetV2, hooks, sockets, dice, canvas/PIXI, Scene Levels, Regions as templates, ActiveEffects V2, v13→v14 migration, boilerplate filesFoundry VTT
foundry-vtt-system-devBuild Foundry VTT v14 game systems — system.json documentTypes, Actor/Item TypeDataModel, dice mechanics, combat/initiative, ActiveEffect V2 subtypes, data migration, character sheets, status effects, macros, enrichersFoundry VTT
openclaw-genieComprehensive OpenClaw gateway skill — installation, configuration, 38+ channels, memory, tools, hooks, deployment, multi-agentOpenClaw
nuvemshop-sdkPrepare, audit, implement, homologate, and publish Nuvemshop/Tiendanube apps — OAuth, API, NubeSDK, Nexo, Nimbus, webhooks, and App Store approvalNuvemshop
react-animationsReact animation patterns and utilitiesReact

Game Dev — Design

SkillDescription
game-design-fundamentalsCore loops, MDA framework, progression curves
game-economy-designVirtual economies, currencies, loot tables
level-designLevels, environments, difficulty curves
procedural-genDungeon gen, noise terrain, wave function collapse
quest-mission-designQuests, objectives, quest trees
skill-progression-treesSkill trees, talent trees, unlock graphs
ui-ux-gameHUD, menus, onboarding, accessibility

Game Dev — Engineering

SkillDescription
betterauth-integrationAuth, OAuth, JWT, RBAC
bullmq-game-queuesJob queues, async events, scheduled tasks
elevenlabs-sound-musicSFX generation, adaptive music, voice acting
game-backend-architectureGame servers, WebSocket, rooms, tick loops
game-state-syncClient-server sync, rollback netcode, delta compression
gameplay-analyticsRetention analytics, funnels, D1/D7/D30
matchmaking-systemMatchmaking, lobbies, ELO, skill-based queues
postgres-game-schemaGame DB schemas, Drizzle ORM, inventory
redis-game-patternsCaching, leaderboards, pub/sub, rate limiting
stripe-game-paymentsIn-app purchases, subscriptions, webhooks

Game Dev — Infrastructure

SkillDescription
ci-cd-gameCI/CD pipelines, GitHub Actions, deployment
claude-code-game-workflowEntry point for AI agents on game projects
cursor-codex-integrationCursor IDE, .cursorrules, Codex setup
monitoring-game-opsMonitoring, logging, telemetry, alerts

Game Dev — Narrative

SkillDescription
character-design-narrativeCharacters, NPCs, dialogue, archetypes
quest-narrative-coherenceNarrative coherence check, lore validation
story-structure-gameBranching narratives, player agency, story arcs
worldbuildingLore, factions, geography, world bibles

Structure

All skills follow a flat layout:

skills/<skill-name>/
├── README.md           # Overview and installation instructions
├── SKILL.md            # Main skill file (YAML frontmatter + body)
├── boilerplate/        # Starter code to copy and customize (optional)
├── templates/          # Document and config templates (optional)
├── references/         # Deep-dive reference files (optional)
└── ARCHITECTURE.md     # System design decisions (optional)
  • SKILL.md is always the entry point — read this first
  • boilerplate/ files are starter code, copy and customize
  • templates/ are document/config templates to fill in
  • ARCHITECTURE.md explains system design decisions

Installation

game-dev plugin (Claude Code)

/plugin marketplace add fcsouza/agent-skills
/plugin install game-dev@fcsouza-agent-skills

See plugins/game-dev/README.md for the full skill index, commands, and agents.

Individual skills (cherry-pick)

# Install a specific skill
npx skills add fcsouza/agent-skills --skill game-design-fundamentals

# Install all game-dev engineering skills at once
npx skills add fcsouza/agent-skills --skill betterauth-integration --skill postgres-game-schema --skill game-backend-architecture

# List all available skills
npx skills add fcsouza/agent-skills --list

Manual

# Plugin (full bundle)
cp -r plugins/game-dev/ .claude/plugins/game-dev/

# Individual skill
cp -r skills/<skill-name>/ .claude/skills/<skill-name>/

# For OpenClaw
cp -r skills/<skill-name>/ ~/.openclaw/workspace/skills/<skill-name>/

License

GPL-3.0

Source 2 files
hooks/register.ts 19 lines
1import type { Register } from 'claude-code';
2
3import { rewrite } from './rewrite';
4
5export const register: Register = on => {
6  on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
7    const command = rewrite(e.command);
8    if (command === e.command) {
9      return next(e);
10    }
11
12    const ran = await next({ ...e, command });
13    if (ran.deny !== undefined) {
14      return ran;
15    }
16    return { ...ran, context: [...(ran.context ?? []), `${$.plugin.name} ran \`${command}\` in place of \`${e.command}\`. This machine uses bun only.`] };
17  }).catch(($, e, next) => next(e));
18};
19
hooks/rewrite.ts 104 lines
1// Rewrites package-manager commands to bun. Pure, so the tests call it directly.
2
3// A command starts at a line's start or after &&, ||, ; or |. The tool name must
4// end at a space or the segment's end, so `npm-check-updates` is left alone.
5const SEGMENT = /(^|&&|\|\||;|\|)([ \t]*)((?:npm|npx|yarn|pnpm)(?=[ \t]|$|[&|;])[^&|;\n]*|bunx[ \t]+(?:@biomejs\/)?biome(?=[ \t]|$)[^&|;\n]*)/gm;
6
7// Package-manager commands with no bun spelling here: run as written.
8const BUILTINS = new Set([
9  'publish',
10  'pack',
11  'version',
12  'view',
13  'info',
14  'why',
15  'outdated',
16  'upgrade',
17  'up',
18  'update',
19  'link',
20  'unlink',
21  'audit',
22  'login',
23  'logout',
24  'whoami',
25  'config',
26  'workspace',
27  'workspaces',
28  'cache',
29  'store',
30  'global',
31  'patch',
32  'dedupe',
33  'prune',
34  'licenses',
35  'env',
36  'set',
37  'import',
38]);
39
40export function rewrite(command: string): string {
41  return command.replace(SEGMENT, (_all, sep: string, space: string, body: string) => `${sep}${space}${rewriteOne(body.trimEnd())}${trailing(body)}`);
42}
43
44const trailing = (body: string): string => body.slice(body.trimEnd().length);
45
46function rewriteOne(body: string): string {
47  const [tool = '', ...rest] = body.split(/\s+/);
48  const [sub, ...args] = rest;
49
50  if (tool === 'bunx') {
51    // bunx biome format --write / check --write fix; anything else only checks.
52    return /\b(format|check|lint)\b.*--write\b/.test(body) ? 'bun run format' : 'bun run lint:biome';
53  }
54  if (tool === 'npx' || (tool === 'pnpm' && sub === 'dlx') || (tool === 'yarn' && sub === 'dlx')) {
55    const tail = tool === 'npx' ? rest : args;
56    return ['bunx', ...tail.filter(arg => arg !== '-y' && arg !== '--yes')].join(' ');
57  }
58
59  if (sub === undefined || sub === 'install' || sub === 'i' || sub === 'ci') {
60    const packages = args.filter(arg => !arg.startsWith('-'));
61    if (sub === undefined || packages.length === 0) {
62      return ['bun', 'install', ...flags(args)].join(' ');
63    }
64    return ['bun', 'add', ...flags(args), ...packages].join(' ');
65  }
66  if (sub === 'add') {
67    return ['bun', 'add', ...flags(args), ...args.filter(arg => !arg.startsWith('-'))].join(' ');
68  }
69  if (sub === 'uninstall' || sub === 'remove' || sub === 'rm' || sub === 'un') {
70    return ['bun', 'remove', ...args].join(' ');
71  }
72  if (sub === 'run' || sub === 'run-script') {
73    return ['bun', 'run', ...args].join(' ');
74  }
75  if (sub === 'exec') {
76    return ['bunx', ...args].join(' ');
77  }
78  if (sub === 'test' || sub === 't' || sub === 'start' || sub === 'build') {
79    // `npm test` runs the "test" script; plain `bun test` would run bun's own runner.
80    return ['bun', 'run', sub === 't' ? 'test' : sub, ...args].join(' ');
81  }
82  if (sub === 'create' || sub === 'init') {
83    return args.length > 0 ? ['bun', 'create', ...args].join(' ') : 'bun init';
84  }
85  if ((tool === 'yarn' || tool === 'pnpm') && !sub.startsWith('-') && !BUILTINS.has(sub)) {
86    // `yarn dev` / `pnpm dev` run a script.
87    return ['bun', 'run', sub, ...args].join(' ');
88  }
89  return body;
90}
91
92/** npm/yarn/pnpm flags in bun's spelling; unknown flags are dropped. */
93function flags(args: readonly string[]): string[] {
94  const out: string[] = [];
95  for (const arg of args) {
96    if (arg === '-D' || arg === '--save-dev' || arg === '--dev') out.push('-d');
97    else if (arg === '-g' || arg === '--global') out.push('-g');
98    else if (arg === '-E' || arg === '--save-exact' || arg === '--exact') out.push('--exact');
99    else if (arg === '--frozen-lockfile' || arg === '--immutable') out.push('--frozen-lockfile');
100    else if (arg === '-O' || arg === '--save-optional' || arg === '--optional') out.push('--optional');
101  }
102  return out;
103}
104