# Contributing

> Contribution workflow, cross-platform/SSH/agent constraints from AGENTS.md, PR expectations, and maintainer release cutting via GitHub Actions.

- Repository: stablyai/orca
- GitHub: https://github.com/stablyai/orca
- Human docs: https://grok-wiki.com/public/docs/stablyai-orca-2036d532bf1c
- Complete Markdown: https://grok-wiki.com/public/docs/stablyai-orca-2036d532bf1c/llms-full.txt

## Source Files

- `.github/CONTRIBUTING.md`
- `AGENTS.md`
- `docs/STYLEGUIDE.md`
- `.github/workflows/release-cut.yml`
- `package.json`

---

---
title: "Contributing"
description: "Contribution workflow, cross-platform/SSH/agent constraints from AGENTS.md, PR expectations, and maintainer release cutting via GitHub Actions."
---

Contributions land through GitHub pull requests against `stablyai/orca`, with local validation via `pnpm lint`, `pnpm typecheck`, `pnpm test`, and `pnpm build`, agent-facing rules in `AGENTS.md`, and maintainer-only version tags cut exclusively by the **Cut Release** workflow (`.github/workflows/release-cut.yml`)—there are no `pnpm release:*` scripts in `package.json`.

## Prerequisites and local setup

| Requirement | Value |
| --- | --- |
| Node.js | `24` (`package.json` → `engines.node`) |
| Package manager | `pnpm@10.24.0` (pinned in `packageManager`) |
| Install | `pnpm install` |
| Dev app | `pnpm dev` (runs `ensure:electron-runtime` then electron-vite dev) |

<Note>
`pnpm prepare` installs Husky; the pre-commit hook runs `lint-staged` (oxlint + oxfmt on staged `*.{ts,tsx,js,jsx,mts,cts}` and oxfmt on `*.{json,css}`).
</Note>

For deeper build graphs, native runtime rebuilds, and platform packaging, see [Develop and build](/develop-and-build). For test targets beyond the default Vitest run, see [Testing](/testing).

## Scope and engineering constraints

Keep each change scoped to one user-facing improvement, bug fix, or focused refactor. Orca ships on **macOS, Linux, and Windows**, supports **local repos, remote runtimes, and SSH worktrees**, and integrates many **CLI agents** and **git providers**—generic behavior must stay provider-neutral with integration-specific logic behind explicit checks.

### Cross-platform (renderer, menus, paths)

