Files
fusion/docs/contributing.md
Fusion c85ffa9198 feat(FN-2605): merge fusion/fn-2605 (auto-resolved)
- test(FN-2605): complete Step 4 — align tests with planning labels
- docs(FN-2605): complete Step 3 — update demo and script terminology
- docs(FN-2605): complete Step 2 — update docs terminology
- docs(FN-2605): complete Step 1 — update README terminology
2026-04-26 12:34:02 -07:00

183 lines
6.0 KiB
Markdown

# Contributing
[← Docs index](./README.md)
Thanks for contributing to Fusion.
## Development Setup
### Prerequisites
- Node.js (current LTS recommended)
- pnpm (`packageManager` is pnpm)
- Git
- `pi` runtime/auth configured for AI features
### Install dependencies
```bash
pnpm install --frozen-lockfile
```
### Build all packages
```bash
pnpm build
```
## Workspace Package Overview
| Package | Purpose |
|---|---|
| `@fusion/core` | Shared domain types, stores, persistence, and core utilities |
| `@fusion/dashboard` | Express API + React UI (including dashboard TUI in CLI) |
| `@fusion/engine` | Scheduling, planning, execution, merge orchestration |
| `@fusion/desktop` | Electron shell around Fusion dashboard/client |
| `@fusion/mobile` | Capacitor + PWA mobile packaging |
| `@fusion/plugin-sdk` | Plugin SDK for building Fusion extensions |
| `@runfusion/fusion` | Published CLI + pi extension (includes merged TUI) |
## Development Workflow
```bash
pnpm dev # build + run CLI entrypoint in dev mode
pnpm dev:ui # dashboard dev server only
pnpm lint # lint all packages
pnpm test # workspace test suite (clean-worktree compatible)
pnpm build # workspace builds
pnpm verify:workspace # canonical lint -> test -> build verification gate
pnpm typecheck # workspace typechecks
```
## Deterministic workspace verification bootstrap
Fusion codifies workspace verification as a deterministic contract:
- Use `pnpm install --frozen-lockfile` for clean bootstrap and dependency repair paths.
- `pnpm test` must be runnable in a clean worktree without requiring a prior `pnpm build`.
- This includes clean states where `packages/core/dist`, `packages/engine/dist`, and `packages/dashboard/dist` are absent.
- `pnpm verify:workspace` is the canonical pre-merge gate and runs in strict order:
1. `pnpm lint`
2. `pnpm test`
3. `pnpm build`
CI uses `pnpm verify:workspace` directly, so changes that reintroduce hidden test pre-build dependencies fail fast.
## Quality Gate Checklist
Before submitting changes, verify:
- [ ] `pnpm verify:workspace` — canonical lint → test → build gate
- [ ] `pnpm typecheck` — type checking passes
## Testing Requirements
Use real test runs (not manual verification substitutes):
```bash
pnpm test
pnpm test:coverage
pnpm test:coverage:core
pnpm test:coverage:engine
pnpm test:coverage:cli
pnpm test:coverage:dashboard
```
### Test File Organization
All test files live in `__tests__/` subdirectories alongside the code they test:
- Test for `src/foo.ts``src/__tests__/foo.test.ts`
- Test for `app/components/Bar.tsx``app/components/__tests__/Bar.test.tsx`
When adding new tests, follow this convention. The monorepo has been standardized on `__tests__/` organization.
## Build Standalone Executables
Fusion supports standalone binary builds through Bun compile scripts in the CLI package.
```bash
pnpm build:exe # build host-target executable
pnpm build:exe:all # build multi-target executables
```
## Release Process
Fusion uses Changesets + version PR workflow.
- See [RELEASING.md](../RELEASING.md) for release flow details.
- For published package behavior changes, include a changeset.
## Code Signing
Release binary signing setup is documented here:
- [Code Signing Setup](./CODE_SIGNING.md)
## Git / Commit Conventions
Use task-ID-scoped conventional commits:
- `feat(FN-XXX): ...`
- `fix(FN-XXX): ...`
- `test(FN-XXX): ...`
- `docs(FN-XXX): ...` (for documentation-only changes)
## Project Memory
When enabled, Fusion uses OpenClaw-style memory files:
- `.fusion/memory/MEMORY.md` — long-term project memory
- `.fusion/memory/YYYY-MM-DD.md` — daily running notes
- `.fusion/memory/DREAMS.md` — dream-processing memory file
- The legacy top-level memory file is a deprecated migration fallback (seed/alias behavior) and should not be treated as canonical
Use project memory for reusable patterns, constraints, and pitfalls that should persist across tasks.
### Background Memory Summarization
Fusion can automatically extract insights from memory and prune transient content. Enable via `insightExtractionEnabled` setting:
- `.fusion/memory/MEMORY.md` — Canonical long-term memory source (inside the layered `.fusion/memory/` workspace) compacted/pruned by extraction jobs
- `.fusion/memory-insights.md` — Distilled insights output
- `.fusion/memory-audit.md` — Audit report after each extraction (includes pruning outcome)
See [Settings Reference](./settings-reference.md#background-memory-summarization--audit) for configuration details.
## Dashboard CSS Organization
The dashboard's CSS has been modularized:
- **Global stylesheet** (`packages/dashboard/app/styles.css`, ~4,500 lines)
- Design tokens, primitives (`.btn`, `.card`, `.modal`, `.form-input`), global cross-component rules
- **Per-component stylesheets** (56+ files in `packages/dashboard/app/components/`)
- Each component needing CSS has a co-located `ComponentName.css`
- Each `ComponentName.tsx` must import: `import "./ComponentName.css";`
**Rule:** New component CSS goes in the component's `.css` file, not in `styles.css`. Only truly global rules belong in the root stylesheet.
### CSS Testing
For CSS regression tests, use the helper at `packages/dashboard/app/test/cssFixture.ts`:
```ts
import { loadAllAppCss, loadAllAppCssBaseOnly } from "../test/cssFixture";
// Load all CSS (styles.css + all component .css)
const allCss = await loadAllAppCss();
// Load base rules only (strips @media/@supports)
const baseOnly = await loadAllAppCssBaseOnly();
```
Never directly `readFileSync('../styles.css')` — the ESLint rule `no-restricted-syntax` in `eslint.config.mjs` blocks this in test files and directs you to `cssFixture.ts`.
## SQLite Test Runner Pitfall
When running engine tests with Vitest and `node:sqlite`, ensure the engine Vitest config uses thread pool mode:
-`pool: "threads"`
-`pool: "vmThreads"`
`node:sqlite` fails under Vitest VM contexts; using threads avoids that failure mode.