mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-08-21 14:23:26 +00:00
Pin the server and UI client to the installed beta runtime and reject mismatched CLI versions before shared-service startup. Delegate proven shared-service shutdown to Service.stop while retaining CodeNomad lease, peer, registration, endpoint, and process-identity checks. Adopt native Forms and the client/solid data reducer for live messages, tools, permissions, and input forms. Propagate internal stream generations into authoritative reconnect reconciliation and replace directory-wide session scans with native project cursor pagination. Fail worktree deletion when session evacuation fails and deduplicate canonical workspace folders instead of exposing non-isolated duplicate instances. Update migration notes and CI coverage for the reviewed contract. Validated with server/UI/Electron typechecks, 244 UI partition tests, 122 Electron native tests, 248 server tests plus 3 platform skips (the sole Windows cleanup race passed in isolation), UI/server/Electron builds, Tauri cargo check --locked, and git diff --check.
7 KiB
7 KiB
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
git clone https://github.com/NeuralNomadsAI/CodeNomad.git
cd CodeNomad
npm install
npm run dev
Finding Issues to Work On
Browse open 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
# 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
# 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.
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
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, UI, and the selected
opencode2CLI must use the exact@opencode-ai/clientversion pinned by the server package. Startup probes and rejects mismatched CLIs. Review OpenCode release notes, current documentation, and installed declarations on every upgrade; this is not the public@opencode-ai/sdkcontract. - Upgrade references: OpenCode releases, OpenCode documentation, and
node_modules/@opencode-ai/client/dist/promise/. packages/server/src/workspaces/opencode-service.tsowns a custom lease-locked discovery, launch, process-proof, and authenticated-stop lifecycle. Production does not callService.ensureorService.stopdirectly. 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-pluginand 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-guideskill:.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 and PRs
- Ask in the issue you're working on
- Review the server documentation for CLI flags and configuration