chore: add OpenCode commands, agents, skills, and permissions#153
chore: add OpenCode commands, agents, skills, and permissions#153
Conversation
- Enhance opencode.json with formatter (Biome), permissions (allow safe ops, deny destructive/secret access), and instructions ref - Add 10 slash commands: test, e2e, lint, lint-fix, build, typecheck, db-migrate, db-generate, ci, deploy - Add 3 custom agents: security-auditor (read-only), db-reviewer (read-only), test-writer - Add 4 skills: cloudflare-workers, hono-jsx, drizzle-d1, opencode-research
There was a problem hiding this comment.
Pull request overview
This PR adds OpenCode project configuration and supporting assets (commands, agents, and skills) to standardize how contributors and automation interact with the repo via OpenCode.
Changes:
- Expanded
opencode.jsonwithinstructions, Biome-based formatting, and an allow/deny permissions model. - Added 10 OpenCode slash commands under
.opencode/commands/that wrap commonpnpmworkflows. - Added 3 specialized OpenCode agents and 4 on-demand skills documenting project-specific patterns.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| opencode.json | Adds OpenCode instructions reference, formatter integration, and tool permissions. |
| .opencode/commands/build.md | Adds /build wrapper for pnpm build. |
| .opencode/commands/ci.md | Adds /ci wrapper intended to mirror CI checks. |
| .opencode/commands/db-generate.md | Adds /db-generate wrapper for pnpm db:generate. |
| .opencode/commands/db-migrate.md | Adds /db-migrate wrapper for pnpm db:migrate. |
| .opencode/commands/deploy.md | Adds /deploy workflow combining checks + pnpm deploy. |
| .opencode/commands/e2e.md | Adds /e2e wrapper for pnpm test:e2e. |
| .opencode/commands/lint-fix.md | Adds /lint-fix wrapper for pnpm lint:fix. |
| .opencode/commands/lint.md | Adds /lint wrapper for pnpm lint. |
| .opencode/commands/test.md | Adds /test wrapper for pnpm test:run with args passthrough. |
| .opencode/commands/typecheck.md | Adds /typecheck wrapper for pnpm build:check. |
| .opencode/agents/test-writer.md | Adds a test-writing agent configured for Vitest + project patterns. |
| .opencode/agents/security-auditor.md | Adds a read-only security review agent (plan mode, no write/bash). |
| .opencode/agents/db-reviewer.md | Adds a read-only DB review agent (plan mode, no write/bash). |
| .opencode/skills/cloudflare-workers/SKILL.md | Adds Cloudflare Workers/D1/DO project reference notes. |
| .opencode/skills/drizzle-d1/SKILL.md | Adds Drizzle+D1 schema/migration/query reference notes. |
| .opencode/skills/hono-jsx/SKILL.md | Adds Hono JSX SSR/component conventions and pitfalls. |
| .opencode/skills/opencode-research/SKILL.md | Adds a meta-skill for researching/applying OpenCode best practices. |
| "$schema": "https://opencode.ai/config.json", | ||
| "instructions": ["AGENTS.md"], | ||
| "formatter": { | ||
| "biome check --write --unsafe {file}": "*.ts,*.tsx,*.json" |
There was a problem hiding this comment.
The configured formatter runs biome check --write --unsafe {file}. In this repo, the existing auto-fix script (pnpm lint:fix) does not enable --unsafe, so this could introduce more aggressive/behavior-changing edits on save than the team currently uses. Consider dropping --unsafe (or aligning scripts and documenting why unsafe fixes are desired).
| "biome check --write --unsafe {file}": "*.ts,*.tsx,*.json" | |
| "biome check --write {file}": "*.ts,*.tsx,*.json" |
| "Task" | ||
| ], | ||
| "deny": [ | ||
| "Bash(rm -rf /)*", |
There was a problem hiding this comment.
permissions.deny entry "Bash(rm -rf /)*" looks like a pattern typo/inconsistency: all other Bash patterns keep the wildcard inside the parentheses (e.g. Bash(git status*)). With )* outside the parentheses, this deny rule may not match anything, weakening the intended protection against destructive commands. Consider moving the glob inside the Bash(...) pattern (and/or expanding it to cover the intended targets).
| "Bash(rm -rf /)*", | |
| "Bash(rm -rf /*)", |
| "Bash(rm -rf /)*", | ||
| "Bash(git push --force*)", | ||
| "Bash(git reset --hard*)", | ||
| "Read(.env*)", |
There was a problem hiding this comment.
Read(.env*) will also deny reading the committed .env.sample file in this repo, which is commonly needed for setup/reference. If the intent is to block secret env files while still allowing sample/example env files, narrow this pattern (e.g., deny .env, .env.* but explicitly allow .env.sample/.env.example, depending on how OpenCode resolves allow/deny precedence).
| "Read(.env*)", | |
| "Read(.env)", | |
| "Read(.env.local)", | |
| "Read(.env.development)", | |
| "Read(.env.production)", |
| 2. **Don't use hooks** — No useState, useEffect, etc. This is server-only | ||
| 3. **Don't forget `<!DOCTYPE html>`** — Always wrap with template literal | ||
| 4. **Don't use `class`** — Use `className` (JSX requirement) | ||
| 5. **Components must be async functions** — Not arrow functions assigned to const (for consistency) |
There was a problem hiding this comment.
The guidance in Common Mistakes contradicts the earlier example: it says components must be async functions and "not arrow functions assigned to const", but the example uses export const ExamplePage = async (...) => (...). Please align the example and the rule (either allow async arrow components, or change the example to the preferred declaration style).
| 5. **Components must be async functions** — Not arrow functions assigned to const (for consistency) | |
| 5. **Components must be async functions that return full HTML documents** |
| Run the same checks CI runs, in order: | ||
|
|
There was a problem hiding this comment.
This claims to run "the same checks CI runs", but .github/workflows/ci.yml also has an e2e job (build + pnpm db:migrate + pnpm db:seed + pnpm test:e2e). Either update the description to clarify this only mirrors the test job, or include the e2e steps / point users to run /e2e plus migrations/seed.
| IMPORTANT: Before deploying, run the full CI pipeline to make sure everything passes. | ||
|
|
||
| ``` | ||
| !`pnpm test:run && pnpm lint && pnpm build` | ||
| ``` |
There was a problem hiding this comment.
This says "run the full CI pipeline" but the command shown only runs unit tests + lint + build. In this repo, CI also runs Playwright e2e with pnpm db:migrate, pnpm db:seed, and pnpm test:e2e in a separate job. Please either include those steps here or reword to avoid implying this matches full CI coverage.
| Run the Playwright end-to-end tests. If arguments are provided, pass them through. | ||
|
|
||
| ``` | ||
| !`pnpm test:e2e $ARGUMENTS` | ||
| ``` |
There was a problem hiding this comment.
/e2e runs pnpm test:e2e, but Playwright in this repo expects a local Worker server and a prepared local D1 DB. CI runs pnpm build, pnpm db:migrate, and pnpm db:seed before pnpm test:e2e (see .github/workflows/ci.yml). Consider updating this command to run migrations/seed (or at least document the prerequisite) to make /e2e reliably runnable locally.
| ```ts | ||
| import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; | ||
|
|
||
| export const users = sqliteTable("users", { | ||
| id: integer("id").primaryKey({ autoIncrement: true }), | ||
| email: text("email").notNull().unique(), | ||
| name: text("name").notNull(), | ||
| picture: text("picture"), | ||
| passwordHash: text("password_hash"), | ||
| createdAt: text("created_at").notNull().default(sql`CURRENT_TIMESTAMP`), | ||
| }); |
There was a problem hiding this comment.
The schema snippet for users is out of sync with the actual project schema (hono/db/schema.ts): it shows passwordHash nullable and uses default(sqlCURRENT_TIMESTAMP) without importing sql. Since this skill is meant to be a reference for this repo, please update the example to match current schema patterns (e.g., password_hash non-null and the correct sql import/default expression).
Summary
opencode.jsonwith Biome formatter integration, granular permissions (allow safe git/build ops, deny destructive commands and secret file reads), and explicitinstructionsreference toAGENTS.md/test,/e2e,/lint,/lint-fix,/build,/typecheck,/db-migrate,/db-generate,/ci,/deploy) for common development workflowssecurity-auditor(read-only security review),db-reviewer(read-only schema/query review),test-writer(Vitest test generation)cloudflare-workers,hono-jsx,drizzle-d1, andopencode-research(a meta-skill for researching and applying OpenCode best practices to any project)What changed
opencode.jsoninstructions,formatter,permissionssections.opencode/commands/*.md(10 files).opencode/agents/*.md(3 files).opencode/skills/*/SKILL.md(4 files)No application code was changed. No existing tests are affected.