mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-08-25 00:03:44 +00:00
Remove the duplicate Tauri native event transport and use the server EventSource stream consistently across web, Electron, and Tauri clients. Align the generated client and required opencode2 CLI on next-17353. Restrict workspace proxying to the required V2 API surface, enforce session and directory ownership, validate local file URIs, strip routing headers, and tighten provider, Yolo, worktree, and session event state handling. Protect the shared service lifecycle with private registration state, process-identity leases, safe ownership transfer, bounded shutdown, Windows executable resolution, and WSL namespace-aware PID verification. Unknown wrappers now fail closed rather than leaving an unowned service. Validated with server and UI typechecks, 433 UI tests, focused server lifecycle and proxy suites, 67 Rust tests, server and UI builds, and a real next-17353 service lifecycle smoke test.
5.7 KiB
5.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 and UI pin
@opencode-ai/client@0.0.0-next-17353; do not add@opencode-ai/sdk. packages/server/src/workspaces/opencode-service.tsowns the single sharedService.ensurelifecycle. Workspaces are native OpenCode locations/directories, not separate server processes.- OpenCode session calls use
/workspaces/:id/instance/api/*; CodeNomad control routes and multiplexed events use/api/*and/api/events. - Native
client.session.shellandclient.session.instructions.entrycover Shell and prompt instructions. There is nopackages/opencode-pluginintegration. - 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