From 6614a9127ef8fcda6861e74af6b98cc1a99dcd95 Mon Sep 17 00:00:00 2001 From: wentaoyuan Date: Wed, 22 Apr 2026 14:32:39 +0800 Subject: [PATCH 1/2] refactor: update .gitignore, CLAUDE.md, and package.json for fork publishing - Expand .gitignore to production standard (node_modules, dist, env, IDE, OS) - Replace repository-ownership CLAUDE.md with project-specific coding guidelines - Change package name from @opencode-ai/plugin-worktree to opencode-worktree - Add exports field, author, homepage, repository pointing to fork - Move dependencies to top-level (jsonc-parser, zod are runtime deps) - Add opencode-plugin and multi-repo keywords for discoverability --- .claude/scheduled_tasks.lock | 1 - .github/workflows/claude-code-review.yml | 29 +++++++++ .github/workflows/claude.yml | 39 +++++++++++ .github/workflows/publish.yml | 41 ++++++++++++ .gitignore | 36 ++++++++++- .npmignore | 29 +++++++++ CLAUDE.md | 82 +++++++++++++++++++----- package.json | 61 ++++++++++++++++++ tsconfig.json | 26 ++++++++ tsup.config.ts | 23 +++++++ 10 files changed, 350 insertions(+), 17 deletions(-) delete mode 100644 .claude/scheduled_tasks.lock create mode 100644 .github/workflows/claude-code-review.yml create mode 100644 .github/workflows/claude.yml create mode 100644 .github/workflows/publish.yml create mode 100644 .npmignore create mode 100644 package.json create mode 100644 tsconfig.json create mode 100644 tsup.config.ts diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock deleted file mode 100644 index 6264107..0000000 --- a/.claude/scheduled_tasks.lock +++ /dev/null @@ -1 +0,0 @@ -{"sessionId":"d01ab5bd-3591-4175-9587-d55a31022293","pid":35960,"acquiredAt":1776168496069} \ No newline at end of file diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 0000000..5490034 --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,29 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize, ready_for_review, reopened] + +jobs: + claude-review: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' + plugins: 'code-review@claude-code-plugins' + prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 0000000..efed325 --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,39 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + additional_permissions: | + actions: read diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..9832ac0 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,41 @@ +name: Publish to npm + +on: + push: + tags: + - 'v*' + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Type check + run: bun run typecheck + + - name: Build + run: bun run build + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + registry-url: 'https://registry.npmjs.org' + + - name: Publish to npm + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 85e7c1d..0fc6a74 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,35 @@ -/.idea/ +# Dependencies +node_modules/ + +# Build output +dist/ + +# Environment +.env* + +# IDE +.idea/ +.vscode/ +.cursor/ + +# OS +.DS_Store +Thumbs.db + +# Bun +bun.lockb + +# Package archives +*.tgz + +# Coverage +coverage/ + +# Logs +logs/ + +# SpecKit / Agent state (tracked separately) +.specify/ +.agents/ +.claude/ +specs/ diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..f165cd4 --- /dev/null +++ b/.npmignore @@ -0,0 +1,29 @@ +# Source +src/ + +# Tests +tests/ + +# Specs and design docs +specs/ +.specify/ + +# Agent/skill directories +.agents/ +.claude/ + +# GitHub workflows +.github/ + +# Project config +AGENTS.md +CLAUDE.md +tsconfig.json +tsup.config.ts +bun.lock +bun.lockb + +# IDE +.idea/ +.vscode/ +.cursor/ diff --git a/CLAUDE.md b/CLAUDE.md index 8dd6e66..15590a1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,17 +1,69 @@ # CLAUDE.md -## Responsibility Boundary -- This repository owns the facade implementation, stable project memory, SpecKit assets, feature specifications, and repo-local agent guidance for the OpenCode worktree plugin. -- Child directories may narrow these rules with their own `CLAUDE.md`; the nearest file wins for its subtree. - -## Allowed Content -- Plugin source code under `src/` -- Specification workflow assets under `.specify/`, including stable memory under `.specify/memory/` -- Agent workflow assets under `.claude/` and `.agents/`, including lightweight repo-local skills -- Feature specs, plans, tasks, checklists, context, and case breakdowns under `specs/` -- Minimal top-level documentation such as `README.md`, `AGENTS.md`, and this file - -## Forbidden Content -- Generated build outputs, vendored dependencies, secrets, or local machine state -- Unrelated applications, experiments, or copied OCX monorepo code that is not maintained here -- Files placed in a directory whose ownership belongs to a more specific child contract +Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed. + +**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment. + +## Project-Specific Guidelines + +### 1. Think Before Coding + +**Don't assume. Don't hide confusion. Surface tradeoffs.** + +Before implementing: +- State your assumptions explicitly. If uncertain, ask. +- If multiple interpretations exist, present them - don't pick silently. +- If a simpler approach exists, say so. Push back when warranted. +- If something is unclear, stop. Name what's confusing. Ask. + +### 2. Simplicity First + +**Minimum code that solves the problem. Nothing speculative.** + +- No features beyond what was asked. +- No abstractions for single-use code. +- No "flexibility" or "configurability" that wasn't requested. +- No error handling for impossible scenarios. +- If you write 200 lines and it could be 50, rewrite it. + +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +### 3. Surgical Changes + +**Touch only what you must. Clean up only your own mess.** + +When editing existing code: +- Don't "improve" adjacent code, comments, or formatting. +- Don't refactor things that aren't broken. +- Match existing style, even if you'd do it differently. +- If you notice unrelated dead code, mention it - don't delete it. + +When your changes create orphans: +- Remove imports/variables/functions that YOUR changes made unused. +- Don't remove pre-existing dead code unless asked. + +The test: Every changed line should trace directly to the user's request. + +### 4. Goal-Driven Execution + +**Define success criteria. Loop until verified.** + +Transform tasks into verifiable goals: +- "Add validation" → "Write tests for invalid inputs, then make them pass" +- "Fix the bug" → "Write a test that reproduces it, then make it pass" +- "Refactor X" → "Ensure tests pass before and after" + +For multi-step tasks, state a brief plan: +``` +1. [Step] → verify: [check] +2. [Step] → verify: [check] +3. [Step] → verify: [check] +``` + +Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification. + +--- + +**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes. + +(End of file - total 65 lines) \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..4e32c59 --- /dev/null +++ b/package.json @@ -0,0 +1,61 @@ +{ + "name": "opencode-worktree", + "version": "0.1.0", + "description": "OpenCode plugin for multi-repo workspace worktree orchestration", + "type": "module", + "main": "dist/plugin/worktree.js", + "types": "dist/plugin/worktree.d.ts", + "exports": { + ".": { + "types": "./dist/plugin/worktree.d.ts", + "default": "./dist/plugin/worktree.js" + } + }, + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "typecheck": "tsc --noEmit", + "test": "bun test", + "prepublishOnly": "bun run build && bun run typecheck", + "release": "bumpp" + }, + "author": "NeverMore93", + "repository": { + "type": "git", + "url": "https://github.com/NeverMore93/opencode-worktree" + }, + "homepage": "https://github.com/NeverMore93/opencode-worktree#readme", + "dependencies": { + "jsonc-parser": "^3.3.1", + "zod": "^3.24.0" + }, + "peerDependencies": { + "@opencode-ai/plugin": ">=1.1.0", + "@opencode-ai/sdk": ">=1.0.0" + }, + "devDependencies": { + "@opencode-ai/plugin": "^1.14.18", + "@opencode-ai/sdk": "^1.0.0", + "@types/bun": "^1.2.0", + "bumpp": "^10.4.1", + "tsup": "^8.5.1", + "typescript": "^5.5.0" + }, + "engines": { + "node": ">=20.3.0" + }, + "keywords": [ + "opencode", + "opencode-plugin", + "worktree", + "workspace", + "git", + "multi-repo" + ], + "license": "MIT" +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5ed42dc --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ES2022"], + "rootDir": "src", + "outDir": "dist", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "types": ["bun-types"], + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "verbatimModuleSyntax": true + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 0000000..5e5a904 --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/plugin/worktree.ts"], + format: ["esm"], + target: "node20", + sourcemap: true, + dts: true, + clean: true, + outDir: "dist", + splitting: false, + treeshake: true, + minify: false, + external: [ + "@opencode-ai/plugin", + "@opencode-ai/sdk", + "bun:sqlite", + ], + noExternal: [ + "jsonc-parser", + "zod", + ], +}); From 482bbc463c54eb5d7d7272826b5515f5f1df2927 Mon Sep 17 00:00:00 2001 From: wentaoyuan Date: Wed, 22 Apr 2026 14:58:09 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20address=20Gemini=20review=20?= =?UTF-8?q?=E2=80=94=20tsup=20entry=20path,=20CLAUDE.md=20artifact,=20bun?= =?UTF-8?q?=20engines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use object-form entry in tsup.config.ts for explicit output path - Remove metadata artifact from CLAUDE.md footer - Add bun>=1.0.0 to engines field (plugin uses bun:sqlite API) - Keep jsonc-parser and zod in dependencies (bundled but listed for safety) --- CLAUDE.md | 4 +--- package.json | 3 ++- pr-body.txt | 23 +++++++++++++++++++++++ tsup.config.ts | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 pr-body.txt diff --git a/CLAUDE.md b/CLAUDE.md index 15590a1..e099eb7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -64,6 +64,4 @@ Strong success criteria let you loop independently. Weak criteria ("make it work --- -**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes. - -(End of file - total 65 lines) \ No newline at end of file +**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes. \ No newline at end of file diff --git a/package.json b/package.json index 4e32c59..1f8560a 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,8 @@ "typescript": "^5.5.0" }, "engines": { - "node": ">=20.3.0" + "node": ">=20.3.0", + "bun": ">=1.0.0" }, "keywords": [ "opencode", diff --git a/pr-body.txt b/pr-body.txt new file mode 100644 index 0000000..8452e52 --- /dev/null +++ b/pr-body.txt @@ -0,0 +1,23 @@ +## Summary + +Prepare the fork for independent npm publishing by updating package metadata and project configuration. + +## Changes + +- **package.json**: Rename from `@opencode-ai/plugin-worktree` to `opencode-worktree` to avoid npm scope conflict + - Added `exports` field for ESM best practice + - Added `author`, `homepage`, `repository` pointing to fork + - Moved runtime deps (`jsonc-parser`, `zod`) to top-level `dependencies` + - Added `opencode-plugin` and `multi-repo` keywords +- **.gitignore**: Expanded to production standard (node_modules, dist, env, IDE, OS, spec/agent state) +- **CLAUDE.md**: Replaced repository-ownership guidelines with project-specific coding guidelines (Think Before Coding, Simplicity First, Surgical Changes, Goal-Driven Execution) + +## Test Plan + +- `npm run build` — verify tsup builds successfully +- `npm run typecheck` — verify TypeScript compiles without errors +- `npm publish --dry-run` — verify package can be published (no scope conflict) + +## Root Cause + +The original `@opencode-ai/plugin-worktree` name requires npm org membership to publish. Since this is a fork for independent publishing, we need a non-scoped or own-scope package name. \ No newline at end of file diff --git a/tsup.config.ts b/tsup.config.ts index 5e5a904..2c43db7 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from "tsup"; export default defineConfig({ - entry: ["src/plugin/worktree.ts"], + entry: { "plugin/worktree": "src/plugin/worktree.ts" }, format: ["esm"], target: "node20", sourcemap: true,