| Surface | Rule |
| --- | --- |
| Keyboard shortcuts | Never hardcode `e.metaKey`. Use `navigator.userAgent.includes('Mac')` for `metaKey` vs `ctrlKey`. Electron menu accelerators use `CmdOrCtrl`. |
| Shortcut labels in UI | macOS: `⌘` / `⇧`; Linux/Windows: `Ctrl+` / `Shift+`. |
| File paths | `path.join` or Electron/Node path utilities—never assume `/` or `\`. |

These rules appear in both `AGENTS.md` and `docs/STYLEGUIDE.md` (Cross-platform section).

### SSH and remote execution

All changes must consider the SSH use case: do not assume a process, file, credential, shell, or network path exists only on the local machine. UI work should tolerate **50–200 ms** extra latency (deferred loading states, immediate disable on submit). Verify under SSH or simulated latency when touching loading, focus, or animation.

### Git providers and agents

- Source-control and review work must account for **GitLab** and other supported providers, not only GitHub. Avoid GitHub-only naming for generic review concepts.
- Agent and integration behavior stays **BYOC/BYOK**—no assumption of a single model vendor or hosted connector.
- When using `gh` in scripts or tooling, batch requests and respect API rate limits; keep commands portable across macOS, Linux, and Windows.
- **Do not commit PR evidence images**; attach screenshots and recordings to the PR conversation instead.

### Module naming and comments

- Avoid vague file or module names (`helpers`, `utils`, `common`, `misc`, `shared-stuff`). Name after the domain concept (`tab-group-state.ts`, `terminal-orphan-cleanup.ts`).
- Document **why** (one or two lines) when behavior follows a design doc or non-obvious constraint—do not restate what the code does.

### Worktree safety (agents editing the repo)

When using Orca worktrees or subagents, read and edit only in the **primary worktree checkout** for the task. Do not follow absolute paths from subagent output that point at a different repo root.

### UI and design system

UI changes must follow [`docs/STYLEGUIDE.md`](docs/STYLEGUIDE.md): tokens in `src/renderer/src/assets/main.css`, shadcn primitives under `src/renderer/src/components/ui/`, no invented hex when a token exists. Resolution order when the style guide is silent: sibling components → `components/ui/` primitives → `main.css` tokens → ask before inventing.

## Type declarations

Project-owned types belong in **`.ts` files**, not project-owned `.d.ts`. Ambient shims (`env.d.ts`, `vite/client.d.ts`) stay in `.d.ts`. With `skipLibCheck: true`, unresolved references in `.d.ts` can silently become `any` at call sites.

PR CI **fails** if any `*.d.ts` exists under `src/preload/` or `src/shared/` (see `.github/workflows/pr.yml`). Prefer `.ts` so `pnpm typecheck` actually validates IPC and shared contracts.

## Branch naming

Use descriptive prefixes:

- `fix/ctrl-backspace-delete-word`
- `feat/shift-enter-newline`
- `chore/update-contributor-guide`

Avoid vague names (`test`, `misc`, `changes`).

## Validation before opening a PR

Run the same commands contributors are expected to pass locally (from `.github/CONTRIBUTING.md`):

<CodeGroup>
```bash title="Lint"
pnpm lint
```
```bash title="Typecheck"
pnpm typecheck
```
```bash title="Unit tests"
pnpm test
```
```bash title="Full build"
pnpm build
```
</CodeGroup>

`pnpm lint` runs `oxlint` and `pnpm check:styled-scrollbars`. `pnpm typecheck` runs three `tsgo` projects (node, CLI, web). `pnpm test` ensures the native runtime for Node then runs Vitest. `pnpm build` runs typecheck plus relay, computer, CLI, electron-vite, and web builds.

### What PR CI runs

The **PR Checks** workflow (`.github/workflows/pr.yml`) on `pull_request` (opened, synchronize, reopened, ready_for_review) additionally runs:

| Step | Command / behavior |
| --- | --- |
| Lint | `pnpm exec oxlint --format github` |
| Styled scrollbars | `pnpm check:styled-scrollbars` |
| `.d.ts` guard | `find src/preload src/shared -name '*.d.ts'` must be empty |
| Feature wall budget | `pnpm check:feature-wall-assets` |
| macOS entitlements | `pnpm verify:macos-entitlements` |
| Typecheck | `pnpm typecheck` |
| Native module for tests | `pnpm rebuild better-sqlite3` |
| Test | `pnpm test` |
| Build | `pnpm build` |

Add **high-quality tests** for behavior changes and bug fixes—tests that would catch regressions, not shallow happy-path-only coverage. For UI or interaction changes, verify on every platform the change can affect.

## Pull request expectations

GitHub loads `.github/pull_request_template.md`. Each PR should:

<Steps>
<Step title="Explain the user-visible change">
Fill **Summary** with what users or operators will notice.
</Step>
<Step title="Document visuals">
Add screenshots or a screen recording for new or changed UI. If none, write `No visual change` under **Screenshots**.
</Step>
<Step title="Confirm local checks">
Check off `pnpm lint`, `pnpm typecheck`, `pnpm test`, `pnpm build`, and note added/updated tests (or why tests were not needed).
</Step>
<Step title="Attach AI review and security notes">
**AI Review Report**: cross-platform (macOS, Linux, Windows)—shortcuts, labels, paths, shell, Electron differences; SSH/remote/local compatibility; agent and integration compatibility; performance; UI quality when applicable.

**Security Audit**: input, command execution, paths, auth, secrets, dependencies, IPC.
</Step>
<Step title="Call out environment-specific behavior">
**Notes**: platform-specific, remote/SSH-specific, agent-specific, integration-specific, or git-provider-specific behavior and how you tested it.
</Step>
<Step title="Optional social shoutout">
Include your X handle if you want a merge shoutout on [@orca_build](https://x.com/orca_build).
</Step>
</Steps>

Stay focused on a single topic when possible. Do **not** bump `package.json` version or cut tags unless a maintainer requests it—releases are maintainer-managed.

## Agent authoring (`AGENTS.md`)

Coding agents (Cursor, Claude Code, Grok CLI, etc.) should load `AGENTS.md` at the repo root. It mirrors contributor constraints: design system, cross-platform shortcuts, SSH, git-provider neutrality, `gh` rate limits, no committed PR images, `.ts` over `.d.ts`, and worktree path discipline. UI agents should also respect `docs/STYLEGUIDE.md`.

<Info>
Orca does not require a specific LLM provider for contributions; bring your own agent and credentials (BYOC/BYOK).
</Info>

## Release process (maintainers)

Version bumps, tags, and published binaries are **not** part of normal contributor PRs. There is no local `pnpm release:*` script—releases run only from CI to avoid dirty trees, wrong branches, or stale `main`.

### Cut Release workflow

**Workflow file:** `.github/workflows/release-cut.yml`  
**GitHub UI:** Actions → **Cut Release**

<ParamField body="kind" type="choice" required>
`rc` (default), `patch`, `minor`, or `major`. Scheduled runs force `rc`.
</ParamField>
<ParamField body="ref" type="string">
Branch, tag, or SHA to build from. Default `main`. Scheduled runs always use `main`.
</ParamField>
<ParamField body="dry_run" type="boolean">
On manual dispatch only: validate a scheduled RC slot without creating a tag.
</ParamField>

**Manual cut:** Run workflow → choose `kind` and `ref` → run.

**Scheduled RC:** Cron `*/5 10,11,22,23 * * *` (UTC) with a Pacific-time gate so roughly **two RC cuts per day** (3:00 and 15:00 PT). Idempotency uses `[rc-slot:YYYY-MM-DD-HH]` commit markers and latest RC tag timing.

### Version selection

Latest **stable** is read from GitHub releases: tag must match `^v[0-9]` and must **not** contain `-rc.` (tag shape is authoritative; not the GitHub prerelease flag).

| `kind` | Next version (example: latest stable `1.3.14`) |
| --- | --- |
| `rc` (no RC series for next patch base) | `1.3.15-rc.0` |
| `rc` (series `1.3.15-rc.2` exists) | `1.3.15-rc.3` |
| `patch` | `1.3.15` (ignores intermediate RCs) |
| `minor` | `1.4.0` |
| `major` | `2.0.0` |

RC math always anchors to **latest stable + patch** for the base series, then increments `-rc.N`.

### Safety and recovery

- **Stable guard:** `patch` / `minor` / `major` refuse if the new version is not strictly greater than latest stable (protects `electron-updater` semver on the `latest` channel).
- **Draft RC recovery:** Complete draft releases from prior runs are published before cutting a new RC; unpublished tags with draft/missing releases can be **resumed** instead of bumping `-rc.N+1` again.
- **Off-main `ref`:** Only the tag is pushed; `main` is never fast-forwarded from a non-tip ref.
- **`ref` = tip of `main`:** Version-bump commit is pushed to `main` and the tag so local `package.json` matches shipped builds.
- **Orphan tags:** If a tag exists but no published release, the workflow re-dispatches the build for that tag instead of failing on collision.

### Release pipeline jobs

```mermaid
stateDiagram-v2
  [*] --> cut: workflow_dispatch or schedule
  cut --> create_release: should_release
  create_release --> e2e: tag scoped
  create_release --> build: mac win linux matrix
  e2e --> build: parallel visibility
  build --> publish_release: assets verified draft
  publish_release --> homebrew_bump: stable tag only
  homebrew_bump --> [*]
  publish_release --> [*]: RC skips homebrew
