# Contributing to OpenLife CLI

Thanks for your interest in improving OpenLife. This document covers the
dev setup, test discipline, commit conventions, and PR process used in
this project.

## Quick start (dev setup)

```bash
git clone https://github.com/GOOODZ/openlife-core.git
cd openlife-core
npm install         # postinstall runs scripts/postinstall-check.sh
npm run build       # tsc → dist/
node bin/openlife.js --help    # verify the CLI loads
```

For interactive development without rebuilding each time:

```bash
npm run dev         # ts-node src/index.ts
```

## Test discipline

OpenLife does **not** use Jest. Each test is a standalone executable in
`src/test_*.ts` that the `test:*` script in `package.json` compiles and
runs directly. Tests `throw` or `process.exit(1)` on failure; success
prints a summary line ending with `TEST_<NAME>_OK`.

Run the full canonical suite before committing:

```bash
npm run test:all
```

Run an individual test:

```bash
npm run test:workflow-parser
# or ad-hoc without script:
npm run build && node dist/test_<name>.js
```

`prepublishOnly` runs `test:all` automatically — publish will block on
the suite. Add new tests by:

1. Create `src/test_<feature>.ts` following the existing pattern (use a
   neighboring test file as template).
2. Add a matching `test:<feature>` script in `package.json`.
3. If the test is canonical, append it to the `test:all` chain.

## Commit conventions

- Use [Conventional Commits](https://www.conventionalcommits.org/):
  `feat:`, `fix:`, `docs:`, `chore:`, `refactor:`, `test:`, `ci:`,
  `style:`, `perf:`, `build:`.
- Reference the story or issue: `feat(workflow): add idempotent flag (Story 4.2, v1.2)`.
- Keep commits atomic — one logical change per commit. Pre-commit
  validation runs `npm run test:all` indirectly via prepublish gate.

## TypeScript conventions

- **Strict mode** is enforced (`tsconfig.json` has `"strict": true`).
  Production code must not use `any` — `unknown` + type narrowing is the
  idiomatic alternative. Test files may use `(x as any)` as a test seam.
- **Lazy imports** for heavy classes inside `src/index.ts` Commander
  handlers — never move `Gateway`, `Brain`, `TestHarness`,
  `OrchestrationLoop`, etc. to module scope. They are inside
  `.action(...)` via `require(...)` so that deterministic commands
  (`--help`, `plugin`, tests) stay fast.
- **Error contract for CLI handlers**: return JSON via
  `JSON.stringify(...)` with `{ ok: false, error: '<snake_case_code>',
  ... }`. Use `process.exitCode = 1` (not `process.exit(1)`) for
  failures in handlers.
- **Provider pattern**: new asset sources follow `Composite{X}Provider`
  → `File{X}Provider` / `Cloud{X}Provider` in
  `src/orchestrator/providers/`.
- **No external dev-kit paths at runtime** — runtime must not import
  from `~/.hermes`, Obsidian vaults, or local-only dev-kit dirs.

## Pull request process

1. Fork the repository or create a feature branch (`feat/<short-name>`
   or `fix/<short-name>`).
2. Make atomic commits with conventional commit messages.
3. Ensure `npm run test:all` passes locally.
4. Run `npm run build` to confirm clean TypeScript compilation.
5. Open a PR against `main`. Include in the description:
   - **Summary** of the change (1-3 bullets).
   - **Tests added/changed** with file paths.
   - **Risk assessment** for any runtime-behavior change.
6. CI (`.github/workflows/test.yml`, `build.yml`, `lint.yml`) must pass.
7. A maintainer will review and merge. **Push to `main` and
   `gh pr merge` are restricted to the maintainer** to keep the release
   pipeline deterministic.

## Filing issues

Use the templates in `.github/ISSUE_TEMPLATE/`:

- **Bug report** — for unexpected behavior, crashes, or regressions.
- **Feature request** — for new capabilities or enhancements.
- **Question** — for usage questions that don't fit the above.

Include OS, Node version, OpenLife version (`openlife --version`),
reproduction steps, and expected vs actual behavior.

## Where to put new code

| Adding... | Lives in... |
|---|---|
| Commander command | `src/index.ts` (near related commands, reuse banner sections) |
| Orchestrator class | `src/orchestrator/<ClassName>.ts` |
| CLI installer/wizard | `src/cli/<ClassName>.ts` |
| Memory provider | `src/memory/<Name>Provider.ts` + register in `MemoryProviderRegistry.ts` |
| Asset provider | `src/orchestrator/providers/{File,Cloud,Composite}<X>Provider.ts` |
| Reversa contract/executor | `src/reversa/Reversa<Name>.ts` |
| Test | `src/test_<feature>.ts` + matching `test:<feature>` script |

## Code of Conduct

This project adheres to a Contributor Covenant. See
[CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). By participating, you agree
to abide by its terms.

## License

By contributing, you agree that your contributions will be licensed
under the [MIT License](./LICENSE).

## Questions

Open a question issue or check `docs/getting-started.md` (coming soon).
