Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ jobs:
with:
publish: bun run release
version: bun run version
commit: "chore: release new package version"
title: "🚀🚢 Release new package version 🚀🚢"
commit: 'chore: release new package version'
title: '🚀🚢 Release new package version 🚀🚢'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
3 changes: 3 additions & 0 deletions .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"**/*.{ts,tsx}": ["eslint --fix", "oxfmt"]
}
11 changes: 11 additions & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"tabWidth": 2,
"semi": false,
"arrowParens": "always",
"sortPackageJson": false,
"ignorePatterns": ["node_modules", "dist", ".opencode"]
}
37 changes: 23 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,43 @@ package.json ← npm package config
## Commands

### Install dependencies

```sh
bun install
```

### Build (emit JS + declarations to dist/)

```sh
bun run build
```

### Type-check (no emit)

```sh
bunx tsc --noEmit
```

### Run all tests

```sh
bun test
```

### Run a single test file

```sh
bun test src/index.test.ts
```

### Run tests matching a name pattern

```sh
bun test --test-name-pattern "pattern here"
```

### Run tests in watch mode

```sh
bun test --watch
```
Expand All @@ -86,19 +93,19 @@ bun test --watch

Always use Bun's built-in APIs instead of third-party equivalents:

| Task | Use | Do NOT use |
|---|---|---|
| Run a file | `bun <file>` | `node <file>`, `ts-node <file>` |
| HTTP server | `Bun.serve()` | `express`, `fastify` |
| SQLite | `bun:sqlite` | `better-sqlite3` |
| Redis | `Bun.redis` | `ioredis` |
| Postgres | `Bun.sql` | `pg`, `postgres.js` |
| WebSocket | built-in `WebSocket` | `ws` |
| File I/O | `Bun.file()` | `node:fs` readFile/writeFile |
| Shell commands | `Bun.$\`cmd\`` | `execa`, `child_process` |
| Environment vars | automatic `.env` loading | `dotenv` |
| Frontend | `Bun.serve()` with HTML imports | `vite`, `webpack`, `esbuild` |
| Testing | `bun test` | `jest`, `vitest` |
| Task | Use | Do NOT use |
| ---------------- | ------------------------------- | ------------------------------- |
| Run a file | `bun <file>` | `node <file>`, `ts-node <file>` |
| HTTP server | `Bun.serve()` | `express`, `fastify` |
| SQLite | `bun:sqlite` | `better-sqlite3` |
| Redis | `Bun.redis` | `ioredis` |
| Postgres | `Bun.sql` | `pg`, `postgres.js` |
| WebSocket | built-in `WebSocket` | `ws` |
| File I/O | `Bun.file()` | `node:fs` readFile/writeFile |
| Shell commands | `Bun.$\`cmd\`` | `execa`, `child_process` |
| Environment vars | automatic `.env` loading | `dotenv` |
| Frontend | `Bun.serve()` with HTML imports | `vite`, `webpack`, `esbuild` |
| Testing | `bun test` | `jest`, `vitest` |

---

Expand Down Expand Up @@ -180,6 +187,7 @@ Key settings from `tsconfig.json`:
### Testing

- Use Bun's built-in `bun:test` — do not install Jest or Vitest.

```ts
import { test, expect, describe, beforeEach } from "bun:test";

Expand All @@ -189,6 +197,7 @@ Key settings from `tsconfig.json`:
});
});
```

- Place test files next to the code they test, e.g., `foo.ts` → `foo.test.ts`.
- Test file discovery: `**/*.test.ts`, `**/*.test.tsx`, `**/*.spec.ts`, `**/*.spec.tsx`.

Expand All @@ -206,5 +215,5 @@ The `.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc` rule applies to al
> Default to using Bun instead of Node.js.
> `Bun.serve()` supports WebSockets, HTTPS, and routes — don't use Express.
> HTML imports with `Bun.serve()` for frontend — don't use Vite.
> `Bun.$\`ls\`` instead of execa.
> `Bun.$` instead of execa.

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

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

The guidance line `Bun.$` instead of execa. is ambiguous because Bun.$ is a template tag and needs a command template literal to be actionable. Consider updating this to a syntactically correct example (and format it so the backticks render correctly in Markdown), e.g. showing Bun.$\ls`` or similar.

Suggested change
> `Bun.$` instead of execa.
> Use Bun's process spawning helper (for example, `await Bun.$`git status`;`) instead of execa.

Copilot uses AI. Check for mistakes.
> Bun automatically loads `.env` — don't use dotenv.
352 changes: 340 additions & 12 deletions bun.lock

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import prettier from "eslint-config-prettier/flat";

export default tseslint.config(
{
ignores: ["dist", "node_modules", "*.config.js"],
},
js.configs.recommended,
...tseslint.configs.recommended,
prettier,
{
files: ["**/*.ts"],
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
parser: tseslint.parser,
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
globals: {
// Node.js globals
console: "readonly",
process: "readonly",
Buffer: "readonly",
// Web APIs
URL: "readonly",
AbortController: "readonly",
// Bun globals
Bun: "readonly",
},
},
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "warn",
"no-console": "error",
},
}
);
17 changes: 15 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@
"build:bundle": "bun build src/index.ts --outfile dist/index.js --format esm --target bun --external @opencode-ai/plugin",
"build:types": "tsc --project tsconfig.build.json",
"typecheck": "tsc --noEmit",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "oxfmt 'src/**/*.ts'",
"format:check": "oxfmt --check 'src/**/*.ts'",
Comment thread
mcmunder marked this conversation as resolved.
"version": "changeset version",
"release": "bun run build && changeset publish",
"prepare": "simple-git-hooks"
},
"simple-git-hooks": {
"commit-msg": "bunx commitlint --edit $1"
"commit-msg": "bunx commitlint --edit $1",
"pre-commit": "bunx lint-staged"
},
"keywords": [
"opencode",
Expand All @@ -50,9 +55,17 @@
"@changesets/cli": "^2.30.0",
"@commitlint/cli": "^20.5.0",
"@commitlint/config-conventional": "^20.5.0",
"@eslint/js": "^9.39.1",
"@opencode-ai/plugin": "1.2.27",
"@types/bun": "1.3.10",
"simple-git-hooks": "^2.13.1"
"@types/node": "^20.11.5",
"bun-types": "^1.3.11",
"eslint": "^9.39.1",
"eslint-config-prettier": "10.1.8",
"lint-staged": "^15.2.0",
"oxfmt": "^0.42.0",
"simple-git-hooks": "^2.13.1",
"typescript-eslint": "^8.57.0"
},
"peerDependencies": {
"@opencode-ai/plugin": "^1.1.0",
Expand Down
Loading
Loading