Skip to article
PlanToCodeDocsGet the app

HandbookContribute

Build, test & contribute

A practical path from a source checkout to a focused change, with the checks that prove each boundary still works.

Checked against the source on 17 September 2026

On this page

Start with a focused development surface

Use a source checkout with its lockfiles and read AGENTS.md for the current repository contract. The root package manager is pnpm 10.34.5, and the root package.json pins vulnerable transitive versions through pnpm overrides and patched dependencies, which is why --frozen-lockfile fails after a dependency change until the lockfile is regenerated. Install a compatible Node runtime, stable Rust for native work, and the target platform’s native compiler tools. iOS work requires macOS and Xcode. There is no root command that starts every component together; run only the surfaces needed by your change.

Install JavaScript dependencies from the repository root
pnpm install --frozen-lockfile
TaskStart command or projectWhat it proves
Websitepnpm dev:websiteDocumentation and marketing UI in a browser.
Desktop frontendpnpm -C desktop devReact layout and frontend behavior; native calls require a Tauri runtime.
Native desktoppnpm -C desktop tauri:devThe actual WebView, Rust commands, sidecar, and local files.
Serverpnpm dev:server after local setupConfigured HTTP and relay service behavior.
iOSmobile/ios/PlanToCode.xcodeproj, PlanToCode schemeNative companion UI and, with a configured desktop, remote control.
Androidmobile/android in Android StudioThe Compose companion and, with a configured desktop, remote control.

Build the native companions

  1. iPhone: open mobile/ios/PlanToCode.xcodeproj, select the PlanToCode scheme, resolve the local Core, VibeUI, and VibeUIFormatting packages, and configure the Auth0 values from mobile/ios/README.md. Run on an iOS 18 simulator or a device with your signing team.
  2. Android: open mobile/android in Android Studio, let Gradle sync, and configure the Auth0 and Firebase values from mobile/android/README.md. The app targets Android 8.0 and later.
  3. For a live control test on either platform, connect to a configured desktop with the same account and region and read a known file before you try a mutation.
Discover local destinations; use one of the returned destinations for builds/tests
xcodebuild -showdestinations \
  -project mobile/ios/PlanToCode.xcodeproj \
  -scheme PlanToCode

Simulators and emulators cover layout, decoding, and state transitions. They prove nothing about physical push delivery, store purchases, or a signed release’s provider login, so test those on real services and a real device before you call a release ready.

Follow one operation through the code

Example: trace outbox submission from contract to storage
rg -n "codexChatOutboxSubmit" rpc-contract.v1.json desktop/src-tauri/src/remote_api server/src mobile/ios
rg -n "submit_outbox_request" desktop/src-tauri/src/commands
rg -n "save_workspace_chat_outbox_with_operation_identity" desktop/src-tauri/src
  1. Describe the user action, expected result, and a failure case before editing.
  2. Find the transport DTO and the domain service that owns the operation. Read both; an adapter alone does not define behavior.
  3. Change the smallest owning layer. Preserve stable operation, session, and timeline identities.
  4. If you change a shared RPC, update the manifest, desktop, server, iOS, and Android consumers together. The manifest pins what they share: page sizes 12 and 100, timeouts of 15, 60, 115, 60, and 20 seconds, the initial-timeline retry policy, and the mutations that require an idempotency key.
  5. Add a focused regression test at the failure boundary. For visual or lifecycle behavior, also inspect the running surface.
  6. Update the relevant technical chapter and its source references with the code change.

Choose checks that match the change

Changed surfaceRepository commands
Desktop TypeScriptpnpm -C desktop typecheck; pnpm -C desktop lint; pnpm -C desktop test
Desktop Rustpnpm desktop:check, then focused Rust tests for the changed service.
Server Rustpnpm server:check, then focused cargo tests and configured service tests as needed.
Shared RPCpnpm check:rpc-contract, plus the affected client and server tests.
Codex storage boundarypnpm check:codex-storage-boundary
Websitepnpm -C website typecheck; pnpm -C website lint; pnpm -C website test; pnpm -C website build
Cross-boundary reviewpnpm check:quality-boundaries chains nine checks, including the Tauri command surface and an ast-grep duplicate scan of changed Rust, Kotlin, Swift, and Python with a minimum of 18 lines; pnpm check:all runs the broader suite.

A typecheck proves type consistency, not delivery correctness, and a relay unit test does not prove a native login. State which checks ran, which need external services, and what you inspected in the live product.

Make the change easy to review

Keep one canonical runtime path. Remove obsolete branches instead of adding silent compatibility behavior. Keep components modular, use the dependencies already present, and retain unrelated work in a dirty checkout. The repository caps files at 550 lines and functions at 100, with baseline files that record existing debt and may only shrink, and it targets five authored source or test files per folder with a hard cap of seven; split growing folders by feature or reader task.

A contribution should explain the trigger, the resulting behavior, the affected contract, and the validation evidence, with a screenshot for a visible change and a bounded trace for a delivery defect. Never include private session transcripts, auth files, or machine-specific paths.