Thank you for your interest in contributing! Here's everything you need to get started.
- Development Setup
- Branching Strategy
- Commit Convention
- Pull Request Process
- Code Style
- Testing
- Adding a Publisher
- Adding a Generation Format
Prerequisites: Node.js 20+, pnpm 9+
git clone https://github.com/sairam0424/Inkforge.git
cd Inkforge
pnpm install
cp .env.example .env # fill in BEDROCK_ or ANTHROPIC_API_KEY at minimum
pnpm build
pnpm test # all vitest suites in packages/core must passmain ← production releases only (protected)
develop ← integration branch — all features merge here
feature/* ← one branch per feature or fix
Always branch from develop:
git checkout develop
git pull origin develop
git checkout -b feature/my-featureNever branch directly from main.
Follow Conventional Commits:
<type>(<scope>): <short description>
Types: feat | fix | refactor | docs | test | chore | perf | ci
Scopes: core | cli | web | pipeline | llm | rag | publishers | schema | content
Examples:
feat(pipeline): add interactive clarification mode before outline
fix(llm): handle 403 explicit-deny as fallback-eligible error
docs(readme): add carousel PDF publishing workflow
test(ingest): add code-first mode with exported function anchors
chore(deps): bump vitest to 4.2
- Branch from
develop— never frommain - Keep PRs focused — one logical change per PR
- Run
pnpm build && pnpm testbefore opening - Fill out the PR template completely
- PRs require 1 approval before merge
- Use
--no-ffmerge (preserve merge commit history) - Branches are auto-deleted after merge
- TypeScript strict mode — no implicit
anywithout justification - Immutability — create new objects, never mutate in-place
- No magic numbers — use named constants from
src/modes/index.ts - Files under 500 lines — split into focused modules when larger
- No comments explaining WHAT — only comment the WHY (hidden constraints, non-obvious invariants)
- No trailing summaries — don't add "this function adds X" docstrings
pnpm --filter @inkforge/core test # run tests
pnpm --filter @inkforge/core test:watch # watch modeRules:
- All new pipeline stages must have unit tests with mock LLM responses
- Tests live in
src/**/__tests__/mirroring the source structure - Use vitest — not jest
- Test the public interface, not implementation details
- Create
packages/core/src/publishers/<platform>.ts - Export
publishTo<Platform>(article, opts)returning{ id, url } - Auth via
process.env.PLATFORM_API_KEY— never hardcode - Add a subpath export to
packages/core/package.json:"./publishers/<platform>": { "import": "./dist/publishers/<platform>.js" }
- Register it in
PUBLISHER_REGISTRYinpackages/core/src/publishers/registry.ts(the CLI resolves publishers from the registry); browser-driven publishers should also write a tracking record viawritePublishedTrackingRecord - Document the env var in
.env.example - Add platform to
CLAUDE.mdpublishing rules section
- Add to
FormatSchemainpackages/core/src/schema/index.ts - Add structural instructions to
FORMAT_INSTRUCTIONSinpackages/core/src/modes/index.ts - Add to
--formatCLI option inpackages/cli/src/commands/generate.ts - Add to
DialSelectorformat options inapps/web/src/components/generator/GeneratorForm.tsx
- Bugs → Open an issue
- Questions / ideas → Start a discussion
- Security → See SECURITY.md