Skip to content

Contributing

This guide covers what you need to get started contributing to Kangentic. For detailed architecture documentation, see the Architecture page or the repo docs.

PlatformRequired
WindowsVisual Studio Build Tools (for better-sqlite3 native compilation)
macOSXcode Command Line Tools
Linuxbuild-essential, python3
Terminal window
git clone https://github.com/kangentic/kangentic.git
cd kangentic
npm install
npm start

The dev server starts three parallel processes: Vite (renderer HMR), esbuild (main/preload watch), and Electron.

A dev build names itself Kangentic (dev) in the title-bar wordmark and in the OS window title, so a dogfooding npm start window is tellable from an installed build in the taskbar without clicking into it. Production builds drop both strings.

src/
main/ # Electron main process (Node.js)
activity-engine/ # Activity-state engine behind the board's status dots
agent/ # Agent adapters (per-agent subfolders) with detection, command building, hooks, trust
analytics/ # Opt-out usage analytics
boards/ # External board adapters (Asana auth, import sources)
browser/ # Embedded Browser pane host + automation gating
config/ # Three-tier config: global > project > effective
db/ # SQLite database layer + migrations
dev-ports/ # Dev-server port ledger + bind probe
diagnostics/ # Log mirroring, crash capture, IPC recording
fs/ # Filesystem helpers
git/ # Worktree creation and cleanup
ipc/ # IPC handler registration + handlers/
mobile-bridge/ # Mobile companion pairing + relay
monitor/ # Cross-project Agent Monitor aggregation
notifications/ # Desktop alerts and the announcements feed
pop-out/ # Detachable-surface window engine
pr/ # Branch-to-PR resolution + refresh scheduling
pty/ # Terminal session management + queue
retrieval/ # Conversation Memory index + search
search/ # Quick Find query backend
shared/ # Helpers shared across main-process subsystems
task-detail/ # Cross-window task-detail ownership registry
transcription/ # Local voice dictation runtime
transition-engine/ # Transition engine, session recovery
usage-stats/ # Usage dashboard aggregation
preload/ # Context bridge (window.electronAPI)
renderer/ # React UI
components/ # Board, dialogs, layout, terminal
hooks/ # React hooks (useTerminal, etc.)
stores/ # Zustand state management
window-manager/ # In-app window layer: floating/tiled/snapped panes over the board and monitor
shared/ # Shared types, IPC channels, path utilities
packages/ # npm workspaces
launcher/ # The `kangentic` npm package behind `npx kangentic`
protocol/ # @kangentic/protocol - a shared wire-schema package, published to npm on its own version line
tests/
unit/ # Vitest - pure logic, no browser
integration/ # Vitest - opt-in, hits real CLIs/network (excluded from test:unit)
ui/ # Playwright + Chromium - mock electronAPI
e2e/ # Playwright + real Electron
captures/ # Playwright - on-demand screenshots/recordings, not a test tier
fixtures/ # Shared fixtures: mock agent CLIs, real session transcripts
ModeCommandWhat Runs
Developmentnpm start or npm run devVite dev server + esbuild watch + Electron
Productionnpm run buildtsc --noEmit > Vite build > esbuild (minified)
Packagenpm run packageBuild + unpacked app directory (electron-builder --dir, no installer)
Makenpm run makeBuild + create platform installers
Publishnpm run publishBuild + upload to GitHub Releases

In development, native modules (better-sqlite3, node-pty, sherpa-onnx-node, sqlite-vec, @huggingface/transformers, and font-list) are marked external in esbuild and loaded at runtime from node_modules (as is electron itself).

Kangentic uses electron-builder for creating platform installers, configured via electron-builder.yml in the project root.

PlatformFormatNotes
WindowsNSIS installer (.exe)Signed via Azure Trusted Signing
macOSDMG (.dmg) and ZIP (.zip)Hardened runtime + notarization
Linux.deb, .rpmAuto-update via electron-updater, deferred to an explicit restart

better-sqlite3 is rebuilt for the target Electron version manually, via scripts/rebuild-native.js (electron-builder’s own rebuild is turned off with npmRebuild: false), while node-pty ships NAPI prebuilts and needs no rebuild. The bridge script is selectively unpacked from the ASAR archive to allow process spawning.

Production builds enable Electron security fuses:

  • RunAsNode - disabled (prevents ELECTRON_RUN_AS_NODE)
  • NodeOptions - disabled (prevents NODE_OPTIONS injection)
  • Inspection - disabled (prevents --inspect debugging)
  • Cookie encryption - enabled
  • ASAR integrity - enabled
  • Only load app from ASAR - enabled

First-time contributors must sign a Contributor License Agreement (CLA) before their pull request can be merged. When you open your first PR, the CLA Assistant bot will post a comment - you sign by adding a comment to the PR. It takes about 30 seconds and only needs to be done once.

