Contributions are welcome. This guide is for people developing the AIC codebase (not only installing and using AIC as an end user).
The architecture is deliberate; small, focused changes are reviewed and merged faster than broad refactors.
- Development setup
- Branches and RFC
- Good contribution types
- Contribution expectations
- Issues and pull requests
- Pull request checklist
Node.js >= 22 and pnpm are required. Older Node majors are rejected by the engines field in package.json (and the engine-strict=true guardrail in .npmrc) because better-sqlite3 only ships prebuilt binaries for recent Node ABIs; the MCP server additionally runs a startup preflight that prints an actionable message when Node is too old or when a better-sqlite3 ABI mismatch is detected. See .nvmrc for the reference Node major used to develop and test AIC.
Clone the repository, then from the repo root:
pnpm installFollow documentation/installation.md.
AIC creates per-project files (
aic.config.json, hooks, trigger rules) on first use; you do not need to create them manually.
While working in this repository, some editor setups expect aic_compile before other tools run. This repository commits "devMode": true in aic.config.json for documentation and tooling that key off dev mode; the Cursor compile gate still enforces aic_compile unless skipCompileGate is also true in aic.config.json (emergency bypass). Other projects can set the same pair only when they intentionally need that bypass. See the installation doc for your editor.
To verify CLI diagnostic subcommands against your local build (instead of the published npm package), use pnpm aic from the repo root after building:
pnpm build
pnpm aic status
pnpm aic last
pnpm aic chat-summary --project $(pwd)
pnpm aic projectsThis routes through node mcp/dist/server.js directly, so you see the output of your local changes immediately without an npm release.
pnpm test
pnpm lintGitHub Actions (.github/workflows/ci.yml) on pull requests and pushes to main runs pnpm install --frozen-lockfile, a lockfile vulnerability scan with google/osv-scanner-action/osv-scanner-action@v2.3.5 on pnpm-lock.yaml, then pnpm lint, pnpm build, pnpm typecheck, and pnpm test.
At minimum, read architecture.md and implementation-spec.md so your changes match the project's design and rules. For day-to-day usage patterns, see best-practices.md. All SQL and schema migrations belong in shared/src/storage/ only (see project-plan.md storage and migration ADRs and the schema sections in implementation-spec.md).
For optional Agent Skill workflows in this repo, see .claude/skills/ (each subfolder is one skill; SKILL.md is the contract). Packages include task planning (aic-task-planner), isolated task execution (aic-task-executor), evidence-backed documentation (aic-documentation-writer), cited research notes (aic-researcher), changelog hygiene (aic-update-changelog), progress file updates (aic-update-progress), surface-area audits that register Phase BUGS (aic-code-audit), structured PR review from a diff (aic-pr-review), systematic single-bug investigation (aic-systematic-debugging), roadmap proposals for the progress file (aic-roadmap-forge), git history rewrite plans (aic-git-history-clean), and full release orchestration (aic-release).
Husky already runs checks on commit and push: lint-staged on commit (ESLint with fix on staged TypeScript under shared/, cli/, and mcp/; Prettier on staged files matched by the project config). Staged *.ts files at the repository root get Prettier only, not ESLint. commitlint runs on the commit message; typecheck, tests, and lint:clones run on push. You can still run the commands below locally before committing or when debugging CI.
| Command | Purpose |
|---|---|
pnpm typecheck |
Full TypeScript project build |
pnpm test:watch |
Tests in watch mode |
pnpm lint:fix |
ESLint with auto-fix |
pnpm format |
Prettier write |
pnpm format:check |
Prettier check only |
pnpm knip |
Unused files, exports, and dependencies |
pnpm check:headers |
SPDX license headers |
pnpm lint:clones |
Duplicate-code scan (jscpd; also runs on pre-push) |
pnpm aic <subcommand> |
CLI diagnostics against the local build (status, last, chat-summary, quality, projects; see Local MCP testing for --project) |
pnpm aicrequires a priorpnpm build. Usepnpm run dev:mcpfor a live-reloading MCP server during development (no build step needed).
To run the MCP server from your clone instead of the published package:
-
From the repo root (no build step required):
pnpm run dev:mcp
-
Temporarily replace the
aicserver entry in your editor's MCP config with:"aic": { "command": "pnpm", "args": ["run", "dev:mcp"], "cwd": "/absolute/path/to/your/AIC/clone" }
Use the real absolute path to your clone for
cwd. If your editor does not supportcwd, start the editor from the AIC repo root. -
Restart your editor or reload MCP so it picks up the local server. Restore the published entry when done:
"command": "npx", "args": ["-y", "@jatbas/aic@latest"].
Cursor in this repository: The checked-in .cursor/mcp.json registers the dev server under the config key aic-dev. When agents or automation refer to calling AIC MCP tools by server name, Cursor may expose this workspace as project-0-AIC-aic-dev — use that identifier for aic_compile, aic_status, aic_quality_report, and related tools here. The full reminder lives in .cursor/rules/aic-architect.mdc.
- From the repo root, run
pnpm build, then runpnpm aic status,pnpm aic projects,pnpm aic last,pnpm aic quality, andpnpm aic chat-summary --project <absolute workspace root>to exercise the compiled diagnostic CLI. When your shell cwd is not registered in the global AIC database—including a git worktree root that has noprojectsrow—pass--project <absolute path to a registered clone>tostatus,last, andchat-summary.
pnpm run dev:mcp runs the server via tsx (on-the-fly TypeScript), so no build step is needed during development. The server process must be restarted to pick up changes:
| What you changed | What to do |
|---|---|
Integration hooks (integrations/*/hooks/*.cjs) |
Restart the AIC dev server. On startup the server re-runs the installers, which copy the updated hooks to their target locations. |
Integration installers (integrations/*/install.cjs) |
Restart the AIC dev server. |
MCP server code (mcp/src/**) |
Restart the AIC dev server. |
Core / pipeline / adapters / storage (shared/src/**) |
Restart the AIC dev server. tsx picks up changes at next start — no separate build needed. |
Restart the dev MCP process so the server is respawned: reload MCP in the editor, or restart the editor when reload does not pick up the change. A full
pnpm buildis only needed before publishing or running the compiled MCP server (mcp/dist/server.js).
Use a descriptive branch before substantial work.
Pattern: (kind) firstnamelastname/short-slug
- firstnamelastname: first and last name run together, lowercase, no spaces (
Jorge Santosmaps tojorgesantos). - short-slug: lowercase, hyphenated.
Example: (feature) jorgesantos/new-feature-that-will-do-whatever
Kinds: (feature), (fix), and (chore); also (docs), (refactor), or (test) when the PR is limited to that kind of change.
Use an RFC when the change affects architecture, pipeline behavior, rule enforcement, guardrails or security boundaries, editor integration strategy, or public configuration or user-facing workflow.
Add RFC.md at the repository root on the same branch as your implementation. Commit it with or before your code so the PR shows design and changes together.
The RFC should explain:
- the problem
- the proposed change
- why the current design is insufficient
- expected impact on determinism, security, and token efficiency
- migration or compatibility concerns, if any
- bug fixes
- editor integration improvements
- language provider improvements
- content transformer improvements
- test coverage
- benchmark and validation work
- documentation clarifications
- Keep changes narrowly scoped.
- Follow the existing architecture and naming patterns.
- Preserve deterministic behavior.
- Do not weaken local-first guarantees, guardrails, or logging boundaries without prior discussion.
- Include tests for behavior changes.
- Update documentation when changing commands, config, workflow, or other user-visible behavior.
Use the bug report or feature request templates when opening an issue. Security vulnerabilities go through GitHub Security Advisories — do not open a public issue.
Pull requests use a template that mirrors the checklist below.
Before opening a PR, ensure:
- Branch name follows the convention when the change is non-trivial
-
RFC.mdis on the branch when an RFC is required (see above) -
pnpm lintpasses -
pnpm testpasses -
pnpm knippasses if relevant to the change - New behavior is covered by tests
- Docs are updated where needed
- The change does not introduce editor-specific assumptions into the core pipeline
- The PR description explains motivation and scope clearly
For deeper contribution rules and project context, see the project documentation.