Skip to content

Contributing


Development Setup

bash
git clone https://github.com/your-org/forge-studio.git
cd forge-studio
npm install
uv sync          # Python venv for backend testing
npm run dev      # Electron dev mode with hot reload

Branch Strategy

  • main — always buildable and passing tests.
  • Feature branches off main; merge via PR.
  • Hotfix branches off main with a direct merge.

Before Committing

bash
npm run typecheck   # Must be zero errors
npm run test        # All tests must pass
npm run lint        # No lint errors

Commit Style

  • Imperative subject line: Add, Fix, Update, Remove, Refactor.
  • Keep the first line ≤ 72 characters.
  • Add a blank line and body for non-trivial changes explaining why.
  • Do not add Co-Authored-By: Claude or any AI attribution lines.

Good:

Fix TWIX parser: scan 2 MB instead of 512 KB

Real files have the main ASCCONV block at byte offset ~552 KB.
The previous 512 KB limit caused silent fallback to empty headers.

Code Standards

TypeScript

  • Strict mode is enabled — no any types.
  • All renderer↔main types go through src/shared/ipc-types.ts.
  • Never use require() — ESM only.

React

  • Functional components only.
  • Use useTheme() for all color access — never hardcode hex values.
  • Lazy-load tab components with React.lazy + Suspense.

IPC Security

  • The main process must validate all inputs from the renderer — treat it as untrusted.
  • Never expose Node.js APIs directly to the renderer.
  • All channels use the forge: prefix.

Design System

  • Use the 38-token design system from src/renderer/theme/tokens.ts.
  • Base components: Btn, Badge, Card — do not bypass these with raw <button>.
  • Do not hardcode colors, font sizes, spacing, or border radii.

Adding a New IPC Method

  1. Add the method signature to ForgeAPI in src/shared/ipc-types.ts.
  2. Implement the handler in src/main/ipc-handlers.ts.
  3. Expose it in src/preload/index.ts.
  4. Call it from the renderer via window.forgeAPI.yourMethod().

If it's a push event (main → renderer):

  1. Add onYourEvent(cb): UnsubscribeFn to ForgeAPI.
  2. Wire in src/renderer/store/ipc-middleware.ts.
  3. Dispatch into the appropriate Redux slice.

Adding a New Workflow Parameter Type

  1. Add the discriminant to WorkflowParam in src/shared/param-types.ts.
  2. Add the editor case to ParamEditor.tsx.
  3. Update the JSON Schema in resources/schema/workflow-v1.json.
  4. Add tests in test/unit/main/workflow-loader.test.ts.

Adding a New Backend

  1. Add the backend key to the backend field in workflow-types.ts.
  2. Add a runner function in backend-dispatcher.ts.
  3. Add the case to dispatchStage().
  4. Provide a forge_dispatcher.<ext> script in resources/<backend>/.
  5. Add the ForgeAPI settings fields for path and version.
  6. Wire detection in compute-backend.ts and ipc-handlers.ts.

Specs Directory

All architecture decisions are documented in specs/. Read specs/claude-code-handoff.md for the phased implementation roadmap before working on significant features.

When specs conflict, the authority hierarchy is:

forge-cli-spec.md            > architecture.md §4.2, §5.1
forge-ipc-api-spec.md        > architecture.md §2.3
forge-workflow-schema.md     > architecture.md §4.1
design-system-specification  > architecture.md §3.1

Project-Specific Rules

  • No hardcoded colors — use design tokens.
  • No any types — use unknown and narrow.
  • No direct filesystem access from renderer — all FS goes through IPC.
  • One active job at a time — enforced in job-manager.ts.
  • Stage chaining — each stage receives prior stage outputs, not the original raw file.

FORGE Studio