Kangentic is dual-licensed: the public version uses AGPLv3, and commercial licenses are available for organizations that need proprietary modifications. The CLA (modeled after the Apache ICLA) grants VORPAHL LLC a non-exclusive license to distribute your contribution under any license, while you retain full copyright to your work.

To inquire about a commercial license, email licensing@kangentic.com.

  • Text formatting - no em-dashes (U+2014) and no -- used as punctuation in anything you author (code, comments, tests, docs, commit messages). Use a single dash or restructure with a period. Enforced by a CI unit test plus review
  • TypeScript strict mode - noImplicitAny enabled, no any types (use the types in src/shared/types.ts, unknown with a type guard, or generics), and full descriptive names: currentIndex not curIdx
  • UI conventions - use the shared primitives (Select rather than a raw <select>, CountBadge, ConfirmDialog) and Lucide React icons, never inline SVGs. Respect the font floor: text-xs by default and never below text-[11px]. Avoid hover-only controls, use theme-adaptive semantic tokens rather than hardcoded colors so the UI re-colors across every theme, prefer visual subtraction over addition, and add data-testid attributes on interactive elements for test selectors
  • No personal info - the repo is public, so never hardcode usernames, emails, or home-directory paths. Use generic placeholders like C:\Users\dev in tests and examples
  • Reuse before reimplement - search for an existing utility before adding a new one, and extract duplicated logic into a shared module instead of copying it
  • Bounded IPC payloads - cap large captured buffers, such as child-process stdout and stderr, before they cross IPC. An Error must never carry tens of megabytes
  • IPC channels - src/shared/ipc-channels.ts is the single source of truth
  • Cross-platform parity - code and tests must behave identically on Windows, macOS, and Linux. No hardcoded OS paths, pass { force: true } to fs.rmSync/fs.rm for Windows file locking, write test files only under os.tmpdir(), and avoid pixel-exact or bare-timeout assertions. Enforced by a CI unit test and the Linux CI run
  • Docs stay in sync - changing an anchor source file (union types, IPC channels, DB migrations, adapter capabilities, or settings) means updating the matching doc under docs/. Enforced by an automated doc-anchor check when the PR is opened and merged
  • Commit messages - Conventional Commits format (type(scope): subject), enforced by commitlint. Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert

These are the conventions that most often need a maintainer follow-up when missed; the full set lives in the repo’s .claude/rules/ directory.

  1. Fork the repo and create a branch from main. Use a descriptive branch name like fix/session-resume-crash, feature/multi-agent-support, or docs/update-architecture.

  2. Make your changes and add or update tests for them.

  3. Run the quick local pass before opening the PR:

    Terminal window
    npm run lint
    npm run typecheck
    npm run test:unit
    npx playwright test --project=ui
  4. Sign the CLA when the bot prompts you on your first PR (see Contributor License Agreement above).

  5. Open the PR. The template prompts you for What / Why / How / Tests and a short checklist. Link any related issues.

Small, focused PRs are easier to review and merge faster. For the full three-tier testing strategy, see Testing.

Your PR must be green on every CI check before it can merge:

CheckTool
LintESLint, runs with --max-warnings 0, so any warning fails it
Type checktsc
Unit testsVitest
BuildProduction bundle
UI testsPlaywright
E2E testsElectron

If a check fails, push a fix and CI re-runs automatically. Contributors cannot re-run checks directly (that requires write access), so to re-trigger a run for a failure unrelated to your change - a flaky test, say - push a new commit (an empty git commit --allow-empty is fine), close and reopen the PR, or ask a maintainer to re-run it.

  • A maintainer may push follow-up commits to your branch for design polish or hardening before merging. This is normal and keeps the bar consistent, not a reflection on your work.
  • UI changes get a maintainer design review against the UI conventions. Including a screenshot or short clip in the PR makes that review much faster.
  • A maintainer merges your PR once it is approved and green. You do not need write access to the repository; repeat contributors may be granted it over time, at which point you merge your own PRs once approved.

Kangentic drives thirteen coding-agent CLIs, and the maintainers do not hold a subscription to all of them. Anything that needs a live, authenticated CLI is measured where that is possible and recorded honestly where it is not, so the gaps are written down rather than papered over. If you use one of these agents every day, you are better placed to close them than we are.

The clearest example is auto-command delivery. Kangentic confirms that an injected command actually became a user turn, and an agent only earns the last-resort recovery of restarting the session once two separate things have been proven for it. The per-adapter status, what each agent is still missing, and a step-by-step recipe live in docs/command-injection.md. Partial results are welcome: measuring one agent and reporting the numbers is a useful pull request on its own, as is committing a sanitized capture, and neither requires touching an adapter.

Bug reports in this area are most useful with the agent name, the task’s auto_command_state, and whether the session was local or remote.

Look for issues labeled good first issue for approachable tasks. If you want to take on something larger, open an issue first to discuss the approach. Questions are welcome in GitHub Discussions.

Kangentic is free and open source. A star helps other people find it.

Star on GitHub