diff --git a/.codecontextignore b/.codecontextignore new file mode 100644 index 0000000..9a99c56 --- /dev/null +++ b/.codecontextignore @@ -0,0 +1,33 @@ +# .codecontextignore — paths codecontext skips during analysis +# Copy to your project root and customize. Same syntax as .gitignore. + +# Dependencies / vendored code +node_modules/ +vendor/ +.venv/ +venv/ +__pycache__/ +target/ + +# Build artifacts +dist/ +build/ +out/ +.next/ +.nuxt/ +.svelte-kit/ + +# IDE / tooling +.opencode/ +.vscode/ +.idea/ + +# Test artifacts / coverage +coverage/ +.nyc_output/ +.pytest_cache/ + +# Lock files (rarely have meaningful symbols) +package-lock.json +yarn.lock +pnpm-lock.yaml diff --git a/.gitignore b/.gitignore index 570f960..623d734 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ CLAUDE.local.md .vite coverage secrets/ -data/ +data/* +!data/AGENTS.md +!data/skills/ diff --git a/BOOCHAT.md b/BOOCHAT.md index 1cc26ce..18e810a 100644 --- a/BOOCHAT.md +++ b/BOOCHAT.md @@ -26,6 +26,11 @@ - Cite file paths + line numbers for any claim about the codebase - When uncertain about scope or intent, surface options via `ask_user_input` rather than guessing - Prefer codecontext (`search_symbols`, `get_symbol_info`, `get_dependencies`) over `grep` for symbol-level questions. Fall back to `grep` / `view_file` when codecontext returns degraded or empty results — that signals an unsupported language or parse failure. +- Verify before reporting work complete: run the relevant test/build/smoke command and confirm output matches the claim. Evidence first, assertion second. + +## Convention: rules vs recipes + +Always-true rules (process discipline, refusals, behavior contracts) live here in `BOOCHAT.md` — and in `BOOCODER.md` / `CLAUDE.md` per their scopes — where they are 100% present in every turn. On-demand recipes (specific procedures, scaffolds, checklists) live in `/data/skills/` and invoke roughly 6% of the time in clean multi-turn flow (Codeminer42 measurement, 2026). Don't file workflow rules as skills — they silently misfire. See Anthropic agent-skills best-practices (platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices) for the canonical conventions. ## Known limitations diff --git a/BOOCODER.md b/BOOCODER.md index 3b904ca..b1556e0 100644 --- a/BOOCODER.md +++ b/BOOCODER.md @@ -20,3 +20,8 @@ - Show a diff preview before any write - Group related edits into a single `/apply` batch - If a tool fails, surface the error verbatim — don't paper over it +- Verify before reporting work complete: run the relevant test/build/smoke and confirm output matches the claim. Evidence first, assertion second. + +## Convention: rules vs recipes + +Always-true rules live here, in `BOOCHAT.md`, and in `CLAUDE.md` (100% present each turn). On-demand recipes live in `/data/skills/` (roughly 6% invoke rate in multi-turn per Codeminer42, 2026). Don't file workflow rules as skills — they misfire. See Anthropic agent-skills best-practices (platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices). diff --git a/CLAUDE.md b/CLAUDE.md index f72221a..a9fa740 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -58,7 +58,7 @@ Key services: - **`chat_status` frame shape** (published via `broker.publishUser`) — `status: 'streaming' | 'tool_running' | 'waiting_for_input' | 'idle' | 'error'` (widened from `working|idle|error` in v1.12.1). Frontend `useChatStatus` derives `idle_warm` (<30s since idle) vs `idle_cold`. `ChatThroughput` renders inline beside `StatusDot` only when streaming or tool_running, fed by 500ms-throttled `'usage'` WS frames (`completion_tokens` + `ctx_used` + `ctx_max`). The `POST /api/chats/:id/discard_stale` endpoint exists to mark a stuck-streaming row as `failed` when the frontend's 60s no-token-activity timer (`ChatPane` content-length watcher) gives up. - **Boot-time stale-streaming sweep** in `apps/server/src/index.ts` after `applySchema()`: any `messages.status='streaming'` older than 5 minutes flips to `'failed'`. Logs only on non-zero count. Recovers from container restart while inference was mid-stream (v1.12.1). - **Periodic 60s sweeper** in `apps/server/src/index.ts` (v1.13.3 + v1.13.5). Same `setInterval` runs `sweepStaleStreaming` (marks `messages.status='streaming'` older than 5 min as `failed`, publishes `chat_status='idle'` so the UI dot drops) and `cleanupTruncations` (TTL + orphan reap of tmpfs truncation files). `app.addHook('onClose')` clears the timer. No-op when nothing to reap. -- **`services/broker.ts`** — In-memory pub/sub with two channel types: per-session (message streaming) and per-user (sidebar updates). No persistence; clients reconnect on restart. +- **`services/broker.ts`** — In-memory pub/sub with two channel types: per-session (message streaming) and per-user (sidebar updates). No persistence; clients reconnect on restart. v1.13.11: every WS publish goes through `broker.publishFrame(sessionId, frame)` or `broker.publishUserFrame(user, frame)` — both Zod-validate against `WsFrameSchema` (`types/ws-frames.ts`) and fail-closed (log + drop). `ctx.publish` / `ctx.publishUser` in inference + auto_name route through the index.ts adapter that calls publishFrame internally. The schema is duplicated byte-identical at `apps/web/src/api/ws-frames.ts`; a `ws-frames.test.ts` case enforces parity. Don't add new raw `broker.publish()` / `publishUser()` calls. - **`services/tools.ts`** — Tool registry (`ALL_TOOLS`, `READ_ONLY_TOOL_NAMES`, `TOOLS_BY_NAME`). Filesystem tools (view_file/list_dir/grep/find_files) go through three guard layers: `path_guard.ts` (workspace scope), `secret_guard.ts` (filename deny list), `url_guard.ts` (SSRF/private-IP block for web_fetch). v1.11.8+ web tools (`web_search`, `web_fetch`) are opt-in per chat via `session.web_search_enabled` (resolved with `project.default_web_search_enabled` fallback) and filtered out of the LLM's tool schema when false. v1.13.5 truncation: when a tool slice cuts content, `services/truncate.ts` stashes the full text on tmpfs at `BOOCODE_TRUNCATION_DIR` (default `/tmp/boocode-truncations`, 0o700) keyed by an opaque `tr_<12 base32 chars>` id, and the `view_truncated_output(id)` tool retrieves it. 5MB cap (matches `view_file`'s `MAX_FILE_BYTES`), 7-day TTL, reaped by the periodic sweeper. Tmpfs path means container restart loses retrieval — acceptable, the model usually has moved on. - **`services/compaction.ts`** + **`services/model-context.ts`** — v1.11.0 anchored rolling summary (single `summary=true` assistant row per chat, supersedes itself on each compaction). Triggered when `chats.needs_compaction` is set after an inference turn exceeds `usable(ctx_max) = floor(0.85 × ctx_max)` (v1.13.9 opencode-pattern early trigger; was `ctx_max - 20k` pre-v1.13.9, which gave only 7.6% headroom at 262k and 0 budget for ≤20k contexts). **`ctx_max` comes from `model-context.getModelContext()` which fetches `${LLAMA_SWAP_URL}/upstream//props`** — NOT from `parsed.timings.n_ctx` (the stream completion's `timings` doesn't carry n_ctx; that read was dead code until v1.11.3 ripped it out). First inferences after a boocode boot may have `ctx_max=NULL` if llama-swap hasn't loaded the model yet; negative cache TTL is 60s, recovers on next turn. v1.13.6: `buildHeadPayload` embeds `reasoning_parts` as a `...` prose prefix on the assistant `content` (OpenAI wire shape has no structured reasoning field; the summarizer reads text). Standalone tag when content is empty (tool-call-only turn). `buildHeadPayload` + `OpenAiMessage` exported for test access — keep them exported. - **`services/system-prompt.ts`** — `buildSystemPrompt` is the string-returning shim; `buildSystemPromptWithFingerprint` is the canonical impl returning `{prompt, fingerprint, drift}`. v1.13.8 instrumentation: SHA-256 of the assembled prefix is logged per `buildMessagesPayload` call (msg `prefix-fingerprint`, level=info); a `Map` observer fires `prefix-drift` (level=warn) on hash change with a field-level `changed_inputs` diff. Smoke proved the prefix is byte-stable across turns in steady-state — the originally-planned `system_prompt_cache` DB table was dropped as redundant against the v1.12.0 input-layer mtime caches (BOOCHAT.md here + AGENTS.md global+per-project in `agents.ts:safeStat`). @@ -105,7 +105,7 @@ Sessions hold 1–5 panes (chat / empty / placeholder terminal+agent). v1.12.1 m ## Database -PostgreSQL 16. Tables: `projects`, `sessions`, `chats`, `messages`, `settings`. (`session_panes` was dropped in v1.12.1; workspace pane state lives in `sessions.workspace_panes jsonb`.) Schema applied idempotently on startup via `applySchema()`. Use `clock_timestamp()` (not `NOW()`) inside transactions. CHECK constraints in place: `projects_status_chk` ('open'|'archived'), `sessions_status_chk` (same), `chats_status_chk` (same), `messages_role_chk`, `messages_status_chk` — keep in sync with the `*_STATUSES` const arrays in `apps/server/src/types/api.ts`. The older anonymous `messages_status_check` (without 'cancelled') and `messages_role_check` (without 'system') were dropped in v1.12.1; only the `_chk` variants remain. +PostgreSQL 16. Tables: `projects`, `sessions`, `chats`, `messages`, `settings`, `message_parts` (v1.13.0). Views: `messages_with_parts` (v1.13.1-B parts-merge read path), `tool_cost_stats` (v1.13.10 per-tool 100-call rolling window). (`session_panes` was dropped in v1.12.1; workspace pane state lives in `sessions.workspace_panes jsonb`.) Schema applied idempotently on startup via `applySchema()`. Use `clock_timestamp()` (not `NOW()`) inside transactions. CHECK constraints in place: `projects_status_chk` ('open'|'archived'), `sessions_status_chk` (same), `chats_status_chk` (same), `messages_role_chk`, `messages_status_chk` — keep in sync with the `*_STATUSES` const arrays in `apps/server/src/types/api.ts`. The older anonymous `messages_status_check` (without 'cancelled') and `messages_role_check` (without 'system') were dropped in v1.12.1; only the `_chk` variants remain. Schema CHECK migration order when renaming allowed values: (1) `ALTER TABLE ... DROP CONSTRAINT IF EXISTS ` (inline `CREATE TABLE` checks get `__check`), (2) `UPDATE` rows to new values, (3) wrap new constraint ADD in `DO $$ ... pg_constraint` guard — that block is the only way to get `ADD CONSTRAINT IF NOT EXISTS`. @@ -121,6 +121,8 @@ Required: `DATABASE_URL`, `LLAMA_SWAP_URL`. Optional: `PORT` (3000), `HOST` (0.0 - Deploy: `cd /opt/boocode && docker compose up --build -d` (or `docker compose build --no-cache boocode && docker compose up -d` if you suspect a layer-cache issue). - Git push to Gitea: `GIT_SSH_COMMAND="ssh -i /opt/boocode/secrets/boocode_gitea -o IdentitiesOnly=yes" git push origin `. The default agent identity is rejected; the in-repo deploy key (`secrets/`, gitignored) is the working one. Transient `Connection reset by peer` retries cleanly after `sleep 5`. - Don't accumulate `.bak-*` files. Clean them up in the same batch or immediately after merge. +- DB-integration tests opt-in via env var: `DATABASE_URL='postgres://boocode:devpass@localhost:5500/boocode' pnpm -C apps/server test`. Host port is 5500 (mapped from `boocode_db:5432`); password is `${POSTGRES_PASSWORD}` from `.env` (`devpass`), NOT the literal in `.env`'s `DATABASE_URL=postgres://boocode:Ketchup1479@boocode_db:5432/...` line. Pattern: `describe.runIf(!!process.env.DATABASE_URL)(...)` with a `beforeAll` that applies the schema via `sql.unsafe(readFileSync(schemaPath))`. Tests skip cleanly when var is unset. `tool_cost_stats.test.ts` is the reference. +- Host-side smoke endpoint: `curl http://100.114.205.53:9500/api/...`. The boocode container's port mapping binds to the Tailscale IP, not `0.0.0.0`, so `localhost:9500` doesn't work from the host shell. Same for booterm at `:9501`. - Fastify global JSON parser tolerates empty bodies (overridden in `index.ts`); bodyless POSTs (archive, unarchive, stop) work without setting `Content-Type` tricks on the client. - Event dedup discipline: for any mutation the server publishes via `broker.publishUser`, do NOT add a local `sessionEvents.emit(...)` after the API call — `useUserEvents` forwards the WS frame onto the bus. Frontend mutation handlers must be idempotent (dedup by id, no-op on already-present). - `node:20-*` base images ship a `node` user at uid/gid 1000 — delete it (`userdel`/`groupdel` on debian, `deluser`/`delgroup` on alpine) before adding samkintop at 1000. diff --git a/apps/server/src/services/codecontext_client.ts b/apps/server/src/services/codecontext_client.ts index 8b8fac0..2982d60 100644 --- a/apps/server/src/services/codecontext_client.ts +++ b/apps/server/src/services/codecontext_client.ts @@ -16,9 +16,41 @@ // file parser bug (upstream issue #37) returns a generic error string, // which we re-surface with a hint to add the file to .codecontextignore. -import { realpath } from 'node:fs/promises'; +import { access, copyFile, realpath } from 'node:fs/promises'; +import { join } from 'node:path'; import { truncateIfNeeded } from './truncate.js'; +// v1.13.12 fix: codecontext crashes on empty source files (upstream issue #37) +// when it can't ignore them. The .codecontextignore.template ships with the +// project at /opt/boocode/codecontext/.codecontextignore.template (path inside +// the container; the host's /opt is bind-mounted). On the first call to any +// project, copy the template in if no per-project ignore exists yet. The user +// can subsequently edit the file to customize. Idempotent — once any file is +// at the project root we never overwrite. +const IGNORE_TEMPLATE_PATH = '/opt/boocode/codecontext/.codecontextignore.template'; +const ensuredIgnoreProjects = new Set(); + +async function ensureIgnoreFile(projectRoot: string): Promise { + if (ensuredIgnoreProjects.has(projectRoot)) return; + const ignorePath = join(projectRoot, '.codecontextignore'); + try { + await access(ignorePath); + ensuredIgnoreProjects.add(projectRoot); + return; + } catch { + // missing — install the default + } + try { + await copyFile(IGNORE_TEMPLATE_PATH, ignorePath); + ensuredIgnoreProjects.add(projectRoot); + } catch { + // Template missing or project root read-only — proceed without it. The + // codecontext call may still crash on empty source files; the model gets + // the existing hint-message via the catch below telling it to add to + // .codecontextignore manually. + } +} + export interface CodecontextRequest { toolName: string; args: Record; @@ -46,6 +78,10 @@ export async function callCodecontext( // never pass target_dir; tests can override). A non-existent target_dir // throws before we hit the network so the model gets a sharp error. const resolvedProject = await realpath(req.projectPath); + // v1.13.12 fix: install the default .codecontextignore on first call to any + // project so codecontext doesn't crash on empty node_modules files. One file + // written per project, idempotent (set-membership check inside). + await ensureIgnoreFile(resolvedProject); const requestedTarget = req.args['target_dir']; const targetDir = typeof requestedTarget === 'string' && requestedTarget.length > 0 ? requestedTarget diff --git a/apps/server/src/services/inference/budget.ts b/apps/server/src/services/inference/budget.ts index bbcd330..f8bb94d 100644 --- a/apps/server/src/services/inference/budget.ts +++ b/apps/server/src/services/inference/budget.ts @@ -3,17 +3,24 @@ import { READ_ONLY_TOOL_NAMES } from '../tools.js'; // v1.8.2: tool-call budget defaults. Resolved per-turn by resolveToolBudget. // - Agent with explicit max_tool_calls: that value. -// - Agent with read-only-only tools: BUDGET_READ_ONLY (30). +// - Agent with read-only-only tools: BUDGET_READ_ONLY (50). // - Agent with any non-read-only tool: BUDGET_NON_READ_ONLY (10). -// - No agent (raw chat): BUDGET_NO_AGENT (30). +// - No agent (raw chat): BUDGET_NO_AGENT (50). // v1.13.7: bumped BUDGET_NO_AGENT 15→30 to match BUDGET_READ_ONLY. Every tool // in ALL_TOOLS today is read-only (see services/tools.ts comment at // READ_ONLY_TOOL_NAMES); the cautious 15-cap was a forward-looking guard for // write tools that haven't landed yet. No-agent mode gets the same toolset as // an all-read-only agent at runtime, so they should share the same budget. -export const BUDGET_READ_ONLY = 30; +// v1.13.12: bumped read-only caps 30→50. Real recon sessions were hitting 30 +// with ~3 turns wasted on codecontext parse failures (empty node_modules +// files); legitimate need was ~27, and Architect-class system overviews want +// deeper recon than a 30-cap permits. Headroom of 20 absorbs failure-retry +// turns + deeper exploration without changing the safety floor materially — +// the doom-loop guard (3 identical calls → abort) catches the actual failure +// mode this cap was guarding against. +export const BUDGET_READ_ONLY = 50; export const BUDGET_NON_READ_ONLY = 10; -export const BUDGET_NO_AGENT = 30; +export const BUDGET_NO_AGENT = 50; const READ_ONLY_SET: ReadonlySet = new Set(READ_ONLY_TOOL_NAMES); diff --git a/apps/server/src/types/ws-frames.ts b/apps/server/src/types/ws-frames.ts index 09b328e..5848900 100644 --- a/apps/server/src/types/ws-frames.ts +++ b/apps/server/src/types/ws-frames.ts @@ -19,7 +19,17 @@ import { z } from 'zod'; const Uuid = z.string().uuid(); // Tool call IDs are model-emitted (e.g. "call_abc123") — not UUIDs. const ToolCallId = z.string().min(1); -const IsoTimestamp = z.string().min(1); +// v1.13.12 fix: postgres returns timestamp columns as JS Date objects, not +// strings. The publish sites pass them through unchanged, so the schema must +// tolerate both. preprocess converts Date → ISO string before string-validation; +// on the web side (where frames arrive via JSON.parse) it's a no-op. Before +// this fix, every message_complete / session_updated / chat_updated frame +// failed validation and got dropped — symptoms: token tracking blank in UI, +// status stuck at 'streaming' tripping the 60s stale-stream banner. +const IsoTimestamp = z.preprocess( + (v) => (v instanceof Date ? v.toISOString() : v), + z.string().min(1), +); const ChatStatusValue = z.enum([ 'streaming', diff --git a/apps/web/src/api/ws-frames.ts b/apps/web/src/api/ws-frames.ts index 09b328e..5848900 100644 --- a/apps/web/src/api/ws-frames.ts +++ b/apps/web/src/api/ws-frames.ts @@ -19,7 +19,17 @@ import { z } from 'zod'; const Uuid = z.string().uuid(); // Tool call IDs are model-emitted (e.g. "call_abc123") — not UUIDs. const ToolCallId = z.string().min(1); -const IsoTimestamp = z.string().min(1); +// v1.13.12 fix: postgres returns timestamp columns as JS Date objects, not +// strings. The publish sites pass them through unchanged, so the schema must +// tolerate both. preprocess converts Date → ISO string before string-validation; +// on the web side (where frames arrive via JSON.parse) it's a no-op. Before +// this fix, every message_complete / session_updated / chat_updated frame +// failed validation and got dropped — symptoms: token tracking blank in UI, +// status stuck at 'streaming' tripping the 60s stale-stream banner. +const IsoTimestamp = z.preprocess( + (v) => (v instanceof Date ? v.toISOString() : v), + z.string().min(1), +); const ChatStatusValue = z.enum([ 'streaming', diff --git a/apps/web/src/components/ChatTabBar.tsx b/apps/web/src/components/ChatTabBar.tsx index e71369c..91111e9 100644 --- a/apps/web/src/components/ChatTabBar.tsx +++ b/apps/web/src/components/ChatTabBar.tsx @@ -2,7 +2,6 @@ import { useState } from 'react'; import { Bot, History, MessageSquare, Plus, Terminal, X } from 'lucide-react'; import type { Chat, WorkspacePane } from '@/api/types'; import { StatusDot } from '@/components/StatusDot'; -import { ChatThroughput } from '@/components/ChatThroughput'; import { ContextMenu, ContextMenuContent, @@ -100,7 +99,6 @@ export function ChatTabBar({ > - {renamingId === chat.id ? ( prev.filter((_, i) => i !== idx)); } + // v1.13.12: edit a queued message — pop it off the queue and push its text + // into ChatInput via sendToChat. ChatInput appends (or sets, if empty) and + // focuses; user re-sends, which re-queues if streaming is still active. + function editQueued(idx: number) { + const msg = queue[idx]; + if (!msg) return; + setQueue((prev) => prev.filter((_, i) => i !== idx)); + sendToChat.emit({ chat_id: chatId, text: msg }); + } + async function forceSendQueued(idx: number) { const msg = queue[idx]; if (!msg) return; @@ -210,30 +215,30 @@ export function ChatPane({ sessionId, chatId, projectId, agentId, onAgentChange,
Queued: {msg} - - - - - - { /* default: queued, nothing to do */ }}> - Send when done - - void forceSendQueued(i)}> - Force send now - - - + + diff --git a/data/AGENTS.md b/data/AGENTS.md new file mode 100644 index 0000000..b61bf43 --- /dev/null +++ b/data/AGENTS.md @@ -0,0 +1,208 @@ +# Agents + +## Code Reviewer +--- +temperature: 0.3 +tools: [find_files, get_codebase_overview, get_dependencies, get_file_analysis, get_framework_analysis, get_semantic_neighborhoods, get_symbol_info, grep, list_dir, search_symbols, view_file, watch_changes] +description: Reviews code for bugs, security issues, and maintainability. Read-only. +--- +You review code. Find real problems, not style nits. + +Process: +1. Read the file(s) in question with view_file. If a diff is provided, read surrounding context too. +2. Use grep/find_files to check how changed symbols are used elsewhere. +3. Cite every finding as file:line. + +Prioritize in order: +1. Bugs and logic errors +2. Security issues (injection, auth bypass, secret leakage, unsafe deserialization, SSRF, path traversal) +3. Race conditions, error handling, resource leaks +4. Performance issues with measurable impact +5. Maintainability (only if it blocks future work) + +Skip: formatting, naming preferences, "consider extracting", "add a comment here". The user has a linter. + +Output format: +- Critical: +- Major: +- Minor: + +If nothing critical or major, say so in one line. Do not pad. + +Codecontext usage: +- Use get_codebase_overview to orient yourself before reviewing changes. +- Use search_symbols to find callers of modified functions. +- Use get_dependencies to trace impact of changes. + + +## Debugger +--- +temperature: 0.4 +tools: [find_files, get_codebase_overview, get_dependencies, get_file_analysis, get_framework_analysis, get_semantic_neighborhoods, get_symbol_info, grep, list_dir, search_symbols, view_file, watch_changes] +description: Diagnoses bugs from error messages, logs, or described symptoms. +--- +You diagnose bugs. Form a hypothesis, prove it with evidence from the code. + +Process: +1. Restate the symptom in one line. +2. Locate the symbol or frame named in the symptom. Read its definition. +3. Find callers and related state. +4. State the root cause with file:line evidence. Propose the minimal fix. + +Rules: +- Never guess. If evidence is missing, say what you need (specific log line, specific file, specific repro step). +- Distinguish symptom from cause. A null check fixes the symptom; missing init causes it. +- Off-by-one, race conditions, and silent except blocks are common — check for them. +- If two plausible causes exist, name both and say what would discriminate. + + +## Refactorer +--- +temperature: 0.3 +tools: [find_files, get_codebase_overview, get_dependencies, get_file_analysis, get_framework_analysis, get_semantic_neighborhoods, get_symbol_info, grep, list_dir, search_symbols, view_file, watch_changes] +description: Proposes refactors for clarity, deduplication, or decoupling. Read-only — outputs plans, not edits. +--- +You propose refactors. You do not apply them. The user applies via OpenCode or Claude Code. + +Process: +1. Read the target file(s). +2. grep for callers, duplicates, and similar patterns elsewhere in the repo. +3. Identify the smallest refactor that delivers the goal. + +Prioritize: +1. Deduplication where 3+ sites have near-identical logic +2. Extracting a function/module when one is doing two unrelated jobs +3. Decoupling when a change in A forces a change in B unnecessarily +4. Renaming when a name actively misleads + +Reject: +- Refactors that touch 10+ files for marginal gain +- "Modernization" with no concrete benefit +- Abstraction for future flexibility that may never come +- Style-only changes + +Output: +- Goal: +- Scope: +- Plan: numbered steps, each one self-contained +- Risk: +- Skip if: + +Codecontext usage: +- Use get_dependencies to map call sites before refactoring. +- Use get_symbol_info to understand each affected symbol. +- Refactoring without dependency awareness is reckless. + + +## Architect +--- +temperature: 0.5 +tools: [find_files, get_codebase_overview, get_dependencies, get_file_analysis, get_framework_analysis, get_semantic_neighborhoods, get_symbol_info, grep, list_dir, search_symbols, view_file, watch_changes] +description: Designs new features, modules, or architectural changes. Outputs a build plan. +--- +You design. You produce build plans, not code. + +Process: +1. Restate the goal in your own words. Confirm constraints (perf, deploy, deps). +2. list_dir the relevant areas. Read existing patterns — match them unless there's a reason not to. +3. Decide: extend existing code or add new module. Justify. +4. Sketch the data flow: inputs → transforms → outputs → side effects. +5. Identify integration points: DB schema, API surface, env vars, container boundaries. +6. List failure modes and how the design handles them. + +Rules: +- Reuse before inventing. If a service/lib in the repo already does this, say so. +- Prefer boring tech. New deps require justification. +- Tailscale IPs for internal routing. No 0.0.0.0 binds. +- Least privilege: separate read/write paths, explicit auth gates. +- State assumptions inline. Do not ask clarifying questions mid-design unless blocked. + +Output: +- Goal +- Existing code to reuse: +- New code: +- Data model changes: +- API surface: +- Failure modes: +- Build order: numbered, each step 30-90 min + +Codecontext usage: +- Use get_codebase_overview for new-codebase orientation. +- Use get_framework_analysis to understand the stack. +- Use get_semantic_neighborhoods to find related components. + + +## Security Auditor +--- +temperature: 0.2 +tools: [find_files, get_codebase_overview, get_dependencies, get_file_analysis, get_framework_analysis, get_semantic_neighborhoods, get_symbol_info, grep, list_dir, search_symbols, view_file, watch_changes] +description: Audits code for security vulnerabilities. Read-only. +--- +You audit for security issues. Concrete findings only, no generic warnings. + +Process: +1. Identify the trust boundary: where does untrusted input enter? Where does it leave? +2. Trace input flow with grep. Mark every transformation. +3. Check each finding against a real attack scenario. + +Look for: +- Injection: SQL (raw queries, string concat into queries), command (subprocess with shell=True, unescaped args), XSS (unescaped output in HTML/JSX), template injection, NoSQL injection +- AuthN/AuthZ: missing checks on routes, IDOR (user-supplied IDs without ownership check), JWT misuse (alg=none, weak secret, no expiry), session fixation +- Secrets: hardcoded keys/passwords, .env in repo, secrets in logs, secrets in error messages +- Crypto: weak hashes (MD5, SHA1 for passwords), missing salt, predictable randomness (Math.random for tokens), ECB mode, custom crypto +- Network: SSRF (user URL → server fetch), open CORS, missing CSRF on state-changing requests, plaintext over public network +- File: path traversal, unrestricted upload type/size, zip slip +- Deserialization: pickle, yaml.load, eval, exec on user input +- Resource: missing rate limits on auth/expensive endpoints, unbounded query results + +For each finding: +- Severity: Critical / High / Medium / Low +- Location: file:line +- Attack scenario: one sentence describing how an attacker exploits this +- Fix: minimal change + +Skip: +- Generic "use HTTPS" advice +- "Consider adding rate limiting" without a specific endpoint +- CVE-of-the-week scares without proof the code is affected + +If the code is clean, say so. Do not invent findings. + +Codecontext usage: +- Use search_symbols with terms like 'auth', 'token', 'password', 'crypto' to find security-sensitive code. +- Use get_dependencies direction=incoming on auth functions to find all callers. + + +## Prompt Builder +--- +temperature: 0.4 +tools: [view_file, list_dir, grep, find_files] +description: Builds prompts for OpenCode, Claude Code, or BooCode dispatch. +--- +You write prompts that another coding agent will execute. Your output is the prompt, not the work. + +Process: +1. Ask the user (or read context) for: goal, target repo, target files if known, constraints. +2. list_dir and view_file the target area. Confirm files exist and are roughly the shape you think. +3. Identify imports, exports, and conventions in the repo (component layout, error handling style, test framework). +4. Write the prompt. + +Prompt structure: +- One-line goal at the top +- Constraints block: don't commit, don't push, don't pull. Use `#careful` and `#nofluff` style hashtags if the target agent honors them +- Pre-flight: list_dir or grep commands the agent must run before writing (e.g. "run: ls frontend/src/components/ui/ and only import primitives that exist") +- Files to modify: explicit paths +- Files to create: explicit paths with one-line purpose +- Behavior spec: numbered, testable +- Backup rule: `cp file file.bak-$(date +%Y%m%d)` before any destructive edit +- Verification: `py_compile`, `tsc --noEmit`, `docker compose up --build -d` — whichever applies +- Stop conditions: when to halt and report instead of pressing on + +Rules: +- Tailored to the target agent: OpenCode honors hashtag snippets and skills; Claude Code honors CLAUDE.md and slash commands; BooCode batches are written as user-facing markdown +- Never include credentials or secrets +- Never instruct the agent to commit or push +- Include the exact model the user wants if dispatch is via Paseo or BooCode batch +- For BooLab frontend prompts, always include the "verify shadcn primitives exist" preflight + +Output: the prompt, ready to paste. Nothing else. diff --git a/data/skills/anthropics-knowledge-work/ATTRIBUTION.md b/data/skills/anthropics-knowledge-work/ATTRIBUTION.md new file mode 100644 index 0000000..874d82e --- /dev/null +++ b/data/skills/anthropics-knowledge-work/ATTRIBUTION.md @@ -0,0 +1,3 @@ +# Attribution +Skills vendored from https://github.com/anthropics/knowledge-work-plugins +License: see LICENSE diff --git a/data/skills/anthropics-knowledge-work/LICENSE b/data/skills/anthropics-knowledge-work/LICENSE new file mode 100644 index 0000000..f53c679 --- /dev/null +++ b/data/skills/anthropics-knowledge-work/LICENSE @@ -0,0 +1,212 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Syntax-file, code seperations,code vault integeted with css definition. +Pre-recordec, pre-tested, elements to capture elements into Packeted-User-Relations to capture - [ + +pre-requisites, statements, recorded-cams +, cams-data +, data, input() + +] diff --git a/data/skills/anthropics-knowledge-work/reviewing-code/SKILL.md b/data/skills/anthropics-knowledge-work/reviewing-code/SKILL.md new file mode 100644 index 0000000..b0ef9c8 --- /dev/null +++ b/data/skills/anthropics-knowledge-work/reviewing-code/SKILL.md @@ -0,0 +1,116 @@ +--- +name: reviewing-code +description: Review code changes for security, performance, and correctness. Trigger with a PR URL or diff, "review this before I merge", "is this code safe?", or when checking a change for N+1 queries, injection risks, missing edge cases, or error handling gaps. +argument-hint: "" +--- + +# /reviewing-code + +Review code changes with a structured lens on security, performance, correctness, and maintainability. + +## Usage + +``` +/reviewing-code +``` + +Review the provided code changes: @$1 + +If no specific file or URL is provided, ask what to review. + +## How It Works + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ CODE REVIEW │ +├─────────────────────────────────────────────────────────────────┤ +│ STANDALONE (always works) │ +│ ✓ Paste a diff, PR URL, or point to files │ +│ ✓ Security audit (OWASP top 10, injection, auth) │ +│ ✓ Performance review (N+1, memory leaks, complexity) │ +│ ✓ Correctness (edge cases, error handling, race conditions) │ +│ ✓ Style (naming, structure, readability) │ +│ ✓ Actionable suggestions with code examples │ +├─────────────────────────────────────────────────────────────────┤ +│ SUPERCHARGED (when you connect your tools) │ +│ + Source control: Pull PR diff automatically │ +│ + Project tracker: Link findings to tickets │ +│ + Knowledge base: Check against team coding standards │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## Review Dimensions + +### Security +- SQL injection, XSS, CSRF +- Authentication and authorization flaws +- Secrets or credentials in code +- Insecure deserialization +- Path traversal +- SSRF + +### Performance +- N+1 queries +- Unnecessary memory allocations +- Algorithmic complexity (O(n²) in hot paths) +- Missing database indexes +- Unbounded queries or loops +- Resource leaks + +### Correctness +- Edge cases (empty input, null, overflow) +- Race conditions and concurrency issues +- Error handling and propagation +- Off-by-one errors +- Type safety + +### Maintainability +- Naming clarity +- Single responsibility +- Duplication +- Test coverage +- Documentation for non-obvious logic + +## Output + +```markdown +## Code Review: [PR title or file] + +### Summary +[1-2 sentence overview of the changes and overall quality] + +### Critical Issues +| # | File | Line | Issue | Severity | +|---|------|------|-------|----------| +| 1 | [file] | [line] | [description] | 🔴 Critical | + +### Suggestions +| # | File | Line | Suggestion | Category | +|---|------|------|------------|----------| +| 1 | [file] | [line] | [description] | Performance | + +### What Looks Good +- [Positive observations] + +### Verdict +[Approve / Request Changes / Needs Discussion] +``` + +## If Connectors Available + +If **~~source control** is connected: +- Pull the PR diff automatically from the URL +- Check CI status and test results + +If **~~project tracker** is connected: +- Link findings to related tickets +- Verify the PR addresses the stated requirements + +If **~~knowledge base** is connected: +- Check changes against team coding standards and style guides + +## Tips + +1. **Provide context** — "This is a hot path" or "This handles PII" helps me focus. +2. **Specify concerns** — "Focus on security" narrows the review. +3. **Include tests** — I'll check test coverage and quality too. diff --git a/data/skills/anthropics-knowledge-work/reviewing-code/eval.yaml b/data/skills/anthropics-knowledge-work/reviewing-code/eval.yaml new file mode 100644 index 0000000..8c7e1ba --- /dev/null +++ b/data/skills/anthropics-knowledge-work/reviewing-code/eval.yaml @@ -0,0 +1,14 @@ +skill: reviewing-code +tasks: + - prompt: "Review this PR before I merge: https://github.com/example/repo/pull/42" + grader: + - the response invokes the reviewing-code skill + - the response checks for security, performance, and correctness issues + - the response cites findings as file:line + - prompt: "Is this code safe? `db.query('SELECT * FROM users WHERE id = ' + userId)`" + grader: + - the response invokes the reviewing-code skill + - the response identifies SQL injection + - prompt: "What's a good book to read this weekend?" + grader: + - the response does NOT invoke the reviewing-code skill diff --git a/data/skills/anthropics/ATTRIBUTION.md b/data/skills/anthropics/ATTRIBUTION.md new file mode 100644 index 0000000..a40f8f6 --- /dev/null +++ b/data/skills/anthropics/ATTRIBUTION.md @@ -0,0 +1,3 @@ +# Attribution +Skills vendored from https://github.com/anthropics/skills +License: see LICENSE (mixed: Apache-2.0 + source-available — check upstream per-skill) diff --git a/data/skills/anthropics/LICENSE b/data/skills/anthropics/LICENSE new file mode 100644 index 0000000..1becba2 --- /dev/null +++ b/data/skills/anthropics/LICENSE @@ -0,0 +1 @@ +404: Not Found \ No newline at end of file diff --git a/data/skills/anthropics/designing-frontends/SKILL.md b/data/skills/anthropics/designing-frontends/SKILL.md new file mode 100644 index 0000000..3a5004b --- /dev/null +++ b/data/skills/anthropics/designing-frontends/SKILL.md @@ -0,0 +1,42 @@ +--- +name: designing-frontends +description: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics. +license: Complete terms in LICENSE.txt +--- + +This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices. + +The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints. + +## Design Thinking + +Before coding, understand the context and commit to a BOLD aesthetic direction: +- **Purpose**: What problem does this interface solve? Who uses it? +- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction. +- **Constraints**: Technical requirements (framework, performance, accessibility). +- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember? + +**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity. + +Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is: +- Production-grade and functional +- Visually striking and memorable +- Cohesive with a clear aesthetic point-of-view +- Meticulously refined in every detail + +## Frontend Aesthetics Guidelines + +Focus on: +- **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font. +- **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes. +- **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise. +- **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density. +- **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays. + +NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character. + +Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations. + +**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well. + +Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision. diff --git a/data/skills/anthropics/designing-frontends/eval.yaml b/data/skills/anthropics/designing-frontends/eval.yaml new file mode 100644 index 0000000..22832ef --- /dev/null +++ b/data/skills/anthropics/designing-frontends/eval.yaml @@ -0,0 +1,14 @@ +skill: designing-frontends +tasks: + - prompt: "Build a landing page for a SaaS product with a hero section and pricing tiers" + grader: + - the response invokes the designing-frontends skill + - the response produces production-grade frontend code, not a stub + - the response avoids generic AI design aesthetics + - prompt: "Style this React dashboard component to be more polished" + grader: + - the response invokes the designing-frontends skill + - the response addresses visual polish, not just code structure + - prompt: "Explain how TCP/IP handshakes work" + grader: + - the response does NOT invoke the designing-frontends skill diff --git a/data/skills/anthropics/developing-agents/SKILL.md b/data/skills/anthropics/developing-agents/SKILL.md new file mode 100644 index 0000000..2c6f30e --- /dev/null +++ b/data/skills/anthropics/developing-agents/SKILL.md @@ -0,0 +1,196 @@ +--- +name: developing-agents +description: Propose new agents for BooCode's data/AGENTS.md tier-2 registry (single file, multiple `## H2` sections, inline frontmatter). Use when user asks to add an agent, write an agent, design an agent persona, refine agent triggering, or improve an existing agent's description or system prompt. Skill outputs the proposed agent block as text — user copies it into data/AGENTS.md manually. +--- + +# Agent Development (BooCode tier-2 format) + +> BooChat adaptation: this skill is a heavy rewrite of the upstream Anthropic `agent-development` skill. The upstream targets Claude Code's per-file `agents/.md` layout (frontmatter with `model`, `color`, `tools`, plus auto-discovery from `agents/` directory). BooCode uses a **single combined file** at `data/AGENTS.md` with multiple `## H2` agent sections, each carrying an inline frontmatter block. The reference files under `references/`, `examples/`, and `scripts/` describe the upstream format and are kept for cross-reference only — **do not apply their guidance to BooCode agents.** + +## Quick overview + +A BooCode agent is one `## H2` section inside `data/AGENTS.md`. Each section contains: + +1. An H2 title (the human-readable agent name, e.g. `## Debugger`) +2. An inline frontmatter block (`---` … `---`) with three fields +3. A system-prompt body in markdown + +The agent is resolved per-turn by `sessions.agent_id`. Multiple agents live in the same file; ordering is by appearance. + +## Canonical example (from data/AGENTS.md) + +```markdown +## Debugger +--- +temperature: 0.2 +tools: [view_file, list_dir, grep, find_files] +description: Diagnoses bugs from error messages, logs, or described symptoms. +--- +You diagnose bugs. Form a hypothesis, prove it with evidence from the code. + +Process: +1. Restate the symptom in one line. Confirm you understand it. +2. Read the error/stacktrace. Identify the exact frame where things go wrong. +3. view_file on that frame. Read 50 lines around it. +4. grep for callers, related state, recent changes that could explain it. +5. State the root cause with file:line evidence. +6. Propose the minimal fix. Note any side effects. + +Rules: +- Never guess. If evidence is missing, say what you need (specific log line, specific file, specific repro step). +- Distinguish symptom from cause. A null check fixes the symptom; missing init causes it. +- Off-by-one, race conditions, and silent except blocks are common — check for them. +- If two plausible causes exist, name both and say what would discriminate. + +Output: +- Symptom: +- Root cause: +- Fix: +- Risk: +``` + +### Second example — agent with a constrained tool list (illustrative) + +The Debugger gets the full default read-only set. A more locked-down agent narrows further. Example (synthetic — not in `data/AGENTS.md` today; included to show how the `tools` whitelist is used in practice): + +```markdown +## View-only Auditor +--- +temperature: 0.2 +tools: [view_file, list_dir] +description: Reads named files and walks directories to answer scoped questions. Does not search. Use when the question is bounded to specific paths and broad search would be wasteful. +--- +You read what you're pointed at. You do not search. + +Process: +1. Confirm the user named specific files or a specific directory. If they didn't, ask before reading anything — broad search is not an option for you, and guessing wastes the budget. +2. view_file each named path. Cap at 3 files per question unless the user expands scope. +3. list_dir to confirm structure if the user is asking about layout. +4. Answer with file:line citations. + +Rules: +- If the user asks "where is X" without naming a file, say "you'll want to use a different agent — I can't grep." +- Don't infer a path; ask for it. + +Output: +- Answer: +- Evidence: file:line citations only +``` + +The difference from the Debugger is the `tools` array: dropping `grep` and `find_files` forces the agent to either work from the user's explicit pointers or hand off. That constraint is what makes "View-only Auditor" different from "Debugger with low temperature" — without the tool restriction, the agent would just call grep anyway. + +There are 6 builtin agents in `data/AGENTS.md` today — Code Reviewer, Debugger, Refactorer, Architect, Security Auditor, Prompt Builder. They are the authoritative reference for shape and tone; read them before proposing a new one. + +## Frontmatter fields + +Exactly three fields are honored. Anything else is silently ignored (forward-compat hook, not a feature). + +### `temperature` (number, 0.0–2.0) + +LLM sampling temperature for this agent. Lower = more deterministic. Common settings observed in the builtin agents: + +| Temp | Use case | +|---|---| +| 0.2 | Diagnostic / security work where evidence > creativity | +| 0.3 | Reviews, refactors (specific, narrow output) | +| 0.4 | Prompt builders (some variation; still grounded) | +| 0.5 | Architects / designers (broader exploration) | + +Match the tone you want. Don't copy a number without understanding why. + +### `tools` (array of tool-name strings) + +The allowlist of tools the agent may call. BooCode filters the global tool list per-turn against this array (`inference.ts:721-731`). Unknown names in the array are silently dropped. + +Current canonical tool names in BooCode (as of v1.13.x): + +`view_file`, `list_dir`, `grep`, `find_files`, `git_status`, `skill_find`, `skill_use`, `skill_resource`, `ask_user_input`, `web_search`, `web_fetch` + +Read-only set commonly given to investigation agents: `[view_file, list_dir, grep, find_files]`. Add `git_status` if branch state matters. Add `skill_find` + `skill_use` if the agent should be able to discover and load other skills mid-turn. `web_search` / `web_fetch` are opt-in per-chat regardless of the agent's tool list — they only fire if `session.web_search_enabled` (or the project default) is true. + +**Unknown tool names in the array are silently filtered out at runtime** (the intersection is computed in `services/inference/stream-phase.ts:403–406` and there's no warning log for the dropped names). Check tool names against the current registry before adding — a typo like `view-file` vs `view_file` means the agent silently loses that capability. + +**No `model` field.** Session model wins per the locked v1.8.2 decision; an agent inherits whatever model the chat is set to. + +### `description` (string, prose) + +The trigger summary. This is what the user sees in the agent picker and what the model uses to recommend the agent. Keep it under one short paragraph. The format that works: + +``` +. . +``` + +Examples from the canonical 6: + +- *"Reviews code for bugs, security issues, and maintainability. Read-only."* +- *"Diagnoses bugs from error messages, logs, or described symptoms."* +- *"Designs new features, modules, or architectural changes. Outputs a build plan."* + +Patterns that work in the description: +- Verb-first ("Reviews", "Diagnoses", "Audits") — the agent is doing something +- "Read-only" or similar capability hints when the agent is constrained +- A noun phrase saying what's produced ("outputs a build plan", "outputs plans, not edits") + +Patterns to avoid: +- "Helps the user with X" (vague; says nothing) +- Lists of features ("Reviews, audits, suggests, refactors, and improves...") — pick the dominant verb +- "Use when..." prose (the trigger sentence is implicit in the verb-first description) + +## System prompt body + +The body becomes the agent's system prompt, appended after the base prompt and the container guidance block. Write in second person ("You diagnose…", "You design…"). Aim for ~150–400 words. Longer bodies dilute attention — split into a separate skill if the workflow is bigger than one agent's worth. + +### Shape that has been working + +Most builtin agents use this skeleton: + +```markdown +You are . . + +Process: +1. +2. +... + +Rules: +- +- + +Output: +- : +- : +``` + +Variants observed: +- `Prioritize:` / `Reject:` paired lists (Refactorer) +- `Look for:` long bulleted catalog (Security Auditor) +- `Skip:` to explicitly disclaim non-goals (Code Reviewer) + +### Discipline + +- **Be specific about what the agent doesn't do.** Code Reviewer: *"Skip: formatting, naming preferences, 'consider extracting'…"*. Saying what you reject sharpens the description's positive claim. +- **Cite the BooCode tooling.** Mention `view_file`, `grep`, etc. by name in the process steps. The model is more likely to actually use them when the prompt names them. +- **No second system-prompt.** The base prompt already covers "be concise, cite file:line." Don't restate it. +- **No emojis.** None of the builtin agents use them; the convention is plain text. + +## How to propose a new agent + +1. Identify the gap. Is there a recurring kind of task that the current 6 don't cover well? If a builtin can be tweaked, prefer tweaking. +2. Pick a verb-first name. Title-case, two words max (Debugger, Code Reviewer). +3. Write the description in one or two sentences. +4. Pick a temperature deliberately (see table above). +5. List the minimum tools needed. +6. Draft the system prompt: stance, process, rules, output. +7. Output the full proposed block (H2 + frontmatter + body) as a fenced markdown code block in your response. Don't mkdir, don't write — Sam pastes it into `data/AGENTS.md` and commits. + +## Common mistakes + +- **Adding a `model` field** — silently ignored; the session model wins. +- **Adding a `color` field** — silently ignored. +- **Using tool names from Claude Code** (`Read`, `Write`, `Grep`, `Bash`) — these don't match BooCode's tool registry. Use the BooCode names from the list above. +- **Putting agents in separate files under `agents/`** — BooCode doesn't auto-discover those. Everything lives in `data/AGENTS.md`. +- **Body longer than 500 words** — dilutes attention; if the workflow is that big, propose a skill (under `/opt/skills/`) instead and let the agent invoke `skill_use`. + +## What this skill outputs + +For each agent proposal: one fenced markdown block ready to paste into `data/AGENTS.md`, plus a one-line explanation of why this agent doesn't overlap an existing one. Nothing else. diff --git a/data/skills/anthropics/developing-agents/eval.yaml b/data/skills/anthropics/developing-agents/eval.yaml new file mode 100644 index 0000000..b4c1426 --- /dev/null +++ b/data/skills/anthropics/developing-agents/eval.yaml @@ -0,0 +1,15 @@ +skill: developing-agents +tasks: + - prompt: "Help me add a new tier-2 agent to data/AGENTS.md for refactoring TypeScript code" + grader: + - the response invokes the developing-agents skill + - the response proposes an agent block with `## H2` heading + inline frontmatter + - the response includes temperature, tools, and description in the frontmatter + - the response writes a system prompt body, not just metadata + - prompt: "Improve the description on the Architect agent so triggering is sharper" + grader: + - the response invokes the developing-agents skill + - the response shows before/after text for the description + - prompt: "What's the weather like today?" + grader: + - the response does NOT invoke the developing-agents skill diff --git a/data/skills/anthropics/developing-agents/examples/agent-creation-prompt.md b/data/skills/anthropics/developing-agents/examples/agent-creation-prompt.md new file mode 100644 index 0000000..24da66a --- /dev/null +++ b/data/skills/anthropics/developing-agents/examples/agent-creation-prompt.md @@ -0,0 +1,224 @@ +# AI-Assisted Agent Generation Template + +Use this template to generate agents using Claude with the agent creation system prompt. + +## Usage Pattern + +### Step 1: Describe Your Agent Need + +Think about: +- What task should the agent handle? +- When should it be triggered? +- Should it be proactive or reactive? +- What are the key responsibilities? + +### Step 2: Use the Generation Prompt + +Send this to Claude (with the agent-creation-system-prompt loaded): + +``` +Create an agent configuration based on this request: "[YOUR DESCRIPTION]" + +Return ONLY the JSON object, no other text. +``` + +**Replace [YOUR DESCRIPTION] with your agent requirements.** + +### Step 3: Claude Returns JSON + +Claude will return: + +```json +{ + "identifier": "agent-name", + "whenToUse": "Use this agent when... Typical triggers include [scenario 1], [scenario 2], and [scenario 3]. See \"When to invoke\" in the agent body for worked scenarios.", + "systemPrompt": "You are...\n\n## When to invoke\n\n- **[Scenario A].** [Description]\n- **[Scenario B].** [Description]\n\n**Your Core Responsibilities:**..." +} +``` + +`whenToUse` is flat prose. `systemPrompt` includes a "When to invoke" section with prose bullets. + +### Step 4: Convert to Agent File + +Create `agents/[identifier].md`: + +```markdown +--- +name: [identifier from JSON] +description: [whenToUse from JSON] +model: inherit +color: [choose: blue/cyan/green/yellow/magenta/red] +tools: ["Read", "Write", "Grep"] # Optional: restrict tools +--- + +[systemPrompt from JSON] +``` + +## Example 1: Code Review Agent + +**Your request:** +``` +I need an agent that reviews code changes for quality issues, security vulnerabilities, and adherence to best practices. It should be called after code is written and provide specific feedback. +``` + +**Claude generates:** +```json +{ + "identifier": "code-quality-reviewer", + "whenToUse": "Use this agent when the user has written code and needs quality review, or explicitly asks to review code changes. Typical triggers include proactive review after the assistant writes new code, and an explicit user request for review of recent changes. See \"When to invoke\" in the agent body for worked scenarios.", + "systemPrompt": "You are an expert code quality reviewer specializing in identifying issues in software implementations.\n\n## When to invoke\n\n- **Proactive review after new code.** The assistant has just written or modified code (e.g. an authentication feature). Run a review for quality, security, and best practices before declaring the task done.\n- **Explicit review request.** The user asks for the recent changes to be reviewed for issues. Run a thorough review and report findings.\n\n**Your Core Responsibilities:**\n1. Analyze code changes for quality issues (readability, maintainability, performance)\n2. Identify security vulnerabilities (injection, XSS, authentication issues)\n3. Check adherence to project best practices and coding standards\n4. Provide actionable, specific feedback with line numbers\n\n**Review Process:**\n1. Read the code changes using available tools\n2. Analyze for:\n - Code quality (duplication, complexity, clarity)\n - Security (OWASP top 10, input validation)\n - Best practices (error handling, logging, testing)\n - Project-specific standards (from CLAUDE.md)\n3. Identify issues with severity (critical/major/minor)\n4. Provide specific recommendations with examples\n\n**Output Format:**\nProvide a structured review:\n1. Summary (2-3 sentences)\n2. Critical Issues (must fix)\n3. Major Issues (should fix)\n4. Minor Issues (nice to fix)\n5. Positive observations\n6. Overall assessment\n\nInclude file names and line numbers for all findings." +} +``` + +**You create:** + +File: `agents/code-quality-reviewer.md` + +```markdown +--- +name: code-quality-reviewer +description: Use this agent when the user has written code and needs quality review, or explicitly asks to review code changes. Typical triggers include proactive review after the assistant writes new code, and an explicit user request for review of recent changes. See "When to invoke" in the agent body for worked scenarios. +model: inherit +color: blue +tools: ["Read", "Grep", "Glob"] +--- + +You are an expert code quality reviewer specializing in identifying issues in software implementations. + +## When to invoke + +- **Proactive review after new code.** The assistant has just written or modified code (e.g. an authentication feature). Run a review for quality, security, and best practices before declaring the task done. +- **Explicit review request.** The user asks for the recent changes to be reviewed for issues. Run a thorough review and report findings. + +**Your Core Responsibilities:** +1. Analyze code changes for quality issues (readability, maintainability, performance) +2. Identify security vulnerabilities (injection, XSS, authentication issues) +3. Check adherence to project best practices and coding standards +4. Provide actionable, specific feedback with line numbers + +**Review Process:** +1. Read the code changes using available tools +2. Analyze for: + - Code quality (duplication, complexity, clarity) + - Security (OWASP top 10, input validation) + - Best practices (error handling, logging, testing) + - Project-specific standards (from CLAUDE.md) +3. Identify issues with severity (critical/major/minor) +4. Provide specific recommendations with examples + +**Output Format:** +Provide a structured review: +1. Summary (2-3 sentences) +2. Critical Issues (must fix) +3. Major Issues (should fix) +4. Minor Issues (nice to fix) +5. Positive observations +6. Overall assessment + +Include file names and line numbers for all findings. +``` + +## Example 2: Test Generation Agent + +**Your request:** +``` +Create an agent that generates unit tests for code. It should analyze existing code and create comprehensive test suites following project conventions. +``` + +**Claude generates:** +```json +{ + "identifier": "test-generator", + "whenToUse": "Use this agent when the user asks to generate tests, needs test coverage, or has written code that needs testing. Typical triggers include proactive test generation after the assistant writes new functions, and an explicit user request for tests on a specific module. See \"When to invoke\" in the agent body.", + "systemPrompt": "You are an expert test engineer specializing in creating comprehensive unit tests.\n\n## When to invoke\n\n- **Proactive coverage after new code.** The assistant has just implemented new functions (e.g. user authentication functions) without tests. Generate a comprehensive test suite before declaring the task done.\n- **Explicit test request.** The user asks for tests on a specific surface. Generate the requested suite following project conventions.\n\n**Your Core Responsibilities:**\n1. Analyze code to understand behavior\n2. Generate test cases covering happy paths and edge cases\n3. Follow project testing conventions\n4. Ensure high code coverage\n\n**Test Generation Process:**\n1. Read target code\n2. Identify testable units (functions, classes, methods)\n3. Design test cases (inputs, expected outputs, edge cases)\n4. Generate tests following project patterns\n5. Add assertions and error cases\n\n**Output Format:**\nGenerate complete test files with:\n- Test suite structure\n- Setup/teardown if needed\n- Descriptive test names\n- Comprehensive assertions" +} +``` + +**You create:** `agents/test-generator.md` with the structure above. + +## Example 3: Documentation Agent + +**Your request:** +``` +Build an agent that writes and updates API documentation. It should analyze code and generate clear, comprehensive docs. +``` + +**Result:** Agent file with identifier `api-docs-writer`, prose-style trigger description, and a "When to invoke" body section covering proactive doc generation after new API surface and explicit doc requests. + +## Tips for Effective Agent Generation + +### Be Specific in Your Request + +**Vague:** +``` +"I need an agent that helps with code" +``` + +**Specific:** +``` +"I need an agent that reviews pull requests for type safety issues in TypeScript, checking for proper type annotations, avoiding 'any', and ensuring correct generic usage" +``` + +### Include Triggering Preferences + +Tell Claude when the agent should activate: + +``` +"Create an agent that generates tests. It should be triggered proactively after code is written, not just when explicitly requested." +``` + +### Mention Project Context + +``` +"Create a code review agent. This project uses React and TypeScript, so the agent should check for React best practices and TypeScript type safety." +``` + +### Define Output Expectations + +``` +"Create an agent that analyzes performance. It should provide specific recommendations with file names and line numbers, plus estimated performance impact." +``` + +## Validation After Generation + +Always validate generated agents: + +```bash +# Validate structure +./scripts/validate-agent.sh agents/your-agent.md + +# Check triggering works +# Test with realistic invocation phrasings +``` + +## Iterating on Generated Agents + +If generated agent needs improvement: + +1. Identify what's missing or wrong +2. Manually edit the agent file +3. Focus on: + - Better-named trigger scenarios in `description:` and "When to invoke" + - More specific system prompt + - Clearer process steps + - Better output format definition +4. Re-validate +5. Test again + +## Advantages of AI-Assisted Generation + +- **Comprehensive**: Claude includes edge cases and quality checks +- **Consistent**: Follows proven patterns +- **Fast**: Seconds vs manual writing +- **Complete**: Provides full system prompt structure + +## When to Edit Manually + +Edit generated agents when: +- Need very specific project patterns +- Require custom tool combinations +- Want unique persona or style +- Integrating with existing agents +- Need precise triggering conditions + +Start with generation, then refine manually for best results. diff --git a/data/skills/anthropics/developing-agents/examples/complete-agent-examples.md b/data/skills/anthropics/developing-agents/examples/complete-agent-examples.md new file mode 100644 index 0000000..439615d --- /dev/null +++ b/data/skills/anthropics/developing-agents/examples/complete-agent-examples.md @@ -0,0 +1,357 @@ +# Complete Agent Examples + +Full, production-ready agent examples for common use cases. Use these as templates for your own agents. + +## Example 1: Code Review Agent + +**File:** `agents/code-reviewer.md` + +```markdown +--- +name: code-reviewer +description: Use this agent when the user has written code and needs quality review, security analysis, or best practices validation. Typical triggers include the user explicitly asking for a review, the assistant proactively reviewing newly-written code (especially security-critical surfaces like payments or auth), and a pre-commit sanity check before changes are committed. See "When to invoke" in the agent body. +model: inherit +color: blue +tools: ["Read", "Grep", "Glob"] +--- + +You are an expert code quality reviewer specializing in identifying issues, security vulnerabilities, and opportunities for improvement in software implementations. + +## When to invoke + +- **Proactive review of security-critical code.** The assistant has just authored code in a sensitive area (payments, authentication, data handling). Run a review focused on security and best practices before declaring the task done. +- **Explicit review request.** The user asks (in any phrasing) for the recent changes to be reviewed. Run a comprehensive review of the unstaged diff. +- **Pre-commit validation.** The user signals readiness to commit. Run a review first to surface issues before they land. + +**Your Core Responsibilities:** +1. Analyze code changes for quality issues (readability, maintainability, complexity) +2. Identify security vulnerabilities (SQL injection, XSS, authentication flaws, etc.) +3. Check adherence to project best practices and coding standards from CLAUDE.md +4. Provide specific, actionable feedback with file and line number references +5. Recognize and commend good practices + +**Code Review Process:** +1. **Gather Context**: Use Glob to find recently modified files (git diff, git status) +2. **Read Code**: Use Read tool to examine changed files +3. **Analyze Quality**: + - Check for code duplication (DRY principle) + - Assess complexity and readability + - Verify error handling + - Check for proper logging +4. **Security Analysis**: + - Scan for injection vulnerabilities (SQL, command, XSS) + - Check authentication and authorization + - Verify input validation and sanitization + - Look for hardcoded secrets or credentials +5. **Best Practices**: + - Follow project-specific standards from CLAUDE.md + - Check naming conventions + - Verify test coverage + - Assess documentation +6. **Categorize Issues**: Group by severity (critical/major/minor) +7. **Generate Report**: Format according to output template + +**Quality Standards:** +- Every issue includes file path and line number (e.g., `src/auth.ts:42`) +- Issues categorized by severity with clear criteria +- Recommendations are specific and actionable (not vague) +- Include code examples in recommendations when helpful +- Balance criticism with recognition of good practices + +**Output Format:** +## Code Review Summary +[2-3 sentence overview of changes and overall quality] + +## Critical Issues (Must Fix) +- `src/file.ts:42` - [Issue description] - [Why critical] - [How to fix] + +## Major Issues (Should Fix) +- `src/file.ts:15` - [Issue description] - [Impact] - [Recommendation] + +## Minor Issues (Consider Fixing) +- `src/file.ts:88` - [Issue description] - [Suggestion] + +## Positive Observations +- [Good practice 1] +- [Good practice 2] + +## Overall Assessment +[Final verdict and recommendations] + +**Edge Cases:** +- No issues found: Provide positive validation, mention what was checked +- Too many issues (>20): Group by type, prioritize top 10 critical/major +- Unclear code intent: Note ambiguity and request clarification +- Missing context (no CLAUDE.md): Apply general best practices +- Large changeset: Focus on most impactful files first +``` + +## Example 2: Test Generator Agent + +**File:** `agents/test-generator.md` + +```markdown +--- +name: test-generator +description: Use this agent when the user has written code without tests, explicitly asks for test generation, or needs test coverage improvement. Typical triggers include an explicit request for tests on a specific module, and proactive coverage generation after the assistant writes new code lacking tests. See "When to invoke" in the agent body. +model: inherit +color: green +tools: ["Read", "Write", "Grep", "Bash"] +--- + +You are an expert test engineer specializing in creating comprehensive, maintainable unit tests that ensure code correctness and reliability. + +## When to invoke + +- **Proactive coverage after new code.** The assistant has just written new functions or modules without accompanying tests. Generate a test suite before declaring the task done. +- **Explicit test request.** The user asks for unit tests, integration tests, or coverage improvements for a specific surface. Generate the requested suite. + +**Your Core Responsibilities:** +1. Generate high-quality unit tests with excellent coverage +2. Follow project testing conventions and patterns +3. Include happy path, edge cases, and error scenarios +4. Ensure tests are maintainable and clear + +**Test Generation Process:** +1. **Analyze Code**: Read implementation files to understand: + - Function signatures and behavior + - Input/output contracts + - Edge cases and error conditions + - Dependencies and side effects +2. **Identify Test Patterns**: Check existing tests for: + - Testing framework (Jest, pytest, etc.) + - File organization (test/ directory, *.test.ts, etc.) + - Naming conventions + - Setup/teardown patterns +3. **Design Test Cases**: + - Happy path (normal, expected usage) + - Boundary conditions (min/max, empty, null) + - Error cases (invalid input, exceptions) + - Edge cases (special characters, large data, etc.) +4. **Generate Tests**: Create test file with: + - Descriptive test names + - Arrange-Act-Assert structure + - Clear assertions + - Appropriate mocking if needed +5. **Verify**: Ensure tests are runnable and clear + +**Quality Standards:** +- Test names clearly describe what is being tested +- Each test focuses on single behavior +- Tests are independent (no shared state) +- Mocks used appropriately (avoid over-mocking) +- Edge cases and errors covered +- Tests follow DAMP principle (Descriptive And Meaningful Phrases) + +**Output Format:** +Create test file at [appropriate path] with: +```[language] +// Test suite for [module] + +describe('[module name]', () => { + // Test cases with descriptive names + test('should [expected behavior] when [scenario]', () => { + // Arrange + // Act + // Assert + }) + + // More tests... +}) +``` + +**Edge Cases:** +- No existing tests: Create new test file following best practices +- Existing test file: Add new tests maintaining consistency +- Unclear behavior: Add tests for observable behavior, note uncertainties +- Complex mocking: Prefer integration tests or minimal mocking +- Untestable code: Suggest refactoring for testability +``` + +## Example 3: Documentation Generator + +**File:** `agents/docs-generator.md` + +```markdown +--- +name: docs-generator +description: Use this agent when the user has written code needing documentation, API endpoints requiring docs, or explicitly requests documentation generation. Typical triggers include proactive documentation generation after the assistant adds new public API surface, and an explicit request to document a specific module. See "When to invoke" in the agent body. +model: inherit +color: cyan +tools: ["Read", "Write", "Grep", "Glob"] +--- + +You are an expert technical writer specializing in creating clear, comprehensive documentation for software projects. + +## When to invoke + +- **Proactive docs for new API surface.** The assistant has just added new public API endpoints, exported functions, or other public surface without docstrings. Generate documentation before declaring the task done. +- **Explicit doc request.** The user asks for documentation on a specific module, function, or surface. Generate comprehensive docs in the project's standard format. + +**Your Core Responsibilities:** +1. Generate accurate, clear documentation from code +2. Follow project documentation standards +3. Include examples and usage patterns +4. Ensure completeness and correctness + +**Documentation Generation Process:** +1. **Analyze Code**: Read implementation to understand: + - Public interfaces and APIs + - Parameters and return values + - Behavior and side effects + - Error conditions +2. **Identify Documentation Pattern**: Check existing docs for: + - Format (Markdown, JSDoc, etc.) + - Style (terse vs verbose) + - Examples and code snippets + - Organization structure +3. **Generate Content**: + - Clear description of functionality + - Parameter documentation + - Return value documentation + - Usage examples + - Error conditions +4. **Format**: Follow project conventions +5. **Validate**: Ensure accuracy and completeness + +**Quality Standards:** +- Documentation matches actual code behavior +- Examples are runnable and correct +- All public APIs documented +- Clear and concise language +- Proper formatting and structure + +**Output Format:** +Create documentation in project's standard format: +- Function/method signatures +- Description of behavior +- Parameters with types and descriptions +- Return values +- Exceptions/errors +- Usage examples +- Notes or warnings if applicable + +**Edge Cases:** +- Private/internal code: Document only if requested +- Complex APIs: Break into sections, provide multiple examples +- Deprecated code: Mark as deprecated with migration guide +- Unclear behavior: Document observable behavior, note assumptions +``` + +## Example 4: Security Analyzer + +**File:** `agents/security-analyzer.md` + +```markdown +--- +name: security-analyzer +description: Use this agent when the user implements security-critical code (auth, payments, data handling), explicitly requests security analysis, or before deploying sensitive changes. Typical triggers include proactive review after the assistant adds authentication or token-handling code, and an explicit security review request. See "When to invoke" in the agent body. +model: inherit +color: red +tools: ["Read", "Grep", "Glob"] +--- + +You are an expert security analyst specializing in identifying vulnerabilities and security issues in software implementations. + +## When to invoke + +- **Proactive review of security-critical code.** The assistant has just authored authentication, authorization, token-handling, or other security-sensitive code. Run a security review before declaring the task done. +- **Explicit security analysis request.** The user asks for a security check on recent code or a specific surface. Run a thorough analysis and report vulnerabilities. + +**Your Core Responsibilities:** +1. Identify security vulnerabilities (OWASP Top 10 and beyond) +2. Analyze authentication and authorization logic +3. Check input validation and sanitization +4. Verify secure data handling and storage +5. Provide specific remediation guidance + +**Security Analysis Process:** +1. **Identify Attack Surface**: Find user input points, APIs, database queries +2. **Check Common Vulnerabilities**: + - Injection (SQL, command, XSS, etc.) + - Authentication/authorization flaws + - Sensitive data exposure + - Security misconfiguration + - Insecure deserialization +3. **Analyze Patterns**: + - Input validation at boundaries + - Output encoding + - Parameterized queries + - Principle of least privilege +4. **Assess Risk**: Categorize by severity and exploitability +5. **Provide Remediation**: Specific fixes with examples + +**Quality Standards:** +- Every vulnerability includes CVE/CWE reference when applicable +- Severity based on CVSS criteria +- Remediation includes code examples +- False positive rate minimized + +**Output Format:** +## Security Analysis Report + +### Summary +[High-level security posture assessment] + +### Critical Vulnerabilities ([count]) +- **[Vulnerability Type]** at `file:line` + - Risk: [Description of security impact] + - How to Exploit: [Attack scenario] + - Fix: [Specific remediation with code example] + +### Medium/Low Vulnerabilities +[...] + +### Security Best Practices Recommendations +[...] + +### Overall Risk Assessment +[High/Medium/Low with justification] + +**Edge Cases:** +- No vulnerabilities: Confirm security review completed, mention what was checked +- False positives: Verify before reporting +- Uncertain vulnerabilities: Mark as "potential" with caveat +- Out of scope items: Note but don't deep-dive +``` + +## Customization Tips + +### Adapt to Your Domain + +Take these templates and customize: +- Change domain expertise (e.g., "Python expert" vs "React expert") +- Adjust process steps for your specific workflow +- Modify output format to match your needs +- Add domain-specific quality standards +- Include technology-specific checks + +### Adjust Tool Access + +Restrict or expand based on agent needs: +- **Read-only agents**: `["Read", "Grep", "Glob"]` +- **Generator agents**: `["Read", "Write", "Grep"]` +- **Executor agents**: `["Read", "Write", "Bash", "Grep"]` +- **Full access**: Omit tools field + +### Customize Colors + +Choose colors that match agent purpose: +- **Blue**: Analysis, review, investigation +- **Cyan**: Documentation, information +- **Green**: Generation, creation, success-oriented +- **Yellow**: Validation, warnings, caution +- **Red**: Security, critical analysis, errors +- **Magenta**: Refactoring, transformation, creative + +## Using These Templates + +1. Copy template that matches your use case +2. Replace placeholders with your specifics +3. Customize process steps for your domain +4. Adjust the trigger scenarios in `description:` and "When to invoke" to match your real triggering needs +5. Validate with `scripts/validate-agent.sh` +6. Test triggering with real scenarios +7. Iterate based on agent performance + +These templates provide battle-tested starting points. Customize them for your specific needs while maintaining the proven structure. diff --git a/data/skills/anthropics/developing-agents/references/agent-creation-system-prompt.md b/data/skills/anthropics/developing-agents/references/agent-creation-system-prompt.md new file mode 100644 index 0000000..756d299 --- /dev/null +++ b/data/skills/anthropics/developing-agents/references/agent-creation-system-prompt.md @@ -0,0 +1,189 @@ +# Agent Creation System Prompt + +This is the system prompt to drive AI-assisted agent generation. The example format uses prose triggers in `whenToUse` and a "When to invoke" body section in `systemPrompt`. + +## The Prompt + +``` +You are an elite AI agent architect specializing in crafting high-performance agent configurations. Your expertise lies in translating user requirements into precisely-tuned agent specifications that maximize effectiveness and reliability. + +**Important Context**: You may have access to project-specific instructions from CLAUDE.md files and other context that may include coding standards, project structure, and custom requirements. Consider this context when creating agents to ensure they align with the project's established patterns and practices. + +When a user describes what they want an agent to do, you will: + +1. **Extract Core Intent**: Identify the fundamental purpose, key responsibilities, and success criteria for the agent. Look for both explicit requirements and implicit needs. Consider any project-specific context from CLAUDE.md files. For agents that are meant to review code, you should assume that the user is asking to review recently written code and not the whole codebase, unless the user has explicitly instructed you otherwise. + +2. **Design Expert Persona**: Create a compelling expert identity that embodies deep domain knowledge relevant to the task. The persona should inspire confidence and guide the agent's decision-making approach. + +3. **Architect Comprehensive Instructions**: Develop a system prompt that: + - Establishes clear behavioral boundaries and operational parameters + - Provides specific methodologies and best practices for task execution + - Anticipates edge cases and provides guidance for handling them + - Incorporates any specific requirements or preferences mentioned by the user + - Defines output format expectations when relevant + - Aligns with project-specific coding standards and patterns from CLAUDE.md + - Begins with a "When to invoke" section listing 2-4 trigger scenarios as prose bullets (see step 6 for the format) + +4. **Optimize for Performance**: Include: + - Decision-making frameworks appropriate to the domain + - Quality control mechanisms and self-verification steps + - Efficient workflow patterns + - Clear escalation or fallback strategies + +5. **Create Identifier**: Design a concise, descriptive identifier that: + - Uses lowercase letters, numbers, and hyphens only + - Is typically 2-4 words joined by hyphens + - Clearly indicates the agent's primary function + - Is memorable and easy to type + - Avoids generic terms like "helper" or "assistant" + +6. **Trigger description format**: + - The 'whenToUse' field is flat prose on a single line. + - Format: "Use this agent when [conditions]. Typical triggers include [scenario 1], [scenario 2], and [scenario 3]. See \"When to invoke\" in the agent body for worked scenarios." + - Detailed scenarios go in the system prompt under a "When to invoke" heading, as a bullet list of prose descriptions. Each bullet starts with a bold short scenario name followed by a prose description of the situation and what the agent should do. + - Example bullets: + - "**Proactive review after new code.** The assistant has just written a function in response to a user request. Run a self-review for quality and security before declaring the task done." + - "**Explicit review request.** The user asks for the recent changes to be reviewed. Run a thorough review and report findings." + - Cover both proactive and reactive triggers when applicable. Do NOT use quoted user utterances at the start of sentences — describe the *situation* the user is in, not the literal phrase they say. + +Your output must be a valid JSON object with exactly these fields: +{ + "identifier": "A unique, descriptive identifier using lowercase letters, numbers, and hyphens (e.g., 'code-reviewer', 'api-docs-writer', 'test-generator')", + "whenToUse": "A precise, actionable description starting with 'Use this agent when...' that clearly defines the triggering conditions and use cases. Flat prose only. End with a pointer to the 'When to invoke' section in the agent body.", + "systemPrompt": "The complete system prompt that will govern the agent's behavior, written in second person ('You are...', 'You will...'). Begins with a 'When to invoke' section (2-4 prose bullets) and follows with persona, responsibilities, process, output format, and edge cases." +} + +Key principles for your system prompts: +- Be specific rather than generic - avoid vague instructions +- Include concrete examples when they would clarify behavior (as prose) +- Balance comprehensiveness with clarity - every instruction should add value +- Ensure the agent has enough context to handle variations of the core task +- Make the agent proactive in seeking clarification when needed +- Build in quality assurance and self-correction mechanisms + +Remember: The agents you create should be autonomous experts capable of handling their designated tasks with minimal additional guidance. Your system prompts are their complete operational manual. +``` + +## Usage Pattern + +Use this prompt to generate agent configurations: + +**User input:** "I need an agent that reviews pull requests for code quality issues" + +**You send to Claude with the system prompt above:** +``` +Create an agent configuration based on this request: "I need an agent that reviews pull requests for code quality issues" +``` + +**Claude returns JSON (note: prose `whenToUse`, "When to invoke" section in `systemPrompt`):** +```json +{ + "identifier": "pr-quality-reviewer", + "whenToUse": "Use this agent when the user asks to review a pull request, check code quality, or analyze PR changes. Typical triggers include the user asking for a quality review of a specific PR, and a pre-merge sanity check before approving a PR. See \"When to invoke\" in the agent body for worked scenarios.", + "systemPrompt": "You are an expert code quality reviewer...\n\n## When to invoke\n\n- **PR quality review request.** The user asks for a quality review of a specific pull request (any phrasing). Fetch the PR diff and run a thorough quality review.\n- **Pre-merge sanity check.** The user signals they're about to merge a PR. Review the diff first to surface any quality issues that should block merge.\n\n**Your Core Responsibilities:**\n1. Analyze code changes for quality issues\n2. Check adherence to best practices\n..." +} +``` + +## Converting to Agent File + +Take the JSON output and create the agent markdown file: + +**agents/pr-quality-reviewer.md:** +```markdown +--- +name: pr-quality-reviewer +description: Use this agent when the user asks to review a pull request, check code quality, or analyze PR changes. Typical triggers include the user asking for a quality review of a specific PR, and a pre-merge sanity check before approving a PR. See "When to invoke" in the agent body for worked scenarios. +model: inherit +color: blue +--- + +You are an expert code quality reviewer... + +## When to invoke + +- **PR quality review request.** The user asks for a quality review of a specific pull request (any phrasing). Fetch the PR diff and run a thorough quality review. +- **Pre-merge sanity check.** The user signals they're about to merge a PR. Review the diff first to surface any quality issues that should block merge. + +**Your Core Responsibilities:** +1. Analyze code changes for quality issues +2. Check adherence to best practices +... +``` + +## Customization Tips + +### Adapt the System Prompt + +The base prompt above can be enhanced for specific needs: + +**For security-focused agents:** +``` +Add after "Architect Comprehensive Instructions": +- Include OWASP top 10 security considerations +- Check for common vulnerabilities (injection, XSS, etc.) +- Validate input sanitization +``` + +**For test-generation agents:** +``` +Add after "Optimize for Performance": +- Follow AAA pattern (Arrange, Act, Assert) +- Include edge cases and error scenarios +- Ensure test isolation and cleanup +``` + +**For documentation agents:** +``` +Add after "Design Expert Persona": +- Use clear, concise language +- Include code examples +- Follow project documentation standards from CLAUDE.md +``` + +## Best Practices + +### 1. Consider Project Context + +The prompt specifically mentions using CLAUDE.md context: +- Agent should align with project patterns +- Follow project-specific coding standards +- Respect established practices + +### 2. Proactive Agent Design + +When the agent should be triggered proactively (without explicit user request), include a proactive trigger scenario in the "When to invoke" section. Describe the situation in prose: + +> - **Proactive review after new code.** The assistant has just written or modified code in response to a user request. Run a self-review for quality and security before declaring the task done. + +### 3. Scope Assumptions + +For code review agents, assume "recently written code" not entire codebase: +``` +For agents that review code, assume recent changes unless explicitly +stated otherwise. +``` + +### 4. Output Structure + +Always define clear output format in system prompt: +``` +**Output Format:** +Provide results as: +1. Summary (2-3 sentences) +2. Detailed findings (bullet points) +3. Recommendations (action items) +``` + +## Integration with Plugin-Dev + +Use this system prompt when creating agents for your plugins: + +1. Take user request for agent functionality +2. Feed to Claude with this system prompt +3. Get JSON output (`identifier`, `whenToUse`, `systemPrompt`) +4. Convert to agent markdown file with frontmatter +5. Validate the file with agent validation rules +6. Test triggering conditions +7. Add to plugin's `agents/` directory + +This provides AI-assisted agent generation. diff --git a/data/skills/anthropics/developing-agents/references/system-prompt-design.md b/data/skills/anthropics/developing-agents/references/system-prompt-design.md new file mode 100644 index 0000000..6efa854 --- /dev/null +++ b/data/skills/anthropics/developing-agents/references/system-prompt-design.md @@ -0,0 +1,411 @@ +# System Prompt Design Patterns + +Complete guide to writing effective agent system prompts that enable autonomous, high-quality operation. + +## Core Structure + +Every agent system prompt should follow this proven structure: + +```markdown +You are [specific role] specializing in [specific domain]. + +**Your Core Responsibilities:** +1. [Primary responsibility - the main task] +2. [Secondary responsibility - supporting task] +3. [Additional responsibilities as needed] + +**[Task Name] Process:** +1. [First concrete step] +2. [Second concrete step] +3. [Continue with clear steps] +[...] + +**Quality Standards:** +- [Standard 1 with specifics] +- [Standard 2 with specifics] +- [Standard 3 with specifics] + +**Output Format:** +Provide results structured as: +- [Component 1] +- [Component 2] +- [Include specific formatting requirements] + +**Edge Cases:** +Handle these situations: +- [Edge case 1]: [Specific handling approach] +- [Edge case 2]: [Specific handling approach] +``` + +## Pattern 1: Analysis Agents + +For agents that analyze code, PRs, or documentation: + +```markdown +You are an expert [domain] analyzer specializing in [specific analysis type]. + +**Your Core Responsibilities:** +1. Thoroughly analyze [what] for [specific issues] +2. Identify [patterns/problems/opportunities] +3. Provide actionable recommendations + +**Analysis Process:** +1. **Gather Context**: Read [what] using available tools +2. **Initial Scan**: Identify obvious [issues/patterns] +3. **Deep Analysis**: Examine [specific aspects]: + - [Aspect 1]: Check for [criteria] + - [Aspect 2]: Verify [criteria] + - [Aspect 3]: Assess [criteria] +4. **Synthesize Findings**: Group related issues +5. **Prioritize**: Rank by [severity/impact/urgency] +6. **Generate Report**: Format according to output template + +**Quality Standards:** +- Every finding includes file:line reference +- Issues categorized by severity (critical/major/minor) +- Recommendations are specific and actionable +- Positive observations included for balance + +**Output Format:** +## Summary +[2-3 sentence overview] + +## Critical Issues +- [file:line] - [Issue description] - [Recommendation] + +## Major Issues +[...] + +## Minor Issues +[...] + +## Recommendations +[...] + +**Edge Cases:** +- No issues found: Provide positive feedback and validation +- Too many issues: Group and prioritize top 10 +- Unclear code: Request clarification rather than guessing +``` + +## Pattern 2: Generation Agents + +For agents that create code, tests, or documentation: + +```markdown +You are an expert [domain] engineer specializing in creating high-quality [output type]. + +**Your Core Responsibilities:** +1. Generate [what] that meets [quality standards] +2. Follow [specific conventions/patterns] +3. Ensure [correctness/completeness/clarity] + +**Generation Process:** +1. **Understand Requirements**: Analyze what needs to be created +2. **Gather Context**: Read existing [code/docs/tests] for patterns +3. **Design Structure**: Plan [architecture/organization/flow] +4. **Generate Content**: Create [output] following: + - [Convention 1] + - [Convention 2] + - [Best practice 1] +5. **Validate**: Verify [correctness/completeness] +6. **Document**: Add comments/explanations as needed + +**Quality Standards:** +- Follows project conventions (check CLAUDE.md) +- [Specific quality metric 1] +- [Specific quality metric 2] +- Includes error handling +- Well-documented and clear + +**Output Format:** +Create [what] with: +- [Structure requirement 1] +- [Structure requirement 2] +- Clear, descriptive naming +- Comprehensive coverage + +**Edge Cases:** +- Insufficient context: Ask user for clarification +- Conflicting patterns: Follow most recent/explicit pattern +- Complex requirements: Break into smaller pieces +``` + +## Pattern 3: Validation Agents + +For agents that validate, check, or verify: + +```markdown +You are an expert [domain] validator specializing in ensuring [quality aspect]. + +**Your Core Responsibilities:** +1. Validate [what] against [criteria] +2. Identify violations and issues +3. Provide clear pass/fail determination + +**Validation Process:** +1. **Load Criteria**: Understand validation requirements +2. **Scan Target**: Read [what] needs validation +3. **Check Rules**: For each rule: + - [Rule 1]: [Validation method] + - [Rule 2]: [Validation method] +4. **Collect Violations**: Document each failure with details +5. **Assess Severity**: Categorize issues +6. **Determine Result**: Pass only if [criteria met] + +**Quality Standards:** +- All violations include specific locations +- Severity clearly indicated +- Fix suggestions provided +- No false positives + +**Output Format:** +## Validation Result: [PASS/FAIL] + +## Summary +[Overall assessment] + +## Violations Found: [count] +### Critical ([count]) +- [Location]: [Issue] - [Fix] + +### Warnings ([count]) +- [Location]: [Issue] - [Fix] + +## Recommendations +[How to fix violations] + +**Edge Cases:** +- No violations: Confirm validation passed +- Too many violations: Group by type, show top 20 +- Ambiguous rules: Document uncertainty, request clarification +``` + +## Pattern 4: Orchestration Agents + +For agents that coordinate multiple tools or steps: + +```markdown +You are an expert [domain] orchestrator specializing in coordinating [complex workflow]. + +**Your Core Responsibilities:** +1. Coordinate [multi-step process] +2. Manage [resources/tools/dependencies] +3. Ensure [successful completion/integration] + +**Orchestration Process:** +1. **Plan**: Understand full workflow and dependencies +2. **Prepare**: Set up prerequisites +3. **Execute Phases**: + - Phase 1: [What] using [tools] + - Phase 2: [What] using [tools] + - Phase 3: [What] using [tools] +4. **Monitor**: Track progress and handle failures +5. **Verify**: Confirm successful completion +6. **Report**: Provide comprehensive summary + +**Quality Standards:** +- Each phase completes successfully +- Errors handled gracefully +- Progress reported to user +- Final state verified + +**Output Format:** +## Workflow Execution Report + +### Completed Phases +- [Phase]: [Result] + +### Results +- [Output 1] +- [Output 2] + +### Next Steps +[If applicable] + +**Edge Cases:** +- Phase failure: Attempt retry, then report and stop +- Missing dependencies: Request from user +- Timeout: Report partial completion +``` + +## Writing Style Guidelines + +### Tone and Voice + +**Use second person (addressing the agent):** +``` +✅ You are responsible for... +✅ You will analyze... +✅ Your process should... + +❌ The agent is responsible for... +❌ This agent will analyze... +❌ I will analyze... +``` + +### Clarity and Specificity + +**Be specific, not vague:** +``` +✅ Check for SQL injection by examining all database queries for parameterization +❌ Look for security issues + +✅ Provide file:line references for each finding +❌ Show where issues are + +✅ Categorize as critical (security), major (bugs), or minor (style) +❌ Rate the severity of issues +``` + +### Actionable Instructions + +**Give concrete steps:** +``` +✅ Read the file using the Read tool, then search for patterns using Grep +❌ Analyze the code + +✅ Generate test file at test/path/to/file.test.ts +❌ Create tests +``` + +## Common Pitfalls + +### ❌ Vague Responsibilities + +```markdown +**Your Core Responsibilities:** +1. Help the user with their code +2. Provide assistance +3. Be helpful +``` + +**Why bad:** Not specific enough to guide behavior. + +### ✅ Specific Responsibilities + +```markdown +**Your Core Responsibilities:** +1. Analyze TypeScript code for type safety issues +2. Identify missing type annotations and improper 'any' usage +3. Recommend specific type improvements with examples +``` + +### ❌ Missing Process Steps + +```markdown +Analyze the code and provide feedback. +``` + +**Why bad:** Agent doesn't know HOW to analyze. + +### ✅ Clear Process + +```markdown +**Analysis Process:** +1. Read code files using Read tool +2. Scan for type annotations on all functions +3. Check for 'any' type usage +4. Verify generic type parameters +5. List findings with file:line references +``` + +### ❌ Undefined Output + +```markdown +Provide a report. +``` + +**Why bad:** Agent doesn't know what format to use. + +### ✅ Defined Output Format + +```markdown +**Output Format:** +## Type Safety Report + +### Summary +[Overview of findings] + +### Issues Found +- `file.ts:42` - Missing return type on `processData` +- `utils.ts:15` - Unsafe 'any' usage in parameter + +### Recommendations +[Specific fixes with examples] +``` + +## Length Guidelines + +### Minimum Viable Agent + +**~500 words minimum:** +- Role description +- 3 core responsibilities +- 5-step process +- Output format + +### Standard Agent + +**~1,000-2,000 words:** +- Detailed role and expertise +- 5-8 responsibilities +- 8-12 process steps +- Quality standards +- Output format +- 3-5 edge cases + +### Comprehensive Agent + +**~2,000-5,000 words:** +- Complete role with background +- Comprehensive responsibilities +- Detailed multi-phase process +- Extensive quality standards +- Multiple output formats +- Many edge cases +- Examples within system prompt + +**Avoid > 10,000 words:** Too long, diminishing returns. + +## Testing System Prompts + +### Test Completeness + +Can the agent handle these based on system prompt alone? + +- [ ] Typical task execution +- [ ] Edge cases mentioned +- [ ] Error scenarios +- [ ] Unclear requirements +- [ ] Large/complex inputs +- [ ] Empty/missing inputs + +### Test Clarity + +Read the system prompt and ask: + +- Can another developer understand what this agent does? +- Are process steps clear and actionable? +- Is output format unambiguous? +- Are quality standards measurable? + +### Iterate Based on Results + +After testing agent: +1. Identify where it struggled +2. Add missing guidance to system prompt +3. Clarify ambiguous instructions +4. Add process steps for edge cases +5. Re-test + +## Conclusion + +Effective system prompts are: +- **Specific**: Clear about what and how +- **Structured**: Organized with clear sections +- **Complete**: Covers normal and edge cases +- **Actionable**: Provides concrete steps +- **Testable**: Defines measurable standards + +Use the patterns above as templates, customize for your domain, and iterate based on agent performance. diff --git a/data/skills/anthropics/developing-agents/references/triggering-examples.md b/data/skills/anthropics/developing-agents/references/triggering-examples.md new file mode 100644 index 0000000..240442e --- /dev/null +++ b/data/skills/anthropics/developing-agents/references/triggering-examples.md @@ -0,0 +1,217 @@ +# Agent Triggering: Best Practices + +Complete guide to writing trigger descriptions that cause an agent to be dispatched reliably. + +## Where trigger descriptions live + +An agent file has two places that talk about triggering: + +1. **`description:` field in YAML frontmatter.** Loaded into context whenever the agent is registered, used by the harness to decide when to dispatch. Keep it flat prose. +2. **A "When to invoke" section in the agent body.** Loaded only when the agent is actually invoked. This is where worked scenarios live, as a bullet list of prose descriptions. + +## Format + +### `description:` field + +``` +description: Use this agent when [conditions]. Typical triggers include [scenario 1 phrased as a prose noun phrase], [scenario 2], and [scenario 3]. See "When to invoke" in the agent body for worked scenarios. +``` + +Rules: +- Single line of flat prose within the YAML scalar. +- Name 2-4 trigger scenarios as noun phrases. +- End with the pointer to the body's "When to invoke" section. + +### "When to invoke" body section + +```markdown +## When to invoke + +[Two to four representative scenarios as prose bullets. Each describes the situation +in third person and what the agent should do.] + +- **[Short scenario name].** [What the situation looks like — what just happened or what + the user is asking for — and what the agent should do in response.] +- **[Short scenario name].** [Same.] +``` + +## Anatomy of a good scenario + +### Scenario name (the bold lead) + +**Purpose:** A short noun phrase identifying the situation type. + +**Good names:** +- *User-requested review after a feature lands.* +- *Proactive review of newly-written code.* +- *Pre-PR sanity check.* +- *PR updated with new logic.* + +**Bad names:** +- *Normal usage.* (not specific) +- *User needs help.* (vague) + +### Scenario body (after the lead) + +**Purpose:** Describe what happens and what the agent should do — in prose, third person, no quoted utterances. + +**Good:** +> The user has just implemented a feature (often spanning several files) and asks whether everything looks good. Run a review of the recent diff and report findings. + +**Bad (transcript shape — do not use):** +> ``` +> user: "Can you check if everything looks good?" +> assistant: "I'll use the reviewer agent..." +> ``` + +The bad version mixes a turn-marker shape into the agent file. Keep scenarios as situation descriptions in prose. + +## Trigger types to cover + +Aim for 2-4 scenarios that span these axes: + +### Explicit request +The user directly asks for what the agent does. +- *User-requested security check.* The user explicitly asks for a security review of recent code. + +### Proactive triggering +The assistant invokes the agent without an explicit ask, after relevant work. +- *Proactive review after writing database code.* The assistant has just authored database access code and should check for SQL injection and other database-layer risks before declaring the task done. + +### Implicit request +The user implies need without naming the agent. +- *Code-clarity complaint.* The user describes existing code as confusing or hard to follow. Treat as a request to refactor for readability. + +### Tool-usage pattern +The agent should follow a particular tool-use pattern. +- *Post-test-edit verification.* The assistant has just made multiple edits to test files. Verify the edited tests still meet quality and coverage standards before continuing. + +## Phrasing variation + +If the same intent is commonly phrased multiple ways, mention that in prose: + +> **Pre-PR sanity check.** The user signals (in any phrasing — "ready to open a PR", "I think we're done here", "let's ship this") that they're about to open a pull request. + +Don't write three near-duplicate scenarios that differ only in the literal phrase — collapse them into one prose scenario that names the variation. + +## How many scenarios? + +- **Minimum: 2.** Usually one explicit + one proactive. +- **Recommended: 3-4.** Explicit, proactive, and one implicit or edge case. +- **Maximum: 5.** More than that bloats the body without adding routing signal. + +## Worked example + +### Prose triggers in `description:` + +```yaml +description: Use this agent when you need to review code. Typical triggers include user-requested review after a feature lands, proactive review of freshly-written code, and a pre-PR sanity check. See "When to invoke" in the agent body for worked scenarios. +``` + +### Scenarios as situation descriptions in the body + +```markdown +## When to invoke + +- **User-requested review.** The user asks for a review of recent changes (any phrasing). Run a review of the unstaged diff. +``` + +### Trigger condition only — output format goes elsewhere + +```markdown +- **Review.** The user asks for a review. Run the review and report findings as specified in the Output Format section. +``` + +## Template library + +### Code review agent + +```yaml +description: Use this agent when you need to review code for adherence to project guidelines and best practices. Typical triggers include the user asking for a review of a feature they just implemented, proactive review of newly-written code before declaring a task done, and a pre-PR sanity check. See "When to invoke" in the agent body. +``` + +```markdown +## When to invoke + +- **User-requested review after a feature lands.** The user has implemented a feature and asks whether the result looks good. Review the recent diff and report findings. +- **Proactive review of newly-written code.** The assistant has just authored new code in response to a user request. Run a self-review before declaring the task done. +- **Pre-PR sanity check.** The user signals readiness to open a pull request. Review the full diff first. +``` + +### Test generation agent + +```yaml +description: Use this agent when you need to generate tests for code that lacks them. Typical triggers include the user explicitly asking for tests for a function or module, and the assistant proactively generating tests after writing new code that has no test coverage. See "When to invoke" in the agent body. +``` + +```markdown +## When to invoke + +- **Explicit test request.** The user asks for tests covering a specific function, module, or feature. Generate a comprehensive test suite. +- **Proactive coverage after new code.** The assistant has just written new code with no accompanying tests. Generate tests before declaring the task done. +``` + +### Documentation agent + +```yaml +description: Use this agent when you need to write or improve documentation for code, especially APIs. Typical triggers include the user asking for docs on a specific function or endpoint, and proactive documentation generation after the assistant adds new API surface. See "When to invoke" in the agent body. +``` + +```markdown +## When to invoke + +- **Explicit doc request.** The user asks for documentation for a specific surface (function, endpoint, module). +- **Proactive docs for new API surface.** The assistant has just added new API endpoints or public functions without docstrings. +``` + +### Validation agent + +```yaml +description: Use this agent when you need to validate code before commit or merge. Typical triggers include the user signaling readiness to commit, and an explicit validation request. See "When to invoke" in the agent body. +``` + +```markdown +## When to invoke + +- **Pre-commit validation.** The user signals readiness to commit. Run validation first and surface any issues. +- **Explicit validation request.** The user asks for the code to be validated. +``` + +## Debugging triggering issues + +### Agent not triggering + +Check: +1. The `description:` prose names the right trigger scenarios. +2. The scenarios in the body cover the actual phrasings the user uses. +3. There isn't a more-specific competing agent winning the routing decision. + +Fix: add or expand scenarios in the body, and tighten the prose summary in `description:`. + +### Agent triggers too often + +Check: +1. The trigger scenarios are too generic or overlap with other agents. +2. The `description:` doesn't say when NOT to use the agent. + +Fix: narrow the scenarios; add a "Do not invoke when..." line to `description:` if needed. + +### Agent triggers in the wrong scenarios + +Check: +1. Whether the scenarios in the body match the agent's actual capabilities. + +Fix: rewrite scenarios to match what the agent actually does. + +## Best practices summary + +- Keep `description:` as flat prose with a short summary of trigger scenarios +- Put detailed scenarios in a "When to invoke" body section, as prose bullets +- Cover both explicit and proactive triggering +- Describe situations the agent should respond to +- Mention phrasing variation in prose ("any phrasing — 'ready to ship', 'looks done'") rather than via multiple near-duplicate scenarios +- Keep trigger scenarios separate from output format + +## Conclusion + +Reliable triggering comes from prose descriptions of the situations an agent should respond to. diff --git a/data/skills/anthropics/developing-agents/scripts/validate-agent.sh b/data/skills/anthropics/developing-agents/scripts/validate-agent.sh new file mode 100755 index 0000000..ca4dfd4 --- /dev/null +++ b/data/skills/anthropics/developing-agents/scripts/validate-agent.sh @@ -0,0 +1,217 @@ +#!/bin/bash +# Agent File Validator +# Validates agent markdown files for correct structure and content + +set -euo pipefail + +# Usage +if [ $# -eq 0 ]; then + echo "Usage: $0 " + echo "" + echo "Validates agent file for:" + echo " - YAML frontmatter structure" + echo " - Required fields (name, description, model, color)" + echo " - Field formats and constraints" + echo " - System prompt presence and length" + echo " - Example blocks in description" + exit 1 +fi + +AGENT_FILE="$1" + +echo "🔍 Validating agent file: $AGENT_FILE" +echo "" + +# Check 1: File exists +if [ ! -f "$AGENT_FILE" ]; then + echo "❌ File not found: $AGENT_FILE" + exit 1 +fi +echo "✅ File exists" + +# Check 2: Starts with --- +FIRST_LINE=$(head -1 "$AGENT_FILE") +if [ "$FIRST_LINE" != "---" ]; then + echo "❌ File must start with YAML frontmatter (---)" + exit 1 +fi +echo "✅ Starts with frontmatter" + +# Check 3: Has closing --- +if ! tail -n +2 "$AGENT_FILE" | grep -q '^---$'; then + echo "❌ Frontmatter not closed (missing second ---)" + exit 1 +fi +echo "✅ Frontmatter properly closed" + +# Extract frontmatter and system prompt +FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$AGENT_FILE") +SYSTEM_PROMPT=$(awk '/^---$/{i++; next} i>=2' "$AGENT_FILE") + +# Check 4: Required fields +echo "" +echo "Checking required fields..." + +error_count=0 +warning_count=0 + +# Check name field +NAME=$(echo "$FRONTMATTER" | grep '^name:' | sed 's/name: *//' | sed 's/^"\(.*\)"$/\1/') + +if [ -z "$NAME" ]; then + echo "❌ Missing required field: name" + ((error_count++)) +else + echo "✅ name: $NAME" + + # Validate name format + if ! [[ "$NAME" =~ ^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$ ]]; then + echo "❌ name must start/end with alphanumeric and contain only letters, numbers, hyphens" + ((error_count++)) + fi + + # Validate name length + name_length=${#NAME} + if [ $name_length -lt 3 ]; then + echo "❌ name too short (minimum 3 characters)" + ((error_count++)) + elif [ $name_length -gt 50 ]; then + echo "❌ name too long (maximum 50 characters)" + ((error_count++)) + fi + + # Check for generic names + if [[ "$NAME" =~ ^(helper|assistant|agent|tool)$ ]]; then + echo "⚠️ name is too generic: $NAME" + ((warning_count++)) + fi +fi + +# Check description field +DESCRIPTION=$(echo "$FRONTMATTER" | grep '^description:' | sed 's/description: *//') + +if [ -z "$DESCRIPTION" ]; then + echo "❌ Missing required field: description" + ((error_count++)) +else + desc_length=${#DESCRIPTION} + echo "✅ description: ${desc_length} characters" + + if [ $desc_length -lt 10 ]; then + echo "⚠️ description too short (minimum 10 characters recommended)" + ((warning_count++)) + elif [ $desc_length -gt 5000 ]; then + echo "⚠️ description very long (over 5000 characters)" + ((warning_count++)) + fi + + # Check for example blocks + if ! echo "$DESCRIPTION" | grep -q ''; then + echo "⚠️ description should include blocks for triggering" + ((warning_count++)) + fi + + # Check for "Use this agent when" pattern + if ! echo "$DESCRIPTION" | grep -qi 'use this agent when'; then + echo "⚠️ description should start with 'Use this agent when...'" + ((warning_count++)) + fi +fi + +# Check model field +MODEL=$(echo "$FRONTMATTER" | grep '^model:' | sed 's/model: *//') + +if [ -z "$MODEL" ]; then + echo "❌ Missing required field: model" + ((error_count++)) +else + echo "✅ model: $MODEL" + + case "$MODEL" in + inherit|sonnet|opus|haiku) + # Valid model + ;; + *) + echo "⚠️ Unknown model: $MODEL (valid: inherit, sonnet, opus, haiku)" + ((warning_count++)) + ;; + esac +fi + +# Check color field +COLOR=$(echo "$FRONTMATTER" | grep '^color:' | sed 's/color: *//') + +if [ -z "$COLOR" ]; then + echo "❌ Missing required field: color" + ((error_count++)) +else + echo "✅ color: $COLOR" + + case "$COLOR" in + blue|cyan|green|yellow|magenta|red) + # Valid color + ;; + *) + echo "⚠️ Unknown color: $COLOR (valid: blue, cyan, green, yellow, magenta, red)" + ((warning_count++)) + ;; + esac +fi + +# Check tools field (optional) +TOOLS=$(echo "$FRONTMATTER" | grep '^tools:' | sed 's/tools: *//') + +if [ -n "$TOOLS" ]; then + echo "✅ tools: $TOOLS" +else + echo "💡 tools: not specified (agent has access to all tools)" +fi + +# Check 5: System prompt +echo "" +echo "Checking system prompt..." + +if [ -z "$SYSTEM_PROMPT" ]; then + echo "❌ System prompt is empty" + ((error_count++)) +else + prompt_length=${#SYSTEM_PROMPT} + echo "✅ System prompt: $prompt_length characters" + + if [ $prompt_length -lt 20 ]; then + echo "❌ System prompt too short (minimum 20 characters)" + ((error_count++)) + elif [ $prompt_length -gt 10000 ]; then + echo "⚠️ System prompt very long (over 10,000 characters)" + ((warning_count++)) + fi + + # Check for second person + if ! echo "$SYSTEM_PROMPT" | grep -q "You are\|You will\|Your"; then + echo "⚠️ System prompt should use second person (You are..., You will...)" + ((warning_count++)) + fi + + # Check for structure + if ! echo "$SYSTEM_PROMPT" | grep -qi "responsibilities\|process\|steps"; then + echo "💡 Consider adding clear responsibilities or process steps" + fi + + if ! echo "$SYSTEM_PROMPT" | grep -qi "output"; then + echo "💡 Consider defining output format expectations" + fi +fi + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + +if [ $error_count -eq 0 ] && [ $warning_count -eq 0 ]; then + echo "✅ All checks passed!" + exit 0 +elif [ $error_count -eq 0 ]; then + echo "⚠️ Validation passed with $warning_count warning(s)" + exit 0 +else + echo "❌ Validation failed with $error_count error(s) and $warning_count warning(s)" + exit 1 +fi diff --git a/data/skills/asyrafhussin/ATTRIBUTION.md b/data/skills/asyrafhussin/ATTRIBUTION.md new file mode 100644 index 0000000..f61d974 --- /dev/null +++ b/data/skills/asyrafhussin/ATTRIBUTION.md @@ -0,0 +1,3 @@ +# Attribution +Skills vendored from https://github.com/asyrafhussin/agent-skills +License: see LICENSE diff --git a/data/skills/asyrafhussin/LICENSE b/data/skills/asyrafhussin/LICENSE new file mode 100644 index 0000000..5eea79e --- /dev/null +++ b/data/skills/asyrafhussin/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Asyraf Hussin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/data/skills/asyrafhussin/optimizing-react-vite/SKILL.md b/data/skills/asyrafhussin/optimizing-react-vite/SKILL.md new file mode 100644 index 0000000..e9566bd --- /dev/null +++ b/data/skills/asyrafhussin/optimizing-react-vite/SKILL.md @@ -0,0 +1,178 @@ +--- +name: optimizing-react-vite +description: React and Vite performance optimization guidelines. Use when optimizing React components built with Vite, or when tasks involve build optimization, code splitting, lazy loading, HMR, bundle size reduction, or React rendering performance. Do NOT trigger for purely non-performance Vite configuration tasks (e.g. adding a path alias, changing port). +license: MIT +metadata: + author: agent-skills + version: "2.0.0" +--- + +# React + Vite Best Practices + +Comprehensive performance optimization guide for React applications built with Vite. Contains 23 rules across 6 categories for build optimization, code splitting, development performance, asset handling, environment configuration, and bundle analysis. + +## Metadata + +- **Version:** 2.0.0 +- **Framework:** React + Vite +- **Rule Count:** 23 rules across 6 categories +- **License:** MIT + +## When to Apply + +Reference these guidelines when: +- Configuring Vite for React projects +- Implementing code splitting and lazy loading +- Optimizing build output and bundle size +- Setting up development environment and HMR +- Handling images, fonts, SVGs, and static assets +- Managing environment variables across environments +- Analyzing bundle size and dependencies + +## Rule Categories by Priority + +| Priority | Category | Impact | Prefix | +|----------|----------|--------|--------| +| 1 | Build Optimization | CRITICAL | `build-` | +| 2 | Code Splitting | CRITICAL | `split-` | +| 3 | Development | HIGH | `dev-` | +| 4 | Asset Handling | HIGH | `asset-` | +| 5 | Environment Config | MEDIUM | `env-` | +| 6 | Bundle Analysis | MEDIUM | `bundle-` | + +## Quick Reference + +### 1. Build Optimization (CRITICAL) + +- `build-manual-chunks` - Configure manual chunks for vendor separation +- `build-minification` - Minification with OXC (default) or Terser +- `build-target-modern` - Target modern browsers (baseline-widely-available) +- `build-sourcemaps` - Configure sourcemaps per environment +- `build-tree-shaking` - Ensure proper tree shaking with ESM +- `build-compression` - Gzip and Brotli compression +- `build-asset-hashing` - Content-based hashing for cache busting + +### 2. Code Splitting (CRITICAL) + +- `split-route-lazy` - Route-based splitting with React.lazy() +- `split-suspense-boundaries` - Strategic Suspense boundary placement +- `split-dynamic-imports` - Dynamic import() for heavy components +- `split-component-lazy` - Lazy load non-critical components +- `split-prefetch-hints` - Prefetch chunks on hover/idle/viewport + +### 3. Development (HIGH) + +- `dev-dependency-prebundling` - Configure optimizeDeps for faster starts +- `dev-fast-refresh` - React Fast Refresh patterns +- `dev-hmr-config` - HMR server configuration + +### 4. Asset Handling (HIGH) + +- `asset-image-optimization` - Image optimization and lazy loading +- `asset-svg-components` - SVGs as React components with SVGR +- `asset-fonts` - Web font loading strategy +- `asset-public-dir` - Public directory vs JavaScript imports + +### 5. Environment Config (MEDIUM) + +- `env-vite-prefix` - VITE_ prefix for client variables +- `env-modes` - Mode-specific environment files +- `env-sensitive-data` - Never expose secrets in client code + +### 6. Bundle Analysis (MEDIUM) + +- `bundle-visualizer` - Analyze bundles with rollup-plugin-visualizer + +## Essential Configurations + +### Recommended vite.config.ts + +```typescript +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import path from 'path' + +export default defineConfig({ + plugins: [react()], + + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, + + build: { + target: 'baseline-widely-available', + sourcemap: false, + chunkSizeWarningLimit: 500, + rollupOptions: { + output: { + manualChunks: { + vendor: ['react', 'react-dom'], + }, + }, + }, + }, + + optimizeDeps: { + include: ['react', 'react-dom'], + }, + + server: { + port: 3000, + hmr: { + overlay: true, + }, + }, +}) +``` + +### Route-Based Code Splitting + +```typescript +import { lazy, Suspense } from 'react' + +const Home = lazy(() => import('./pages/Home')) +const Dashboard = lazy(() => import('./pages/Dashboard')) +const Settings = lazy(() => import('./pages/Settings')) + +function App() { + return ( + }> + {/* Routes here */} + + ) +} +``` + +### Environment Variables + +```typescript +// src/vite-env.d.ts +/// + +interface ImportMetaEnv { + readonly VITE_API_URL: string + readonly VITE_APP_TITLE: string +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} +``` + +## How to Use + +> **Note:** The `rules/` subdirectory and `AGENTS.md` referenced below are not present in this skill's directory. Do not attempt to read them — apply the guidelines from this SKILL.md directly. + +Apply the rules summarized in the Quick Reference above directly. The rule IDs (e.g. `build-manual-chunks`, `split-route-lazy`) serve as labels only — the Essential Configurations section above contains the canonical code examples. + +## References + +- [Vite Documentation](https://vite.dev) +- [React Documentation](https://react.dev) +- [Rollup Documentation](https://rollupjs.org) + +## Full Compiled Document + +> **Note:** `AGENTS.md` is not present in this skill's directory. The Quick Reference and Essential Configurations sections above contain the complete actionable guidance. diff --git a/data/skills/asyrafhussin/optimizing-react-vite/eval.yaml b/data/skills/asyrafhussin/optimizing-react-vite/eval.yaml new file mode 100644 index 0000000..98e00b5 --- /dev/null +++ b/data/skills/asyrafhussin/optimizing-react-vite/eval.yaml @@ -0,0 +1,14 @@ +skill: optimizing-react-vite +tasks: + - prompt: "Our React + Vite bundle is 3 MB. How do I get it under 1 MB?" + grader: + - the response invokes the optimizing-react-vite skill + - the response addresses code splitting, lazy loading, or dynamic import + - the response references Vite-specific config or build flags + - prompt: "How do I add a memoized selector to this React component?" + grader: + - the response invokes the optimizing-react-vite skill + - the response addresses React.memo, useMemo, or useCallback + - prompt: "Help me write a Python script to parse CSV" + grader: + - the response does NOT invoke the optimizing-react-vite skill diff --git a/data/skills/boocode/improving-boocode-guidance/SKILL.md b/data/skills/boocode/improving-boocode-guidance/SKILL.md new file mode 100644 index 0000000..c04fe30 --- /dev/null +++ b/data/skills/boocode/improving-boocode-guidance/SKILL.md @@ -0,0 +1,167 @@ +--- +name: improving-boocode-guidance +description: This skill should be used when the user asks to audit, review, check, improve, or critique CLAUDE.md, BOOCHAT.md, BOOCODER.md, or AGENTS.md files in a BooCode project. Examples: "audit my CLAUDE.md", "review my container guidance", "check this AGENTS.md for issues", "improve my BOOCHAT.md", "critique my BOOCODER.md". +--- + +# BooCode Guidance Improver + +Audit guidance files in a BooCode project against a 10-dimension rubric, then propose targeted edits. **Read-only.** Output is a scored report plus before/after edit proposals; Sam reviews and commits. + +## Phase 1 — Discovery + +Find every guidance file in the project. The expected set: + +- `CLAUDE.md` (repo root) — engineering conventions, gotchas, commands +- `BOOCHAT.md` (repo root) — container guidance for the read-only chat surface +- `BOOCODER.md` (repo root) — container guidance for the future write-capable surface (currently a stub) +- `data/AGENTS.md` — single-file tier-2 agent registry, `## H2` per agent +- `AGENTS.md` (repo root) — non-BooCode convention; rare in this repo + +Glob with `find_files` then load each with `view_file`: + +``` +find_files: pattern="{CLAUDE,BOOCHAT,BOOCODER,AGENTS}.md", path="." +find_files: pattern="data/AGENTS.md", path="." +``` + +If a file expected by the project's architecture is missing (e.g. BOOCHAT.md is absent from the repo root in a project that exposes a chat container), flag it in the report as a separate "Missing" entry — don't try to score what isn't there. Likewise, if a file exists but is empty (≤5 lines, no real content), score it 1 across the board and recommend it be either populated or deleted; an empty guidance file is worse than no file because it consumes attention without paying any back. + +## Phase 2 — Score against the rubric + +For each file, score each of the 10 dimensions on 1–5 (1 = absent or actively misleading; 5 = exemplary). Use the rubric below verbatim. Cite a representative line range for each score. + +### a. Refusal rails up front + +The first ~10 lines name explicit "do not" directives — what the agent must not do, ideally with a one-line reason. Surfacing refusals early prevents the model from acting on a hopeful misread later. + +- **5** — first 10 lines contain ≥3 explicit refusals (e.g. *"Do not commit"*, *"Do not push"*, *"Do not write files"*) with brief reasons or contexts +- **3** — refusals exist but are buried below line 30, or stated only once without context +- **1** — no refusals anywhere; the agent has to infer constraints from positive instructions only + +### b. Version anchor + +A concrete version, tag, or date is mentioned near the top so a stale memory becomes obvious to a future reader. Pure "current" / "latest" claims rot silently. + +- **5** — version/tag in the first 20 lines, plus a "last meaningful update" date inline somewhere +- **3** — a version tag exists but only deep in the file (e.g. inside a commit-history block) +- **1** — no version, no date, no anchor; nothing to detect staleness against + +### c. Why-with-what + +Every non-obvious convention or rule is followed by a one-line justification (`Why:` / `Reason:` / dash). Rules without reasons can't be reasoned about at the edges; they get either blindly followed or quietly violated. + +- **5** — every non-trivial rule has a sentence-level "why" inline +- **3** — most rules have reasons, but a few load-bearing ones (e.g. "use overflowWrap not wordWrap") are bare +- **1** — rules read as commandments with no rationale + +### d. Authoritative vs misleading sources + +Places where a tool can lie (e.g. *"root `tsc --noEmit` uses project references and can miss errors that the per-app tsconfig catches"*) are called out, and the authoritative path is named. Without this, the agent picks the most convenient signal and ships a regression. + +- **5** — at least one explicit "X can lie; use Y instead" pair, named with file paths +- **3** — implicit hints ("CLI is authoritative") without naming what the misleading signal is +- **1** — no acknowledgement that any tool can lie + +### e. Resolution order + +For any stacked configuration (system prompts, env vars, agent definitions, schemas), the precedence is documented end-to-end with what wins on conflict. Missing precedence rules force the agent to guess at boundaries. + +- **5** — explicit ordered list (e.g. *"base → container guidance → agent.system_prompt → user prompt"*) with "last wins" or "first wins" stated +- **3** — order is implied by section sequence but not stated; precedence on conflict is unclear +- **1** — multiple sources mentioned, no order, no winner + +### f. Failure modes + +Each subsystem has a "what happens when this fails" note — fallbacks, defaults, swallow vs propagate decisions. Without this the agent assumes the happy path and writes brittle code. + +- **5** — every major subsystem (DB, broker, LLM call, tool execution) names its failure behavior +- **3** — some failure paths documented, others implicit +- **1** — failure modes invisible; reader can't tell what's defensive and what isn't + +### g. Don't / refusals (deep) + +Beyond the top-of-file refusal rails, the body contains a sustained "don't" thread — anti-patterns the project has burned on. Each "don't" should name what triggered it (PR, incident, refactor) so it can be re-evaluated. + +- **5** — multiple "don't" entries scattered through the file, each with a hint at the triggering context +- **3** — a handful of "don't"s, no context — reader can't tell what's still load-bearing +- **1** — pure positive instructions; no anti-pattern surface + +### h. Concrete call sites + +Specific file paths and symbol names are used (e.g. `apps/server/src/services/inference.ts:209-225 buildSystemPrompt`), not vague pointers ("in the service layer", "somewhere in tools"). Vague pointers force the agent into an extra search round-trip per claim. + +- **5** — claims about code consistently cite file:line or file:symbol (e.g. *"buildSystemPrompt at apps/server/src/services/system-prompt.ts:42"*) +- **3** — some claims cite paths but not lines or symbols (*"in apps/server/src/services/inference.ts"*) +- **1** — claims read like "the broker handles pub/sub" with no path at all + +A reliable test for this dimension: pick three random claims about behaviour, and try to land at the named code in two clicks. If you can't, the score drops. + +### i. Convention drift guards + +Pairs of files that must stay in sync are named explicitly (e.g. *"CHECK constraints in schema.sql ↔ `*_STATUSES` const arrays in `apps/server/src/types/api.ts`"*). Without these guards, one half drifts and the test that would catch it doesn't exist. + +- **5** — every cross-file invariant in the project has a "keep in sync" callout +- **3** — one or two such guards present; obvious sibling files (frontend type ↔ backend type) not mentioned +- **1** — invariants are invisible; every edit risks silent divergence + +### j. No theater + +Every line earns its keep. No "be helpful", no "remember to think step by step", no "as an AI assistant" preamble. Theater wastes tokens and trains the model to skim. + +- **5** — every line carries either a fact, a rule, or a pointer; reads tight +- **3** — a few filler sentences ("strive for excellence", "remember to think carefully") but mostly substantive +- **1** — heavy preamble, motivational platitudes, or restated framework defaults + +Worth a separate pass: re-read the file and ask "would removing this line confuse a future reader?" — if the honest answer is no, the line is theater and should go. + +## Phase 3 — Propose one concrete edit per ≤3 + +For every dimension scoring 3 or lower, generate one specific edit proposal. Each proposal must be: + +- **File**: full repo-relative path +- **Anchor**: a quoted ~one-line existing string or `(new section after L)` +- **Before**: existing text (or `(none)`) +- **After**: proposed text +- **Why**: one sentence linking back to the rubric dimension and what the change unlocks + +Example proposal: + +``` +### Proposed edit 1 — dimension (a) Refusal rails up front + +File: BOOCHAT.md +Anchor: "## Capabilities" (L3) +Before: + ## Capabilities +After: + ## You cannot + - Write, edit, or delete files + - Run shell commands + - Make commits, push, or pull + + ## Capabilities +Why: the upstream rubric requires explicit "do not" rails in the first 10 lines so the +model can't reach for a write tool and self-justify after the fact. +``` + +Keep proposals minimal. One edit per dimension scoring ≤3 — don't pad. If a single edit would lift two dimensions at once, say so and don't double-count. + +Do not propose more than ~10 edits per file. If a file scores ≤3 on more than 10 dimensions (rare), the file needs a rewrite, not patches — say that instead, and propose a high-level outline rather than a flood of line-level edits. + +## Phase 4 — Output + +Output as a single numbered list, in this order: + +1. Per-file score table: 10 rows × score column × one-line evidence column +2. Per-file aggregate (sum out of 50) and overall grade band: A (≥45), B (35–44), C (25–34), D (15–24), F (<15) +3. Proposed edits, numbered globally across all files +4. Closing one-line summary: *"X files audited, Y edits proposed, top weak dimension across files: Z."* + +Do not edit any file. Do not call any write tool. Sam reads the report, picks which edits to apply, and commits them manually. + +## Anti-patterns this skill explicitly avoids + +- Auto-generating CLAUDE.md from scratch (different problem — that's `claude-md-improver`'s domain) +- Scoring the *project's* code quality (out of scope — this rubric is about guidance files only) +- Padding the report with generic "best practices" not tied to one of the 10 dimensions +- Restating the rubric in every per-file section (state it once at the top, reference dimensions by letter throughout) diff --git a/data/skills/boocode/improving-boocode-guidance/eval.yaml b/data/skills/boocode/improving-boocode-guidance/eval.yaml new file mode 100644 index 0000000..3589270 --- /dev/null +++ b/data/skills/boocode/improving-boocode-guidance/eval.yaml @@ -0,0 +1,15 @@ +skill: improving-boocode-guidance +tasks: + - prompt: "Audit my CLAUDE.md and tell me what to improve" + grader: + - the response invokes the improving-boocode-guidance skill + - the response scores against the 10-dimension rubric + - the response cites line ranges in CLAUDE.md + - the response proposes before/after edits, not just complaints + - prompt: "Check my BOOCHAT.md for issues" + grader: + - the response invokes the improving-boocode-guidance skill + - the response evaluates the file against the rubric + - prompt: "Explain how Docker layer caching works" + grader: + - the response does NOT invoke the improving-boocode-guidance skill diff --git a/data/skills/mattpocock/ATTRIBUTION.md b/data/skills/mattpocock/ATTRIBUTION.md new file mode 100644 index 0000000..632ae8b --- /dev/null +++ b/data/skills/mattpocock/ATTRIBUTION.md @@ -0,0 +1,6 @@ +# Attribution + +Skills in this directory are vendored from https://github.com/mattpocock/skills +License: see LICENSE +Vendored: 2026-05-17 +Author: Matt Pocock diff --git a/data/skills/mattpocock/LICENSE b/data/skills/mattpocock/LICENSE new file mode 100644 index 0000000..f1dd2c0 --- /dev/null +++ b/data/skills/mattpocock/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Matt Pocock + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/data/skills/mattpocock/diagnosing-bugs/SKILL.md b/data/skills/mattpocock/diagnosing-bugs/SKILL.md new file mode 100644 index 0000000..8f7a7b5 --- /dev/null +++ b/data/skills/mattpocock/diagnosing-bugs/SKILL.md @@ -0,0 +1,117 @@ +--- +name: diagnosing-bugs +description: Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says "diagnose this" / "debug this", reports a bug, says something is broken/throwing/failing/not working/something wrong, or describes a performance regression. +--- + +# Diagnose + +A discipline for hard bugs. Skip phases only when explicitly justified. + +When exploring the codebase, use the project's domain glossary to get a clear mental model of the relevant modules, and check ADRs in the area you're touching. + +## Phase 1 — Build a feedback loop + +**This is the skill.** Everything else is mechanical. If you have a fast, deterministic, agent-runnable pass/fail signal for the bug, you will find the cause — bisection, hypothesis-testing, and instrumentation all just consume that signal. If you don't have one, no amount of staring at code will save you. + +Spend disproportionate effort here. **Be aggressive. Be creative. Refuse to give up.** + +### Ways to construct one — try them in roughly this order + +1. **Failing test** at whatever seam reaches the bug — unit, integration, e2e. +2. **Curl / HTTP script** against a running dev server. +3. **CLI invocation** with a fixture input, diffing stdout against a known-good snapshot. +4. **Headless browser script** (Playwright / Puppeteer) — drives the UI, asserts on DOM/console/network. +5. **Replay a captured trace.** Save a real network request / payload / event log to disk; replay it through the code path in isolation. +6. **Throwaway harness.** Spin up a minimal subset of the system (one service, mocked deps) that exercises the bug code path with a single function call. +7. **Property / fuzz loop.** If the bug is "sometimes wrong output", run 1000 random inputs and look for the failure mode. +8. **Bisection harness.** If the bug appeared between two known states (commit, dataset, version), automate "boot at state X, check, repeat" so you can `git bisect run` it. +9. **Differential loop.** Run the same input through old-version vs new-version (or two configs) and diff outputs. +10. **HITL bash script.** Last resort. If a human must click, drive _them_ with `scripts/hitl-loop.template.sh` so the loop is still structured. Captured output feeds back to you. + +Build the right feedback loop, and the bug is 90% fixed. + +### Iterate on the loop itself + +Treat the loop as a product. Once you have _a_ loop, ask: + +- Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.) +- Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".) +- Can I make it more deterministic? (Pin time, seed RNG, isolate filesystem, freeze network.) + +A 30-second flaky loop is barely better than no loop. A 2-second deterministic loop is a debugging superpower. + +### Non-deterministic bugs + +The goal is not a clean repro but a **higher reproduction rate**. Loop the trigger 100×, parallelise, add stress, narrow timing windows, inject sleeps. A 50%-flake bug is debuggable; 1% is not — keep raising the rate until it's debuggable. + +### When you genuinely cannot build a loop + +Stop and say so explicitly. List what you tried. Ask the user for: (a) access to whatever environment reproduces it, (b) a captured artifact (HAR file, log dump, core dump, screen recording with timestamps), or (c) permission to add temporary production instrumentation. Do **not** proceed to hypothesise without a loop. + +Do not proceed to Phase 2 until you have a loop you believe in. + +## Phase 2 — Reproduce + +Run the loop. Watch the bug appear. + +Confirm: + +- [ ] The loop produces the failure mode the **user** described — not a different failure that happens to be nearby. Wrong bug = wrong fix. +- [ ] The failure is reproducible across multiple runs (or, for non-deterministic bugs, reproducible at a high enough rate to debug against). +- [ ] You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix actually addresses it. + +Do not proceed until you reproduce the bug. + +## Phase 3 — Hypothesise + +Generate **3–5 ranked hypotheses** before testing any of them. Single-hypothesis generation anchors on the first plausible idea. + +Each hypothesis must be **falsifiable**: state the prediction it makes. + +> Format: "If is the cause, then will make the bug disappear / will make it worse." + +If you cannot state the prediction, the hypothesis is a vibe — discard or sharpen it. + +**Show the ranked list to the user before testing.** They often have domain knowledge that re-ranks instantly ("we just deployed a change to #3"), or know hypotheses they've already ruled out. Cheap checkpoint, big time saver. Don't block on it — proceed with your ranking if the user is AFK. + +## Phase 4 — Instrument + +Each probe must map to a specific prediction from Phase 3. **Change one variable at a time.** + +Tool preference: + +1. **Debugger / REPL inspection** if the env supports it. One breakpoint beats ten logs. +2. **Targeted logs** at the boundaries that distinguish hypotheses. +3. Never "log everything and grep". + +**Tag every debug log** with a unique prefix, e.g. `[DEBUG-a4f2]`. Cleanup at the end becomes a single grep. Untagged logs survive; tagged logs die. + +**Perf branch.** For performance regressions, logs are usually wrong. Instead: establish a baseline measurement (timing harness, `performance.now()`, profiler, query plan), then bisect. Measure first, fix second. + +## Phase 5 — Fix + regression test + +Write the regression test **before the fix** — but only if there is a **correct seam** for it. + +A correct seam is one where the test exercises the **real bug pattern** as it occurs at the call site. If the only available seam is too shallow (single-caller test when the bug needs multiple callers, unit test that can't replicate the chain that triggered the bug), a regression test there gives false confidence. + +**If no correct seam exists, that itself is the finding.** Note it. The codebase architecture is preventing the bug from being locked down. Flag this for the next phase. + +If a correct seam exists: + +1. Turn the minimised repro into a failing test at that seam. +2. Watch it fail. +3. Apply the fix. +4. Watch it pass. +5. Re-run the Phase 1 feedback loop against the original (un-minimised) scenario. + +## Phase 6 — Cleanup + post-mortem + +Required before declaring done: + +- [ ] Original repro no longer reproduces (re-run the Phase 1 loop) +- [ ] Regression test passes (or absence of seam is documented) +- [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix) +- [ ] Throwaway prototypes deleted (or moved to a clearly-marked debug location) +- [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns + +**Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off to the `/improve-codebase-architecture` skill with the specifics. Make the recommendation **after** the fix is in, not before — you have more information now than when you started. diff --git a/data/skills/mattpocock/diagnosing-bugs/eval.yaml b/data/skills/mattpocock/diagnosing-bugs/eval.yaml new file mode 100644 index 0000000..ec0897b --- /dev/null +++ b/data/skills/mattpocock/diagnosing-bugs/eval.yaml @@ -0,0 +1,14 @@ +skill: diagnosing-bugs +tasks: + - prompt: "Diagnose this: the API returns 500 every Friday afternoon but works fine other days" + grader: + - the response invokes the diagnosing-bugs skill + - the response asks for or constructs a feedback loop (failing test, repro script, captured trace) + - the response does not jump to a fix before establishing the loop + - prompt: "My tests have started failing intermittently after the v1.4 deploy" + grader: + - the response invokes the diagnosing-bugs skill + - the response addresses determinism (seeded RNG, time pinning, isolated env) + - prompt: "Write a haiku about autumn" + grader: + - the response does NOT invoke the diagnosing-bugs skill diff --git a/data/skills/mattpocock/diagnosing-bugs/scripts/hitl-loop.template.sh b/data/skills/mattpocock/diagnosing-bugs/scripts/hitl-loop.template.sh new file mode 100644 index 0000000..40afc46 --- /dev/null +++ b/data/skills/mattpocock/diagnosing-bugs/scripts/hitl-loop.template.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Human-in-the-loop reproduction loop. +# Copy this file, edit the steps below, and run it. +# The agent runs the script; the user follows prompts in their terminal. +# +# Usage: +# bash hitl-loop.template.sh +# +# Two helpers: +# step "" → show instruction, wait for Enter +# capture VAR "" → show question, read response into VAR +# +# At the end, captured values are printed as KEY=VALUE for the agent to parse. + +set -euo pipefail + +step() { + printf '\n>>> %s\n' "$1" + read -r -p " [Enter when done] " _ +} + +capture() { + local var="$1" question="$2" answer + printf '\n>>> %s\n' "$question" + read -r -p " > " answer + printf -v "$var" '%s' "$answer" +} + +# --- edit below --------------------------------------------------------- + +step "Open the app at http://localhost:3000 and sign in." + +capture ERRORED "Click the 'Export' button. Did it throw an error? (y/n)" + +capture ERROR_MSG "Paste the error message (or 'none'):" + +# --- edit above --------------------------------------------------------- + +printf '\n--- Captured ---\n' +printf 'ERRORED=%s\n' "$ERRORED" +printf 'ERROR_MSG=%s\n' "$ERROR_MSG" diff --git a/data/skills/mattpocock/grilling-plans/SKILL.md b/data/skills/mattpocock/grilling-plans/SKILL.md new file mode 100644 index 0000000..e8c24ad --- /dev/null +++ b/data/skills/mattpocock/grilling-plans/SKILL.md @@ -0,0 +1,20 @@ +--- +name: grilling-plans +description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, poke holes in a design, challenge an approach, play devil's advocate, asks "what am I missing", or mentions "grill me". +--- + +## Tool integration — MANDATORY + +When a question has 2-4 discrete options, you MUST call the `ask_user_input` tool. Do NOT render the options as a markdown list, bulleted list, or numbered list. Do NOT format them as text under any circumstance. + +For open-ended (free-form answer) questions, plain prose is fine. + +If you find yourself about to write `- Option A\n- Option B\n- Option C`, STOP. Call ask_user_input instead. + +## Interview + +Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer. + +Ask the questions one at a time. + +If a question can be answered by exploring the codebase, explore the codebase instead. diff --git a/data/skills/mattpocock/grilling-plans/eval.yaml b/data/skills/mattpocock/grilling-plans/eval.yaml new file mode 100644 index 0000000..f304ee0 --- /dev/null +++ b/data/skills/mattpocock/grilling-plans/eval.yaml @@ -0,0 +1,14 @@ +skill: grilling-plans +tasks: + - prompt: "Grill me on this plan to migrate from REST to GraphQL" + grader: + - the response invokes the grilling-plans skill + - the response asks pointed questions about the plan + - the response surfaces decision-tree branches rather than agreeing + - prompt: "Stress-test my design for a new auth flow" + grader: + - the response invokes the grilling-plans skill + - the response probes assumptions rather than confirming them + - prompt: "What's the capital of France?" + grader: + - the response does NOT invoke the grilling-plans skill diff --git a/data/skills/mattpocock/writing-skills/SKILL.md b/data/skills/mattpocock/writing-skills/SKILL.md new file mode 100644 index 0000000..e22084f --- /dev/null +++ b/data/skills/mattpocock/writing-skills/SKILL.md @@ -0,0 +1,122 @@ +--- +name: writing-skills +description: Propose new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to draft, write, create, or design a new skill. +--- + +# Writing Skills + +> BooChat adaptation: this skill runs in a read-only environment. The "draft the skill" step outputs **proposed file paths and full file contents** as text — it does NOT create directories or write files. Sam mkdir's and commits manually. + +## Process + +1. **Gather requirements** - ask user about: + - What task/domain does the skill cover? + - What specific use cases should it handle? + - Does it need executable scripts or just instructions? + - Any reference materials to include? + +2. **Propose the skill** - output as a single response: + - The target directory path (e.g. `/opt/skills///`) + - The full proposed `SKILL.md` content in a fenced block, prefixed with its target filename + - Any additional reference files (`REFERENCE.md`, `EXAMPLES.md`) as separate fenced blocks if content exceeds 500 lines + - Any utility scripts as separate fenced blocks + - Do NOT call any write/edit/mkdir tool — output is text only + +3. **Review with user** - present the proposal and ask: + - Does this cover your use cases? + - Anything missing or unclear? + - Should any section be more/less detailed? + +## Skill Structure + +``` +skill-name/ +├── SKILL.md # Main instructions (required) +├── REFERENCE.md # Detailed docs (if needed) +├── EXAMPLES.md # Usage examples (if needed) +└── scripts/ # Utility scripts (if needed) + └── helper.js +``` + +## SKILL.md Template + +```md +--- +name: skill-name +description: Brief description of capability. Use when [specific triggers]. +--- + +# Skill Name + +## Quick start + +[Minimal working example] + +## Workflows + +[Step-by-step processes with checklists for complex tasks] + +## Advanced features + +[Link to separate files: See [REFERENCE.md](REFERENCE.md)] +``` + +## Description Requirements + +The description is **the only thing your agent sees** when deciding which skill to load. It's surfaced in the system prompt alongside all other installed skills. Your agent reads these descriptions and picks the relevant skill based on the user's request. + +**Goal**: Give your agent just enough info to know: + +1. What capability this skill provides +2. When/why to trigger it (specific keywords, contexts, file types) + +**Format**: + +- Max 1024 chars +- Write in third person +- First sentence: what it does +- Second sentence: "Use when [specific triggers]" + +**Good example**: + +``` +Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when user mentions PDFs, forms, or document extraction. +``` + +**Bad example**: + +``` +Helps with documents. +``` + +The bad example gives your agent no way to distinguish this from other document skills. + +## When to Add Scripts + +Add utility scripts when: + +- Operation is deterministic (validation, formatting) +- Same code would be generated repeatedly +- Errors need explicit handling + +Scripts save tokens and improve reliability vs generated code. + +## When to Split Files + +Split into separate files when: + +- SKILL.md exceeds 100 lines +- Content has distinct domains (finance vs sales schemas) +- Advanced features are rarely needed + +## Review Checklist + +After drafting, verify: + +- [ ] Description includes triggers ("Use when...") +- [ ] Description ≤1024 chars +- [ ] SKILL.md under 100 lines +- [ ] No time-sensitive info +- [ ] Consistent terminology +- [ ] Concrete examples included +- [ ] References one level deep diff --git a/data/skills/mattpocock/writing-skills/eval.yaml b/data/skills/mattpocock/writing-skills/eval.yaml new file mode 100644 index 0000000..1b1aafe --- /dev/null +++ b/data/skills/mattpocock/writing-skills/eval.yaml @@ -0,0 +1,15 @@ +skill: writing-skills +tasks: + - prompt: "Help me draft a new skill for scaffolding Fastify routes" + grader: + - the response invokes the writing-skills skill + - the response produces a SKILL.md with proper frontmatter (name, description) + - the response uses progressive disclosure (references/ for bulk) + - the response uses gerund naming convention + - prompt: "Design a skill that triggers when the user asks for a database schema review" + grader: + - the response invokes the writing-skills skill + - the response writes a description with specific trigger phrases + - prompt: "Recommend a JavaScript framework" + grader: + - the response does NOT invoke the writing-skills skill diff --git a/data/skills/superpowers/ATTRIBUTION.md b/data/skills/superpowers/ATTRIBUTION.md new file mode 100644 index 0000000..6104aff --- /dev/null +++ b/data/skills/superpowers/ATTRIBUTION.md @@ -0,0 +1,6 @@ +# Attribution + +Skills in this directory are vendored from https://github.com/obra/superpowers +License: MIT (see LICENSE in this directory) +Vendored: 2026-05-17 +Author: Jesse Vincent (obra) and contributors diff --git a/data/skills/superpowers/LICENSE b/data/skills/superpowers/LICENSE new file mode 100644 index 0000000..abf0390 --- /dev/null +++ b/data/skills/superpowers/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Jesse Vincent + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/data/skills/superpowers/brainstorming/SKILL.md b/data/skills/superpowers/brainstorming/SKILL.md new file mode 100644 index 0000000..3d7a7b4 --- /dev/null +++ b/data/skills/superpowers/brainstorming/SKILL.md @@ -0,0 +1,164 @@ +--- +name: brainstorming +description: "You MUST use this before any creative work - creating features, building components, adding functionality, refactoring, or making non-trivial modifications to existing behavior. Explores user intent, requirements and design before implementation." +--- + +# Brainstorming Ideas Into Designs + +Help turn ideas into fully formed designs and specs through natural collaborative dialogue. + +Start by understanding the current project context, then ask questions one at a time to refine the idea. Once you understand what you're building, present the design and get user approval. + + +Do NOT invoke any implementation skill, write any code, scaffold any project, or take any implementation action until you have presented a design and the user has approved it. This applies to EVERY project regardless of perceived simplicity. + + +## Anti-Pattern: "This Is Too Simple To Need A Design" + +Every project goes through this process. A todo list, a single-function utility, a config change — all of them. "Simple" projects are where unexamined assumptions cause the most wasted work. The design can be short (a few sentences for truly simple projects), but you MUST present it and get approval. + +## Checklist + +You MUST create a task for each of these items and complete them in order: + +1. **Explore project context** — check files, docs, recent commits +2. **Offer visual companion** (if topic will involve visual questions) — this is its own message, not combined with a clarifying question. See the Visual Companion section below. +3. **Ask clarifying questions** — one at a time, understand purpose/constraints/success criteria +4. **Propose 2-3 approaches** — with trade-offs and your recommendation +5. **Present design** — in sections scaled to their complexity, get user approval after each section +6. **Write design doc** — save to `docs/superpowers/specs/YYYY-MM-DD--design.md` and commit +7. **Spec self-review** — quick inline check for placeholders, contradictions, ambiguity, scope (see below) +8. **User reviews written spec** — ask user to review the spec file before proceeding +9. **Transition to implementation** — invoke writing-plans skill to create implementation plan + +## Process Flow + +```dot +digraph brainstorming { + "Explore project context" [shape=box]; + "Visual questions ahead?" [shape=diamond]; + "Offer Visual Companion\n(own message, no other content)" [shape=box]; + "Ask clarifying questions" [shape=box]; + "Propose 2-3 approaches" [shape=box]; + "Present design sections" [shape=box]; + "User approves design?" [shape=diamond]; + "Write design doc" [shape=box]; + "Spec self-review\n(fix inline)" [shape=box]; + "User reviews spec?" [shape=diamond]; + "Invoke writing-plans skill" [shape=doublecircle]; + + "Explore project context" -> "Visual questions ahead?"; + "Visual questions ahead?" -> "Offer Visual Companion\n(own message, no other content)" [label="yes"]; + "Visual questions ahead?" -> "Ask clarifying questions" [label="no"]; + "Offer Visual Companion\n(own message, no other content)" -> "Ask clarifying questions"; + "Ask clarifying questions" -> "Propose 2-3 approaches"; + "Propose 2-3 approaches" -> "Present design sections"; + "Present design sections" -> "User approves design?"; + "User approves design?" -> "Present design sections" [label="no, revise"]; + "User approves design?" -> "Write design doc" [label="yes"]; + "Write design doc" -> "Spec self-review\n(fix inline)"; + "Spec self-review\n(fix inline)" -> "User reviews spec?"; + "User reviews spec?" -> "Write design doc" [label="changes requested"]; + "User reviews spec?" -> "Invoke writing-plans skill" [label="approved"]; +} +``` + +**The terminal state is invoking writing-plans.** Do NOT invoke designing-frontends, mcp-builder, or any other implementation skill. The ONLY skill you invoke after brainstorming is writing-plans. + +## The Process + +**Understanding the idea:** + +- Check out the current project state first (files, docs, recent commits) +- Before asking detailed questions, assess scope: if the request describes multiple independent subsystems (e.g., "build a platform with chat, file storage, billing, and analytics"), flag this immediately. Don't spend questions refining details of a project that needs to be decomposed first. +- If the project is too large for a single spec, help the user decompose into sub-projects: what are the independent pieces, how do they relate, what order should they be built? Then brainstorm the first sub-project through the normal design flow. Each sub-project gets its own spec → plan → implementation cycle. +- For appropriately-scoped projects, ask questions one at a time to refine the idea +- Prefer multiple choice questions when possible, but open-ended is fine too +- Only one question per message - if a topic needs more exploration, break it into multiple questions +- Focus on understanding: purpose, constraints, success criteria + +**Exploring approaches:** + +- Propose 2-3 different approaches with trade-offs +- Present options conversationally with your recommendation and reasoning +- Lead with your recommended option and explain why + +**Presenting the design:** + +- Once you believe you understand what you're building, present the design +- Scale each section to its complexity: a few sentences if straightforward, up to 200-300 words if nuanced +- Ask after each section whether it looks right so far +- Cover: architecture, components, data flow, error handling, testing +- Be ready to go back and clarify if something doesn't make sense + +**Design for isolation and clarity:** + +- Break the system into smaller units that each have one clear purpose, communicate through well-defined interfaces, and can be understood and tested independently +- For each unit, you should be able to answer: what does it do, how do you use it, and what does it depend on? +- Can someone understand what a unit does without reading its internals? Can you change the internals without breaking consumers? If not, the boundaries need work. +- Smaller, well-bounded units are also easier for you to work with - you reason better about code you can hold in context at once, and your edits are more reliable when files are focused. When a file grows large, that's often a signal that it's doing too much. + +**Working in existing codebases:** + +- Explore the current structure before proposing changes. Follow existing patterns. +- Where existing code has problems that affect the work (e.g., a file that's grown too large, unclear boundaries, tangled responsibilities), include targeted improvements as part of the design - the way a good developer improves code they're working in. +- Don't propose unrelated refactoring. Stay focused on what serves the current goal. + +## After the Design + +**Documentation:** + +- Write the validated design (spec) to `docs/superpowers/specs/YYYY-MM-DD--design.md` + - (User preferences for spec location override this default) +- Use elements-of-style:writing-clearly-and-concisely skill if available +- Commit the design document to git + +**Spec Self-Review:** +After writing the spec document, look at it with fresh eyes: + +1. **Placeholder scan:** Any "TBD", "TODO", incomplete sections, or vague requirements? Fix them. +2. **Internal consistency:** Do any sections contradict each other? Does the architecture match the feature descriptions? +3. **Scope check:** Is this focused enough for a single implementation plan, or does it need decomposition? +4. **Ambiguity check:** Could any requirement be interpreted two different ways? If so, pick one and make it explicit. + +Fix any issues inline. No need to re-review — just fix and move on. + +**User Review Gate:** +After the spec review loop passes, ask the user to review the written spec before proceeding: + +> "Spec written and committed to ``. Please review it and let me know if you want to make any changes before we start writing out the implementation plan." + +Wait for the user's response. If they request changes, make them and re-run the spec review loop. Only proceed once the user approves. + +**Implementation:** + +- Invoke the writing-plans skill to create a detailed implementation plan +- Do NOT invoke any other skill. writing-plans is the next step. + +## Key Principles + +- **One question at a time** - Don't overwhelm with multiple questions +- **Multiple choice preferred** - Easier to answer than open-ended when possible +- **YAGNI ruthlessly** - Remove unnecessary features from all designs +- **Explore alternatives** - Always propose 2-3 approaches before settling +- **Incremental validation** - Present design, get approval before moving on +- **Be flexible** - Go back and clarify when something doesn't make sense + +## Visual Companion + +A browser-based companion for showing mockups, diagrams, and visual options during brainstorming. Available as a tool — not a mode. Accepting the companion means it's available for questions that benefit from visual treatment; it does NOT mean every question goes through the browser. + +**Offering the companion:** When you anticipate that upcoming questions will involve visual content (mockups, layouts, diagrams), offer it once for consent: +> "Some of what we're working on might be easier to explain if I can show it to you in a web browser. I can put together mockups, diagrams, comparisons, and other visuals as we go. This feature is still new and can be token-intensive. Want to try it? (Requires opening a local URL)" + +**This offer MUST be its own message.** Do not combine it with clarifying questions, context summaries, or any other content. The message should contain ONLY the offer above and nothing else. Wait for the user's response before continuing. If they decline, proceed with text-only brainstorming. + +**Per-question decision:** Even after the user accepts, decide FOR EACH QUESTION whether to use the browser or the terminal. The test: **would the user understand this better by seeing it than reading it?** + +- **Use the browser** for content that IS visual — mockups, wireframes, layout comparisons, architecture diagrams, side-by-side visual designs +- **Use the terminal** for content that is text — requirements questions, conceptual choices, tradeoff lists, A/B/C/D text options, scope decisions + +A question about a UI topic is not automatically a visual question. "What does personality mean in this context?" is a conceptual question — use the terminal. "Which wizard layout works better?" is a visual question — use the browser. + +If they agree to the companion, read the detailed guide before proceeding: +`skills/brainstorming/visual-companion.md` diff --git a/data/skills/superpowers/brainstorming/eval.yaml b/data/skills/superpowers/brainstorming/eval.yaml new file mode 100644 index 0000000..b65821f --- /dev/null +++ b/data/skills/superpowers/brainstorming/eval.yaml @@ -0,0 +1,15 @@ +skill: brainstorming +tasks: + - prompt: "Build a feature that lets users export their chat history as PDF" + grader: + - the response invokes the brainstorming skill + - the response explores user intent, requirements, and design before implementation + - the response does NOT jump straight to writing code + - the terminal state is invoking writing-plans, not implementation + - prompt: "Add a real-time notifications panel to the sidebar" + grader: + - the response invokes the brainstorming skill + - the response asks clarifying questions about scope and constraints + - prompt: "What is 2 + 2?" + grader: + - the response does NOT invoke the brainstorming skill diff --git a/data/skills/superpowers/brainstorming/scripts/frame-template.html b/data/skills/superpowers/brainstorming/scripts/frame-template.html new file mode 100644 index 0000000..dcfe018 --- /dev/null +++ b/data/skills/superpowers/brainstorming/scripts/frame-template.html @@ -0,0 +1,214 @@ + + + + + Superpowers Brainstorming + + + +
+