```

| Job | Role |
| --- | --- |
| `cut` | Resolve ref, compute version, bump `package.json`, commit, tag, push |
| `create-release` | Draft GitHub release with generated notes; `--prerelease` for `-rc.` tags |
| `e2e` | Reuses `.github/workflows/e2e.yml` on the tag (informational; publish does not wait on it) |
| `build` | Matrix: macOS, Windows, Linux—`pnpm build:release`, electron-builder `--publish always`, draft stays draft until final publish |
| `publish-release` | `verify-release-required-assets.mjs`, then `gh release edit --draft=false` with prerelease derived from tag |
| `homebrew-bump` | Stable tags only; calls `homebrew-bump.yml` |

Release builds set `ORCA_BUILD_IDENTITY` (`stable` vs `rc` from tag regex) and `ORCA_POSTHOG_WRITE_KEY` for official artifacts; macOS signing secrets are scoped to the mac job only.

### Common maintainer scenarios

| Scenario | Inputs |
| --- | --- |
| Normal stable release | `kind=patch`, `ref=main` |
| Ship good commit before bad tip on `main` | `kind=patch`, `ref=<good-sha>` (tag only; fix `main` separately) |
| Feature-branch RC | `kind=rc`, `ref=<branch-or-sha>` |
| Minor / major bump | `kind=minor` or `major`, `ref=main` |
| Validate scheduled RC slot | `dry_run=true`, `kind=rc` |

<Warning>
Contributors should not edit `package.json` `version` for release purposes. Maintainers use **Cut Release** only.
</Warning>

## Related pages

<CardGroup>
<Card title="Develop and build" href="/develop-and-build">
Local `pnpm dev`, typecheck targets, native rebuilds, and release build commands.
</Card>
<Card title="Testing" href="/testing">
Vitest, Playwright Electron E2E, and SSH-localhost test flags.
</Card>
<Card title="SSH remote worktrees" href="/ssh-remote-worktrees">
Remote execution constraints contributors must design for.
</Card>
<Card title="Source control integrations" href="/source-control-integrations">
Multi-provider review flows (GitHub, GitLab, and others).
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
CI/native dependency failures and runtime reachability issues.
</Card>
</CardGroup>
