|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This is **opencode-qoder-plugin** — an [opencode](https://opencode.ai) plugin that injects Qoder AI models via a `config` hook. No manual provider configuration needed by users. |
| 4 | + |
| 5 | +## Project Structure |
| 6 | + |
| 7 | +``` |
| 8 | +opencode-qoder-plugin/ |
| 9 | +├── index.ts # Plugin entry — config hook + auth hook |
| 10 | +├── provider.ts # Exports createQoderProvider() (opencode npm loader entry) |
| 11 | +├── src/ |
| 12 | +│ ├── models.ts # 10 built-in model definitions (injected by config hook) |
| 13 | +│ ├── qoder-language-model.ts # LanguageModelV2 implementation (doGenerate + doStream) |
| 14 | +│ ├── prompt-builder.ts # AI SDK CallOptions → Qoder prompt / multimodal builder |
| 15 | +│ └── vendor/ |
| 16 | +│ ├── qoder-agent-sdk.mjs # Vendored Qoder Agent SDK — DO NOT modify |
| 17 | +│ └── qoder-agent-sdk.d.ts # SDK type declarations — DO NOT modify |
| 18 | +└── tests/ |
| 19 | + ├── models.test.ts |
| 20 | + ├── plugin.test.ts |
| 21 | + ├── qoder-language-model.test.ts |
| 22 | + └── integration/ |
| 23 | + ├── real-api.test.ts # Requires `qoder login` |
| 24 | + └── opencode-cli.test.ts |
| 25 | +``` |
| 26 | + |
| 27 | +## Key Design Decisions |
| 28 | + |
| 29 | +- **Plugin, not provider config** — `index.ts` uses the `config` hook to inject `provider.qoder` automatically. Users only need `"plugin": ["opencode-qoder-plugin"]` in their `opencode.json`. |
| 30 | +- **Auth hook** — checks `~/.qoder/.auth/user` for login state. If absent, surfaces a prompt telling users to run `qoder login`. |
| 31 | +- **Vendored SDK** — `src/vendor/qoder-agent-sdk.mjs` is a bundled copy of `@ali/qoder-agent-sdk` (internal registry). Do not replace it without testing the full streaming pipeline. |
| 32 | +- **Model merging** — builtin models from `src/models.ts` are injected first; any `provider.qoder.models` overrides in the user's `opencode.json` take precedence. |
| 33 | + |
| 34 | +## How the Streaming Pipeline Works |
| 35 | + |
| 36 | +``` |
| 37 | +opencode → QoderLanguageModel.doStream() |
| 38 | + → buildPromptFromOptions() # text or multimodal (base64 image) |
| 39 | + → resolveQoderCLI() # finds latest ~/.qoder/bin/qodercli/qodercli-<version> |
| 40 | + → SDK query() # streams SDKMessage events |
| 41 | + ├─ stream_event path # incremental text / tool-input deltas (preferred) |
| 42 | + └─ assistant path # full-block fallback |
| 43 | + → ReadableStream<V2StreamPart> |
| 44 | +``` |
| 45 | + |
| 46 | +## Development |
| 47 | + |
| 48 | +```bash |
| 49 | +npm install |
| 50 | +npm test # unit tests, no network required |
| 51 | +``` |
| 52 | + |
| 53 | +## Release Process |
| 54 | + |
| 55 | +Releases are automated via GitHub Actions: |
| 56 | + |
| 57 | +1. Update `version` in `package.json` |
| 58 | +2. Commit and push: `git commit -m "chore: release vX.Y.Z"` |
| 59 | +3. Tag and push: `git tag vX.Y.Z && git push origin vX.Y.Z` |
| 60 | +4. The **Publish** workflow triggers automatically and publishes to npmjs.com using `NPM_TOKEN` secret |
| 61 | + |
| 62 | +> **NPM_TOKEN** must be set in GitHub repo Settings → Secrets → `NPM_TOKEN`. |
| 63 | +> Use an **Automation** type token from https://www.npmjs.com/settings/~/tokens to bypass OTP. |
| 64 | +
|
| 65 | +## What NOT to Do |
| 66 | + |
| 67 | +- Do not modify `src/vendor/` files without thorough integration testing |
| 68 | +- Do not add a `provider.qoder` block to `opencode.json` — the plugin injects it automatically |
| 69 | +- Do not move `@opencode-ai/plugin` back to `devDependencies` — it must be in `dependencies` so opencode's Bun installer pulls it |
0 commit comments