CodeNomad/CONTRIBUTING.md
Pascal André e996196186
fix(v2): follow current OpenCode runtime
Update the experimental OpenCode client, protocol, and schema dependencies to the latest reviewed next release while removing the exact CLI version gate from shared-service discovery. This lets CodeNomad use current opencode2 releases instead of timing out solely because the runtime advanced.

Refresh migration, contributor, architecture, and skill guidance to require release-note, documentation, declaration, and proxy-parity review on each upgrade. The isolated opencode2 database behavior is documented consistently.

Validated with server and UI typechecks, 36 passing targeted service/workspace tests, a release Tauri build, and a packaged desktop smoke. The smoke opened D:\CodeNomad, reused three existing sessions, and received three distinct exact prompt responses from opencode2 next-17444.
2026-08-15 00:34:38 +02:00

166 lines
6.9 KiB
Markdown

# Contributing to CodeNomad
Thank you for your interest in contributing! This guide will help you get started.
## Prerequisites
- **Node.js 18+** and npm
- **OpenCode CLI** in your `PATH` (CodeNomad uses one shared native V2 service for all workspace locations)
## Quick Start
```bash
git clone https://github.com/NeuralNomadsAI/CodeNomad.git
cd CodeNomad
npm install
npm run dev
```
## Finding Issues to Work On
Browse [open issues](https://github.com/NeuralNomadsAI/CodeNomad/issues) and look for these labels:
| Label | Meaning |
|---|---|
| `ready-to-work` | Clear scope, ready for anyone to pick up |
| `good-first-issue` | Good for first-time contributors |
| `enhancement` | New feature requests |
| `bug` | Bug reports |
**Before starting:** comment on the issue so we can discuss approach and avoid duplicate work.
## Development Workflow
### 1. Fork and Branch
```bash
# Fork the repo on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/CodeNomad.git
cd CodeNomad
# Add the upstream remote
git remote add upstream https://github.com/NeuralNomadsAI/CodeNomad.git
# Create a branch from upstream/dev
git fetch upstream
git checkout -b fix/your-branch-name upstream/dev
```
### 2. Branch Naming
| Prefix | Use for |
|---|---|
| `fix/` | Bug fixes |
| `feat/` | New features |
| `docs/` | Documentation changes |
| `refactor/` | Code refactoring |
| `chore/` | Build, config, maintenance |
Examples: `fix/question-queue-ordering`, `feat/retry-tool-call`, `docs/contributing-guide`
### 3. Make Your Changes
```bash
# Install dependencies
npm install
# Run the dev server
npm run dev
# Run type checking
npm run typecheck --workspace @codenomad/ui
```
### 4. Commit
Write clear, descriptive commit messages. Explain **what** changed and **why**.
```bash
git add .
git commit -m "fix(ui): preserve question queue order when upserting duplicate requests
When a question arrives as a global entry and later resolves to a tool
part with a newer timestamp, the original enqueue time was lost, causing
the question to move behind newer entries and break interruption order."
```
### 5. Push and Create a PR
```bash
git push origin your-branch-name
```
Then open a pull request on GitHub targeting the `dev` branch.
**PR checklist:**
- [ ] Branch is based on latest `upstream/dev`
- [ ] One issue per PR (don't mix unrelated changes)
- [ ] Type checking passes: `npm run typecheck` (root) or the workspace-specific script matching your change area
- [ ] Tests pass (if applicable)
- [ ] PR description explains the change, includes relevant screenshots for UI changes, and links related issues when applicable
## Project Structure
| Package | Description |
|---|---|
| `packages/server` | Core logic & CLI — workspaces, OpenCode proxy, API, auth |
| `packages/ui` | SolidJS frontend — reactive UI components and stores |
| `packages/electron-app` | Electron desktop shell |
| `packages/tauri-app` | Tauri desktop shell (experimental) |
| `packages/cloudflare` | Cloudflare deployment adapters |
### OpenCode V2 Boundaries
- Server and UI must use the same latest reviewed `@opencode-ai/client` `next` release. Runtime discovery does not require an exact CLI version. Review OpenCode release notes, current documentation, and installed declarations on every upgrade; this is not the public `@opencode-ai/sdk` contract.
- Upgrade references: [OpenCode releases](https://github.com/anomalyco/opencode/releases), [OpenCode documentation](https://opencode.ai/docs/), and `node_modules/@opencode-ai/client/dist/promise/`.
- `packages/server/src/workspaces/opencode-service.ts` owns a custom lease-locked discovery, launch, process-proof, and authenticated-stop lifecycle. Production does not call `Service.ensure` or `Service.stop` directly. Workspaces are native OpenCode locations/directories, not separate server processes.
- V2 always uses `~/.local/share/opencode2/opencode.db`. Never reuse the V1 database for V2.
- OpenCode session calls use `/workspaces/:id/instance/api/*`; CodeNomad control routes and multiplexed events use `/api/*` and `/api/events`.
- The proxy is method/path allowlisted, so new upstream functionality is not exposed automatically.
- Native Shell (`client.session.shell`) and prompt instructions (`client.session.instructions.entry`) remain separate from native V2 PTY management.
- Native PTYs are location-scoped and listed in the Status panel. The UI refreshes them on PTY events and reconnect, displays native metadata, and supports title updates and ownership-checked removal. Current installed declarations have no PTY output/read/stream API or separate stop endpoint, so removal is the native stop action for a running PTY. `packages/opencode-plugin` and the server plugin/background-process paths remain deleted and must not be restored.
- Native events are volatile. Reconnect handlers must refetch authoritative state instead of assuming missed events will replay.
- Git mutations and Yolo policy remain CodeNomad-owned server boundaries.
### Key UI Files
| Path | Purpose |
|---|---|
| `packages/ui/src/stores/session-events.ts` | SSE event handlers (idle, status, permissions, questions) |
| `packages/ui/src/stores/session-actions.ts` | User actions (send message, abort, revert, fork) |
| `packages/ui/src/stores/message-v2/` | Message store (v2 architecture) |
| `packages/ui/src/stores/instances.ts` | Instance management and interruption queues |
| `packages/ui/src/components/tool-call.tsx` | Tool call rendering |
| `packages/ui/src/components/message-block.tsx` | Message display blocks |
| `packages/ui/src/components/session/session-view.tsx` | Main session view |
| `packages/ui/src/lib/i18n/messages/` | Translation files (en, es, fr, ja, ru, he, zh-Hans) |
> For the package map, native OpenCode V2 integration, ownership boundaries, and feature traces, load the `codenomad-architecture-guide` skill:
> `.opencode/skills/codenomad-architecture-guide/SKILL.md`
### Styling
- Tokens: `packages/ui/src/styles/tokens.css`
- Utilities: `packages/ui/src/styles/utilities.css`
- Component styles: `packages/ui/src/styles/components/`, `packages/ui/src/styles/messaging/`, `packages/ui/src/styles/panels/`
- Keep style files under ~150 lines; split by component
### Internationalization (i18n)
- Use `useI18n()` in components, `tGlobal()` in stores
- Messages live in `packages/ui/src/lib/i18n/messages/<locale>/`
- When adding a string: add to `en/` first, then add the same key to every other locale
- Placeholders use `{name}` syntax (word characters only)
## Code Principles
- **KISS**: Keep modules narrowly scoped
- **DRY**: Share helpers before copy-pasting
- **Single responsibility**: Split files when concerns diverge
- **Composable primitives**: Prefer signals, hooks, utilities over deep inheritance
## Need Help?
- Check existing [issues](https://github.com/NeuralNomadsAI/CodeNomad/issues) and [PRs](https://github.com/NeuralNomadsAI/CodeNomad/pulls)
- Ask in the issue you're working on
- Review the [server documentation](packages/server/README.md) for CLI flags and configuration