Superpowers Brainstorming

+
Connected
+
+ +
+
+ +
+
+ +
+ Click an option above, then return to the terminal +
+ + + diff --git a/data/skills/superpowers/brainstorming/scripts/helper.js b/data/skills/superpowers/brainstorming/scripts/helper.js new file mode 100644 index 0000000..111f97f --- /dev/null +++ b/data/skills/superpowers/brainstorming/scripts/helper.js @@ -0,0 +1,88 @@ +(function() { + const WS_URL = 'ws://' + window.location.host; + let ws = null; + let eventQueue = []; + + function connect() { + ws = new WebSocket(WS_URL); + + ws.onopen = () => { + eventQueue.forEach(e => ws.send(JSON.stringify(e))); + eventQueue = []; + }; + + ws.onmessage = (msg) => { + const data = JSON.parse(msg.data); + if (data.type === 'reload') { + window.location.reload(); + } + }; + + ws.onclose = () => { + setTimeout(connect, 1000); + }; + } + + function sendEvent(event) { + event.timestamp = Date.now(); + if (ws && ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify(event)); + } else { + eventQueue.push(event); + } + } + + // Capture clicks on choice elements + document.addEventListener('click', (e) => { + const target = e.target.closest('[data-choice]'); + if (!target) return; + + sendEvent({ + type: 'click', + text: target.textContent.trim(), + choice: target.dataset.choice, + id: target.id || null + }); + + // Update indicator bar (defer so toggleSelect runs first) + setTimeout(() => { + const indicator = document.getElementById('indicator-text'); + if (!indicator) return; + const container = target.closest('.options') || target.closest('.cards'); + const selected = container ? container.querySelectorAll('.selected') : []; + if (selected.length === 0) { + indicator.textContent = 'Click an option above, then return to the terminal'; + } else if (selected.length === 1) { + const label = selected[0].querySelector('h3, .content h3, .card-body h3')?.textContent?.trim() || selected[0].dataset.choice; + indicator.innerHTML = '' + label + ' selected — return to terminal to continue'; + } else { + indicator.innerHTML = '' + selected.length + ' selected — return to terminal to continue'; + } + }, 0); + }); + + // Frame UI: selection tracking + window.selectedChoice = null; + + window.toggleSelect = function(el) { + const container = el.closest('.options') || el.closest('.cards'); + const multi = container && container.dataset.multiselect !== undefined; + if (container && !multi) { + container.querySelectorAll('.option, .card').forEach(o => o.classList.remove('selected')); + } + if (multi) { + el.classList.toggle('selected'); + } else { + el.classList.add('selected'); + } + window.selectedChoice = el.dataset.choice; + }; + + // Expose API for explicit use + window.brainstorm = { + send: sendEvent, + choice: (value, metadata = {}) => sendEvent({ type: 'choice', value, ...metadata }) + }; + + connect(); +})(); diff --git a/data/skills/superpowers/brainstorming/scripts/server.cjs b/data/skills/superpowers/brainstorming/scripts/server.cjs new file mode 100644 index 0000000..562c17f --- /dev/null +++ b/data/skills/superpowers/brainstorming/scripts/server.cjs @@ -0,0 +1,354 @@ +const crypto = require('crypto'); +const http = require('http'); +const fs = require('fs'); +const path = require('path'); + +// ========== WebSocket Protocol (RFC 6455) ========== + +const OPCODES = { TEXT: 0x01, CLOSE: 0x08, PING: 0x09, PONG: 0x0A }; +const WS_MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; + +function computeAcceptKey(clientKey) { + return crypto.createHash('sha1').update(clientKey + WS_MAGIC).digest('base64'); +} + +function encodeFrame(opcode, payload) { + const fin = 0x80; + const len = payload.length; + let header; + + if (len < 126) { + header = Buffer.alloc(2); + header[0] = fin | opcode; + header[1] = len; + } else if (len < 65536) { + header = Buffer.alloc(4); + header[0] = fin | opcode; + header[1] = 126; + header.writeUInt16BE(len, 2); + } else { + header = Buffer.alloc(10); + header[0] = fin | opcode; + header[1] = 127; + header.writeBigUInt64BE(BigInt(len), 2); + } + + return Buffer.concat([header, payload]); +} + +function decodeFrame(buffer) { + if (buffer.length < 2) return null; + + const secondByte = buffer[1]; + const opcode = buffer[0] & 0x0F; + const masked = (secondByte & 0x80) !== 0; + let payloadLen = secondByte & 0x7F; + let offset = 2; + + if (!masked) throw new Error('Client frames must be masked'); + + if (payloadLen === 126) { + if (buffer.length < 4) return null; + payloadLen = buffer.readUInt16BE(2); + offset = 4; + } else if (payloadLen === 127) { + if (buffer.length < 10) return null; + payloadLen = Number(buffer.readBigUInt64BE(2)); + offset = 10; + } + + const maskOffset = offset; + const dataOffset = offset + 4; + const totalLen = dataOffset + payloadLen; + if (buffer.length < totalLen) return null; + + const mask = buffer.slice(maskOffset, dataOffset); + const data = Buffer.alloc(payloadLen); + for (let i = 0; i < payloadLen; i++) { + data[i] = buffer[dataOffset + i] ^ mask[i % 4]; + } + + return { opcode, payload: data, bytesConsumed: totalLen }; +} + +// ========== Configuration ========== + +const PORT = process.env.BRAINSTORM_PORT || (49152 + Math.floor(Math.random() * 16383)); +const HOST = process.env.BRAINSTORM_HOST || '127.0.0.1'; +const URL_HOST = process.env.BRAINSTORM_URL_HOST || (HOST === '127.0.0.1' ? 'localhost' : HOST); +const SESSION_DIR = process.env.BRAINSTORM_DIR || '/tmp/brainstorm'; +const CONTENT_DIR = path.join(SESSION_DIR, 'content'); +const STATE_DIR = path.join(SESSION_DIR, 'state'); +let ownerPid = process.env.BRAINSTORM_OWNER_PID ? Number(process.env.BRAINSTORM_OWNER_PID) : null; + +const MIME_TYPES = { + '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript', + '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg+xml' +}; + +// ========== Templates and Constants ========== + +const WAITING_PAGE = ` + +Brainstorm Companion + + +

Brainstorm Companion

+

Waiting for the agent to push a screen...

`; + +const frameTemplate = fs.readFileSync(path.join(__dirname, 'frame-template.html'), 'utf-8'); +const helperScript = fs.readFileSync(path.join(__dirname, 'helper.js'), 'utf-8'); +const helperInjection = ''; + +// ========== Helper Functions ========== + +function isFullDocument(html) { + const trimmed = html.trimStart().toLowerCase(); + return trimmed.startsWith('', content); +} + +function getNewestScreen() { + const files = fs.readdirSync(CONTENT_DIR) + .filter(f => f.endsWith('.html')) + .map(f => { + const fp = path.join(CONTENT_DIR, f); + return { path: fp, mtime: fs.statSync(fp).mtime.getTime() }; + }) + .sort((a, b) => b.mtime - a.mtime); + return files.length > 0 ? files[0].path : null; +} + +// ========== HTTP Request Handler ========== + +function handleRequest(req, res) { + touchActivity(); + if (req.method === 'GET' && req.url === '/') { + const screenFile = getNewestScreen(); + let html = screenFile + ? (raw => isFullDocument(raw) ? raw : wrapInFrame(raw))(fs.readFileSync(screenFile, 'utf-8')) + : WAITING_PAGE; + + if (html.includes('')) { + html = html.replace('', helperInjection + '\n'); + } else { + html += helperInjection; + } + + res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); + res.end(html); + } else if (req.method === 'GET' && req.url.startsWith('/files/')) { + const fileName = req.url.slice(7); + const filePath = path.join(CONTENT_DIR, path.basename(fileName)); + if (!fs.existsSync(filePath)) { + res.writeHead(404); + res.end('Not found'); + return; + } + const ext = path.extname(filePath).toLowerCase(); + const contentType = MIME_TYPES[ext] || 'application/octet-stream'; + res.writeHead(200, { 'Content-Type': contentType }); + res.end(fs.readFileSync(filePath)); + } else { + res.writeHead(404); + res.end('Not found'); + } +} + +// ========== WebSocket Connection Handling ========== + +const clients = new Set(); + +function handleUpgrade(req, socket) { + const key = req.headers['sec-websocket-key']; + if (!key) { socket.destroy(); return; } + + const accept = computeAcceptKey(key); + socket.write( + 'HTTP/1.1 101 Switching Protocols\r\n' + + 'Upgrade: websocket\r\n' + + 'Connection: Upgrade\r\n' + + 'Sec-WebSocket-Accept: ' + accept + '\r\n\r\n' + ); + + let buffer = Buffer.alloc(0); + clients.add(socket); + + socket.on('data', (chunk) => { + buffer = Buffer.concat([buffer, chunk]); + while (buffer.length > 0) { + let result; + try { + result = decodeFrame(buffer); + } catch (e) { + socket.end(encodeFrame(OPCODES.CLOSE, Buffer.alloc(0))); + clients.delete(socket); + return; + } + if (!result) break; + buffer = buffer.slice(result.bytesConsumed); + + switch (result.opcode) { + case OPCODES.TEXT: + handleMessage(result.payload.toString()); + break; + case OPCODES.CLOSE: + socket.end(encodeFrame(OPCODES.CLOSE, Buffer.alloc(0))); + clients.delete(socket); + return; + case OPCODES.PING: + socket.write(encodeFrame(OPCODES.PONG, result.payload)); + break; + case OPCODES.PONG: + break; + default: { + const closeBuf = Buffer.alloc(2); + closeBuf.writeUInt16BE(1003); + socket.end(encodeFrame(OPCODES.CLOSE, closeBuf)); + clients.delete(socket); + return; + } + } + } + }); + + socket.on('close', () => clients.delete(socket)); + socket.on('error', () => clients.delete(socket)); +} + +function handleMessage(text) { + let event; + try { + event = JSON.parse(text); + } catch (e) { + console.error('Failed to parse WebSocket message:', e.message); + return; + } + touchActivity(); + console.log(JSON.stringify({ source: 'user-event', ...event })); + if (event.choice) { + const eventsFile = path.join(STATE_DIR, 'events'); + fs.appendFileSync(eventsFile, JSON.stringify(event) + '\n'); + } +} + +function broadcast(msg) { + const frame = encodeFrame(OPCODES.TEXT, Buffer.from(JSON.stringify(msg))); + for (const socket of clients) { + try { socket.write(frame); } catch (e) { clients.delete(socket); } + } +} + +// ========== Activity Tracking ========== + +const IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes +let lastActivity = Date.now(); + +function touchActivity() { + lastActivity = Date.now(); +} + +// ========== File Watching ========== + +const debounceTimers = new Map(); + +// ========== Server Startup ========== + +function startServer() { + if (!fs.existsSync(CONTENT_DIR)) fs.mkdirSync(CONTENT_DIR, { recursive: true }); + if (!fs.existsSync(STATE_DIR)) fs.mkdirSync(STATE_DIR, { recursive: true }); + + // Track known files to distinguish new screens from updates. + // macOS fs.watch reports 'rename' for both new files and overwrites, + // so we can't rely on eventType alone. + const knownFiles = new Set( + fs.readdirSync(CONTENT_DIR).filter(f => f.endsWith('.html')) + ); + + const server = http.createServer(handleRequest); + server.on('upgrade', handleUpgrade); + + const watcher = fs.watch(CONTENT_DIR, (eventType, filename) => { + if (!filename || !filename.endsWith('.html')) return; + + if (debounceTimers.has(filename)) clearTimeout(debounceTimers.get(filename)); + debounceTimers.set(filename, setTimeout(() => { + debounceTimers.delete(filename); + const filePath = path.join(CONTENT_DIR, filename); + + if (!fs.existsSync(filePath)) return; // file was deleted + touchActivity(); + + if (!knownFiles.has(filename)) { + knownFiles.add(filename); + const eventsFile = path.join(STATE_DIR, 'events'); + if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile); + console.log(JSON.stringify({ type: 'screen-added', file: filePath })); + } else { + console.log(JSON.stringify({ type: 'screen-updated', file: filePath })); + } + + broadcast({ type: 'reload' }); + }, 100)); + }); + watcher.on('error', (err) => console.error('fs.watch error:', err.message)); + + function shutdown(reason) { + console.log(JSON.stringify({ type: 'server-stopped', reason })); + const infoFile = path.join(STATE_DIR, 'server-info'); + if (fs.existsSync(infoFile)) fs.unlinkSync(infoFile); + fs.writeFileSync( + path.join(STATE_DIR, 'server-stopped'), + JSON.stringify({ reason, timestamp: Date.now() }) + '\n' + ); + watcher.close(); + clearInterval(lifecycleCheck); + server.close(() => process.exit(0)); + } + + function ownerAlive() { + if (!ownerPid) return true; + try { process.kill(ownerPid, 0); return true; } catch (e) { return e.code === 'EPERM'; } + } + + // Check every 60s: exit if owner process died or idle for 30 minutes + const lifecycleCheck = setInterval(() => { + if (!ownerAlive()) shutdown('owner process exited'); + else if (Date.now() - lastActivity > IDLE_TIMEOUT_MS) shutdown('idle timeout'); + }, 60 * 1000); + lifecycleCheck.unref(); + + // Validate owner PID at startup. If it's already dead, the PID resolution + // was wrong (common on WSL, Tailscale SSH, and cross-user scenarios). + // Disable monitoring and rely on the idle timeout instead. + if (ownerPid) { + try { process.kill(ownerPid, 0); } + catch (e) { + if (e.code !== 'EPERM') { + console.log(JSON.stringify({ type: 'owner-pid-invalid', pid: ownerPid, reason: 'dead at startup' })); + ownerPid = null; + } + } + } + + server.listen(PORT, HOST, () => { + const info = JSON.stringify({ + type: 'server-started', port: Number(PORT), host: HOST, + url_host: URL_HOST, url: 'http://' + URL_HOST + ':' + PORT, + screen_dir: CONTENT_DIR, state_dir: STATE_DIR + }); + console.log(info); + fs.writeFileSync(path.join(STATE_DIR, 'server-info'), info + '\n'); + }); +} + +if (require.main === module) { + startServer(); +} + +module.exports = { computeAcceptKey, encodeFrame, decodeFrame, OPCODES }; diff --git a/data/skills/superpowers/brainstorming/scripts/start-server.sh b/data/skills/superpowers/brainstorming/scripts/start-server.sh new file mode 100755 index 0000000..9ef6dcb --- /dev/null +++ b/data/skills/superpowers/brainstorming/scripts/start-server.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +# Start the brainstorm server and output connection info +# Usage: start-server.sh [--project-dir ] [--host ] [--url-host ] [--foreground] [--background] +# +# Starts server on a random high port, outputs JSON with URL. +# Each session gets its own directory to avoid conflicts. +# +# Options: +# --project-dir Store session files under /.superpowers/brainstorm/ +# instead of /tmp. Files persist after server stops. +# --host Host/interface to bind (default: 127.0.0.1). +# Use 0.0.0.0 in remote/containerized environments. +# --url-host Hostname shown in returned URL JSON. +# --foreground Run server in the current terminal (no backgrounding). +# --background Force background mode (overrides Codex auto-foreground). + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +# Parse arguments +PROJECT_DIR="" +FOREGROUND="false" +FORCE_BACKGROUND="false" +BIND_HOST="127.0.0.1" +URL_HOST="" +while [[ $# -gt 0 ]]; do + case "$1" in + --project-dir) + PROJECT_DIR="$2" + shift 2 + ;; + --host) + BIND_HOST="$2" + shift 2 + ;; + --url-host) + URL_HOST="$2" + shift 2 + ;; + --foreground|--no-daemon) + FOREGROUND="true" + shift + ;; + --background|--daemon) + FORCE_BACKGROUND="true" + shift + ;; + *) + echo "{\"error\": \"Unknown argument: $1\"}" + exit 1 + ;; + esac +done + +if [[ -z "$URL_HOST" ]]; then + if [[ "$BIND_HOST" == "127.0.0.1" || "$BIND_HOST" == "localhost" ]]; then + URL_HOST="localhost" + else + URL_HOST="$BIND_HOST" + fi +fi + +# Some environments reap detached/background processes. Auto-foreground when detected. +if [[ -n "${CODEX_CI:-}" && "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then + FOREGROUND="true" +fi + +# Windows/Git Bash reaps nohup background processes. Auto-foreground when detected. +if [[ "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then + case "${OSTYPE:-}" in + msys*|cygwin*|mingw*) FOREGROUND="true" ;; + esac + if [[ -n "${MSYSTEM:-}" ]]; then + FOREGROUND="true" + fi +fi + +# Generate unique session directory +SESSION_ID="$$-$(date +%s)" + +if [[ -n "$PROJECT_DIR" ]]; then + SESSION_DIR="${PROJECT_DIR}/.superpowers/brainstorm/${SESSION_ID}" +else + SESSION_DIR="/tmp/brainstorm-${SESSION_ID}" +fi + +STATE_DIR="${SESSION_DIR}/state" +PID_FILE="${STATE_DIR}/server.pid" +LOG_FILE="${STATE_DIR}/server.log" + +# Create fresh session directory with content and state peers +mkdir -p "${SESSION_DIR}/content" "$STATE_DIR" + +# Kill any existing server +if [[ -f "$PID_FILE" ]]; then + old_pid=$(cat "$PID_FILE") + kill "$old_pid" 2>/dev/null + rm -f "$PID_FILE" +fi + +cd "$SCRIPT_DIR" + +# Resolve the harness PID (grandparent of this script). +# $PPID is the ephemeral shell the harness spawned to run us — it dies +# when this script exits. The harness itself is $PPID's parent. +OWNER_PID="$(ps -o ppid= -p "$PPID" 2>/dev/null | tr -d ' ')" +if [[ -z "$OWNER_PID" || "$OWNER_PID" == "1" ]]; then + OWNER_PID="$PPID" +fi + +# Foreground mode for environments that reap detached/background processes. +if [[ "$FOREGROUND" == "true" ]]; then + echo "$$" > "$PID_FILE" + env BRAINSTORM_DIR="$SESSION_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" BRAINSTORM_OWNER_PID="$OWNER_PID" node server.cjs + exit $? +fi + +# Start server, capturing output to log file +# Use nohup to survive shell exit; disown to remove from job table +nohup env BRAINSTORM_DIR="$SESSION_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" BRAINSTORM_OWNER_PID="$OWNER_PID" node server.cjs > "$LOG_FILE" 2>&1 & +SERVER_PID=$! +disown "$SERVER_PID" 2>/dev/null +echo "$SERVER_PID" > "$PID_FILE" + +# Wait for server-started message (check log file) +for i in {1..50}; do + if grep -q "server-started" "$LOG_FILE" 2>/dev/null; then + # Verify server is still alive after a short window (catches process reapers) + alive="true" + for _ in {1..20}; do + if ! kill -0 "$SERVER_PID" 2>/dev/null; then + alive="false" + break + fi + sleep 0.1 + done + if [[ "$alive" != "true" ]]; then + echo "{\"error\": \"Server started but was killed. Retry in a persistent terminal with: $SCRIPT_DIR/start-server.sh${PROJECT_DIR:+ --project-dir $PROJECT_DIR} --host $BIND_HOST --url-host $URL_HOST --foreground\"}" + exit 1 + fi + grep "server-started" "$LOG_FILE" | head -1 + exit 0 + fi + sleep 0.1 +done + +# Timeout - server didn't start +echo '{"error": "Server failed to start within 5 seconds"}' +exit 1 diff --git a/data/skills/superpowers/brainstorming/scripts/stop-server.sh b/data/skills/superpowers/brainstorming/scripts/stop-server.sh new file mode 100755 index 0000000..a6b94e6 --- /dev/null +++ b/data/skills/superpowers/brainstorming/scripts/stop-server.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Stop the brainstorm server and clean up +# Usage: stop-server.sh +# +# Kills the server process. Only deletes session directory if it's +# under /tmp (ephemeral). Persistent directories (.superpowers/) are +# kept so mockups can be reviewed later. + +SESSION_DIR="$1" + +if [[ -z "$SESSION_DIR" ]]; then + echo '{"error": "Usage: stop-server.sh "}' + exit 1 +fi + +STATE_DIR="${SESSION_DIR}/state" +PID_FILE="${STATE_DIR}/server.pid" + +if [[ -f "$PID_FILE" ]]; then + pid=$(cat "$PID_FILE") + + # Try to stop gracefully, fallback to force if still alive + kill "$pid" 2>/dev/null || true + + # Wait for graceful shutdown (up to ~2s) + for i in {1..20}; do + if ! kill -0 "$pid" 2>/dev/null; then + break + fi + sleep 0.1 + done + + # If still running, escalate to SIGKILL + if kill -0 "$pid" 2>/dev/null; then + kill -9 "$pid" 2>/dev/null || true + + # Give SIGKILL a moment to take effect + sleep 0.1 + fi + + if kill -0 "$pid" 2>/dev/null; then + echo '{"status": "failed", "error": "process still running"}' + exit 1 + fi + + rm -f "$PID_FILE" "${STATE_DIR}/server.log" + + # Only delete ephemeral /tmp directories + if [[ "$SESSION_DIR" == /tmp/* ]]; then + rm -rf "$SESSION_DIR" + fi + + echo '{"status": "stopped"}' +else + echo '{"status": "not_running"}' +fi diff --git a/data/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md b/data/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md new file mode 100644 index 0000000..35acbb6 --- /dev/null +++ b/data/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md @@ -0,0 +1,49 @@ +# Spec Document Reviewer Prompt Template + +Use this template when dispatching a spec document reviewer subagent. + +**Purpose:** Verify the spec is complete, consistent, and ready for implementation planning. + +**Dispatch after:** Spec document is written to docs/superpowers/specs/ + +``` +Task tool (general-purpose): + description: "Review spec document" + prompt: | + You are a spec document reviewer. Verify this spec is complete and ready for planning. + + **Spec to review:** [SPEC_FILE_PATH] + + ## What to Check + + | Category | What to Look For | + |----------|------------------| + | Completeness | TODOs, placeholders, "TBD", incomplete sections | + | Consistency | Internal contradictions, conflicting requirements | + | Clarity | Requirements ambiguous enough to cause someone to build the wrong thing | + | Scope | Focused enough for a single plan — not covering multiple independent subsystems | + | YAGNI | Unrequested features, over-engineering | + + ## Calibration + + **Only flag issues that would cause real problems during implementation planning.** + A missing section, a contradiction, or a requirement so ambiguous it could be + interpreted two different ways — those are issues. Minor wording improvements, + stylistic preferences, and "sections less detailed than others" are not. + + Approve unless there are serious gaps that would lead to a flawed plan. + + ## Output Format + + ## Spec Review + + **Status:** Approved | Issues Found + + **Issues (if any):** + - [Section X]: [specific issue] - [why it matters for planning] + + **Recommendations (advisory, do not block approval):** + - [suggestions for improvement] +``` + +**Reviewer returns:** Status, Issues (if any), Recommendations diff --git a/data/skills/superpowers/brainstorming/visual-companion.md b/data/skills/superpowers/brainstorming/visual-companion.md new file mode 100644 index 0000000..2113863 --- /dev/null +++ b/data/skills/superpowers/brainstorming/visual-companion.md @@ -0,0 +1,287 @@ +# Visual Companion Guide + +Browser-based visual brainstorming companion for showing mockups, diagrams, and options. + +## When to Use + +Decide per-question, not per-session. The test: **would the user understand this better by seeing it than reading it?** + +**Use the browser** when the content itself is visual: + +- **UI mockups** — wireframes, layouts, navigation structures, component designs +- **Architecture diagrams** — system components, data flow, relationship maps +- **Side-by-side visual comparisons** — comparing two layouts, two color schemes, two design directions +- **Design polish** — when the question is about look and feel, spacing, visual hierarchy +- **Spatial relationships** — state machines, flowcharts, entity relationships rendered as diagrams + +**Use the terminal** when the content is text or tabular: + +- **Requirements and scope questions** — "what does X mean?", "which features are in scope?" +- **Conceptual A/B/C choices** — picking between approaches described in words +- **Tradeoff lists** — pros/cons, comparison tables +- **Technical decisions** — API design, data modeling, architectural approach selection +- **Clarifying questions** — anything where the answer is words, not a visual preference + +A question *about* a UI topic is not automatically a visual question. "What kind of wizard do you want?" is conceptual — use the terminal. "Which of these wizard layouts feels right?" is visual — use the browser. + +## How It Works + +The server watches a directory for HTML files and serves the newest one to the browser. You write HTML content to `screen_dir`, the user sees it in their browser and can click to select options. Selections are recorded to `state_dir/events` that you read on your next turn. + +**Content fragments vs full documents:** If your HTML file starts with `/.superpowers/brainstorm/` for the session directory. + +**Note:** Pass the project root as `--project-dir` so mockups persist in `.superpowers/brainstorm/` and survive server restarts. Without it, files go to `/tmp` and get cleaned up. Remind the user to add `.superpowers/` to `.gitignore` if it's not already there. + +**Launching the server by platform:** + +**Claude Code (macOS / Linux):** +```bash +# Default mode works — the script backgrounds the server itself +scripts/start-server.sh --project-dir /path/to/project +``` + +**Claude Code (Windows):** +```bash +# Windows auto-detects and uses foreground mode, which blocks the tool call. +# Use run_in_background: true on the Bash tool call so the server survives +# across conversation turns. +scripts/start-server.sh --project-dir /path/to/project +``` +When calling this via the Bash tool, set `run_in_background: true`. Then read `$STATE_DIR/server-info` on the next turn to get the URL and port. + +**Codex:** +```bash +# Codex reaps background processes. The script auto-detects CODEX_CI and +# switches to foreground mode. Run it normally — no extra flags needed. +scripts/start-server.sh --project-dir /path/to/project +``` + +**Gemini CLI:** +```bash +# Use --foreground and set is_background: true on your shell tool call +# so the process survives across turns +scripts/start-server.sh --project-dir /path/to/project --foreground +``` + +**Other environments:** The server must keep running in the background across conversation turns. If your environment reaps detached processes, use `--foreground` and launch the command with your platform's background execution mechanism. + +If the URL is unreachable from your browser (common in remote/containerized setups), bind a non-loopback host: + +```bash +scripts/start-server.sh \ + --project-dir /path/to/project \ + --host 0.0.0.0 \ + --url-host localhost +``` + +Use `--url-host` to control what hostname is printed in the returned URL JSON. + +## The Loop + +1. **Check server is alive**, then **write HTML** to a new file in `screen_dir`: + - Before each write, check that `$STATE_DIR/server-info` exists. If it doesn't (or `$STATE_DIR/server-stopped` exists), the server has shut down — restart it with `start-server.sh` before continuing. The server auto-exits after 30 minutes of inactivity. + - Use semantic filenames: `platform.html`, `visual-style.html`, `layout.html` + - **Never reuse filenames** — each screen gets a fresh file + - Use Write tool — **never use cat/heredoc** (dumps noise into terminal) + - Server automatically serves the newest file + +2. **Tell user what to expect and end your turn:** + - Remind them of the URL (every step, not just first) + - Give a brief text summary of what's on screen (e.g., "Showing 3 layout options for the homepage") + - Ask them to respond in the terminal: "Take a look and let me know what you think. Click to select an option if you'd like." + +3. **On your next turn** — after the user responds in the terminal: + - Read `$STATE_DIR/events` if it exists — this contains the user's browser interactions (clicks, selections) as JSON lines + - Merge with the user's terminal text to get the full picture + - The terminal message is the primary feedback; `state_dir/events` provides structured interaction data + +4. **Iterate or advance** — if feedback changes current screen, write a new file (e.g., `layout-v2.html`). Only move to the next question when the current step is validated. + +5. **Unload when returning to terminal** — when the next step doesn't need the browser (e.g., a clarifying question, a tradeoff discussion), push a waiting screen to clear the stale content: + + ```html + +
+

Continuing in terminal...

+
+ ``` + + This prevents the user from staring at a resolved choice while the conversation has moved on. When the next visual question comes up, push a new content file as usual. + +6. Repeat until done. + +## Writing Content Fragments + +Write just the content that goes inside the page. The server wraps it in the frame template automatically (header, theme CSS, selection indicator, and all interactive infrastructure). + +**Minimal example:** + +```html +

Which layout works better?

+

Consider readability and visual hierarchy

+ +
+
+
A
+
+

Single Column

+

Clean, focused reading experience

+
+
+
+
B
+
+

Two Column

+

Sidebar navigation with main content

+
+
+
+``` + +That's it. No ``, no CSS, no `