diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..8beda4d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,65 @@ +name: Bug report +description: Something isn't working as expected +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to report a bug. Please fill in as much detail as you can. + + - type: textarea + id: description + attributes: + label: What happened? + description: A clear description of the bug. + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Steps to reproduce + description: How do we reproduce the issue? + placeholder: | + 1. Start opencode with the plugin loaded + 2. Send a request to POST /v1/chat/completions with ... + 3. See error + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behaviour + description: What did you expect to happen? + validations: + required: true + + - type: textarea + id: request + attributes: + label: Request / response (if applicable) + description: Paste the curl command or request body and the response you received. + render: bash + + - type: input + id: version + attributes: + label: opencode-llm-proxy version + placeholder: "e.g. 1.6.1" + validations: + required: true + + - type: input + id: runtime + attributes: + label: Runtime and OS + placeholder: "e.g. Node.js 22, macOS 14 / Bun 1.2, Ubuntu 24.04" + validations: + required: true + + - type: input + id: provider + attributes: + label: Provider / model + placeholder: "e.g. github-copilot/claude-sonnet-4.6" diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..671cd64 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,43 @@ +name: Feature request +description: Suggest a new feature or improvement +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Thanks for the suggestion! Please describe the use case clearly so we can understand what you need. + + - type: textarea + id: problem + attributes: + label: What problem does this solve? + description: Describe the situation where this would be useful. + placeholder: "e.g. I use the Vercel AI SDK and currently have to..." + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed solution + description: What would you like to see added or changed? + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives you've considered + description: Any workarounds you're using today? + + - type: dropdown + id: api_format + attributes: + label: Which API format does this relate to? (if any) + options: + - OpenAI Chat Completions + - OpenAI Responses API + - Anthropic Messages API + - Google Gemini + - All / general + - Not API-format specific diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..575fbeb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contributing + +Thanks for your interest in contributing to opencode-llm-proxy. + +## Getting started + +```bash +git clone https://github.com/KochC/opencode-llm-proxy.git +cd opencode-llm-proxy +npm install +``` + +Run the tests: + +```bash +npm test +``` + +Run the linter: + +```bash +npm run lint +``` + +## How to contribute + +### Reporting bugs + +Open a [bug report](https://github.com/KochC/opencode-llm-proxy/issues/new?template=bug_report.yml). Include: + +- What you did +- What you expected +- What actually happened +- Your Node.js / Bun version and OS + +### Suggesting features + +Open a [feature request](https://github.com/KochC/opencode-llm-proxy/issues/new?template=feature_request.yml) describing the use case. + +### Submitting a pull request + +1. Fork the repo and create a branch from `dev` (not `main`) +2. Make your changes +3. Add or update tests in `index.test.js` — all 112+ tests must pass +4. Lint passes: `npm run lint` +5. Commit using [Conventional Commits](https://www.conventionalcommits.org/): + - `fix:` for bug fixes (triggers a patch release) + - `feat:` for new features (triggers a minor release) + - `docs:` / `chore:` / `test:` for everything else (no release) +6. Open a PR against the `dev` branch + +## Branch model + +``` +dev ──► main ──► npm (via Release Please) +``` + +- All work goes on `dev` +- `main` is release-only — only Release Please PRs merge directly there +- Do not open PRs against `main` + +## Tests + +Tests use the Node.js built-in test runner — no external framework needed. + +```bash +node --test # run once +node --test --watch # watch mode +node --test --experimental-test-coverage # with coverage +``` + +Tests mock the OpenCode SDK client entirely — no real LLM calls are made. + +## Code style + +ESLint enforces style. Run `npm run lint` before pushing. The config is in `eslint.config.js`. + +Key conventions in the codebase: + +- Pure functions are exported for testability (`normalizeMessages`, `buildPrompt`, etc.) +- Each API format (OpenAI, Anthropic, Gemini) has its own section in `index.js` +- Error responses mirror the format of the target API (OpenAI errors for `/v1/*`, Anthropic errors for `/v1/messages`, etc.) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bbf87e4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 KochC + +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.