Skip to content

chore: add OpenCode commands, agents, skills, and permissions#153

Merged
mahata merged 1 commit intomainfrom
chore/opencode-best-practices
Mar 29, 2026
Merged

chore: add OpenCode commands, agents, skills, and permissions#153
mahata merged 1 commit intomainfrom
chore/opencode-best-practices

Conversation

@mahata
Copy link
Copy Markdown
Owner

@mahata mahata commented Mar 29, 2026

Summary

  • Enhance opencode.json with Biome formatter integration, granular permissions (allow safe git/build ops, deny destructive commands and secret file reads), and explicit instructions reference to AGENTS.md
  • Add 10 slash commands (/test, /e2e, /lint, /lint-fix, /build, /typecheck, /db-migrate, /db-generate, /ci, /deploy) for common development workflows
  • Add 3 custom agents: security-auditor (read-only security review), db-reviewer (read-only schema/query review), test-writer (Vitest test generation)
  • Add 4 on-demand skills: cloudflare-workers, hono-jsx, drizzle-d1, and opencode-research (a meta-skill for researching and applying OpenCode best practices to any project)

What changed

Area Files Description
Config opencode.json Added instructions, formatter, permissions sections
Commands .opencode/commands/*.md (10 files) Slash-command wrappers for pnpm scripts
Agents .opencode/agents/*.md (3 files) Specialized review and test-writing agents
Skills .opencode/skills/*/SKILL.md (4 files) Domain knowledge for Workers, Hono JSX, Drizzle, and OpenCode research

No application code was changed. No existing tests are affected.

- 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
Copilot AI review requested due to automatic review settings March 29, 2026 13:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.json with instructions, Biome-based formatting, and an allow/deny permissions model.
  • Added 10 OpenCode slash commands under .opencode/commands/ that wrap common pnpm workflows.
  • 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.

Comment thread opencode.json
"$schema": "https://opencode.ai/config.json",
"instructions": ["AGENTS.md"],
"formatter": {
"biome check --write --unsafe {file}": "*.ts,*.tsx,*.json"
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
"biome check --write --unsafe {file}": "*.ts,*.tsx,*.json"
"biome check --write {file}": "*.ts,*.tsx,*.json"

Copilot uses AI. Check for mistakes.
Comment thread opencode.json
"Task"
],
"deny": [
"Bash(rm -rf /)*",
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
"Bash(rm -rf /)*",
"Bash(rm -rf /*)",

Copilot uses AI. Check for mistakes.
Comment thread opencode.json
"Bash(rm -rf /)*",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Read(.env*)",
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
"Read(.env*)",
"Read(.env)",
"Read(.env.local)",
"Read(.env.development)",
"Read(.env.production)",

Copilot uses AI. Check for mistakes.
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)
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
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**

Copilot uses AI. Check for mistakes.
Comment thread .opencode/commands/ci.md
Comment on lines +5 to +6
Run the same checks CI runs, in order:

Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +9
IMPORTANT: Before deploying, run the full CI pipeline to make sure everything passes.

```
!`pnpm test:run && pnpm lint && pnpm build`
```
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment thread .opencode/commands/e2e.md
Comment on lines +5 to +9
Run the Playwright end-to-end tests. If arguments are provided, pass them through.

```
!`pnpm test:e2e $ARGUMENTS`
```
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/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.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +22
```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`),
});
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
@mahata mahata merged commit 3682577 into main Mar 29, 2026
7 checks passed
@mahata mahata deleted the chore/opencode-best-practices branch March 29, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants