Contributing
Contribute to ktx through code, docs, connectors, and examples.
ktx is an open-source context layer for data agents. The project welcomes focused contributions that improve setup, integrations, CLI behavior, documentation, connector coverage, and examples.
Where to start
| Goal | Start here |
|---|---|
| Prepare a local development checkout | Development setup |
| Understand the workspace layout | Repository structure |
| Run verification before a pull request | Running tests |
| Add a database connector | Adding a connector |
| Update docs for a user-visible CLI or setup change | PR guidelines |
Contribution areas
| Area | Good first context |
|---|---|
| CLI and setup | packages/cli, especially setup steps, command definitions, status checks, and smoke tests |
| Context engine | packages/cli/src/context, including project config, ingest orchestration, and semantic search |
| Connectors | packages/cli/src/connectors/<driver>, plus connector-specific tests and integration docs |
| Python semantic layer | python/ktx-sl for planning and SQL compilation |
| ktx daemon | python/ktx-daemon for the portable runtime API |
| Documentation | docs-site/content/docs for public docs and docs-site/tests for docs behavior |
Development setup
This page is for contributors working on the ktx repository. To install ktx for
an analytics project, use the published
@kaelio/ktx package in the
Quickstart.
Prerequisites
- Node.js 22+ and pnpm - for the TypeScript workspace
- Python 3.11+ and uv - for the Python semantic layer and daemon
- Git - for version control
Clone and install
git clone https://github.com/kaelio/ktx.git cd ktx pnpm install uv sync --all-groups
pnpm install sets up the TypeScript workspace.
uv sync --all-groups installs Python dependencies for the semantic layer and
daemon, including dev and test groups.
Build
pnpm run buildThis builds the TypeScript package. You can also build the package directly:
pnpm --filter @kaelio/ktx run build
Link the CLI for local testing
pnpm run setup:dev pnpm run link:dev
This makes the ktx-dev command available globally, pointing at your local
build. Use this development binary when you need to test unpublished repository
changes.
Repository structure
ktx is a pnpm + uv workspace. TypeScript source lives in packages/cli,
and Python projects live in python/.
packages/
cli/ # CLI package and published npm package source
src/context/ # Core context engine (scan, ingest, MCP, semantic layer)
src/llm/ # LLM client abstraction
src/connectors/ # Database connectors
python/
ktx-sl/ # Semantic layer - grain-aware query planning and SQL compilation
ktx-daemon/ # Daemon - portable API server around the semantic layer
examples/ # Example projects and fixtures
scripts/ # Workspace scripts (benchmarks, verification, release)
docs-site/ # Documentation site (Fumadocs)The TypeScript package is ESM ("type": "module") and uses NodeNext module
resolution. The Python projects use pyproject.toml for dependency management.
Running tests
TypeScript
# Run all tests pnpm run test # Run tests for the TypeScript package pnpm --filter @kaelio/ktx run test # Type-check all packages pnpm run type-check # Type-check the TypeScript package pnpm --filter @kaelio/ktx run type-check # CLI smoke test pnpm --filter @kaelio/ktx run smoke
Python
# Run all Python tests uv run pytest -q # Semantic layer tests uv run pytest python/ktx-sl/tests -q # Daemon tests uv run pytest python/ktx-daemon/tests -q
Pre-commit checks
After modifying Python files, run pre-commit on the changed files:
uv run pre-commit run --files python/ktx-sl/src/changed_file.py
Full verification
For cross-cutting changes that affect package exports or shared contracts:
pnpm run build pnpm run type-check pnpm run test uv run pytest -q
Adding a connector
Database connectors live in packages/cli/src/connectors/<driver>/. Each
connector implements the KtxScanConnector interface from the internal context
modules.
Step 1: Scaffold the connector
Create a new directory at packages/cli/src/connectors/<driver>/ with:
packages/cli/src/connectors/<driver>/
index.ts # Internal connector exports
connector.ts # KtxScanConnector implementation
dialect.ts # SQL dialect handlingAdd any connector-specific npm dependency to packages/cli/package.json.
Step 2: Implement the connector
Your connector class must implement KtxScanConnector, which requires:
id- a string identifier, typically"<driver>:<connectionId>"driver- theKtxConnectionDrivervalue for your databasecapabilities- aKtxConnectorCapabilitiesobject declaring what your connector supports:tableSampling,columnSampling,columnStats,readOnlySql,nestedAnalysis,eventStreamDiscovery,formalForeignKeys,estimatedRowCountsintrospect()- discovers tables, columns, types, and constraints, returning aKtxSchemaSnapshot
Optional methods for richer scanning:
sampleColumn()- sample values from a specific columnsampleTable()- sample rows from a tablecolumnStats()- compute column statisticsexecuteReadOnly()- execute arbitrary read-only SQL
Step 3: Add a dialect
The dialect class handles database-specific concerns: identifier quoting, type mapping from native types to normalized types, and query generation for sampling and statistics.
Step 4: Wire it up
Register the new connector in packages/cli/src/local-scan-connectors.ts and
packages/cli/src/local-adapters.ts so the CLI and scan engine can instantiate
it. Keep runtime loading dynamic when the connector is optional.
Step 5: Test
pnpm --filter @kaelio/ktx run build pnpm --filter @kaelio/ktx run type-check pnpm --filter @kaelio/ktx run test
Use packages/cli/src/connectors/sqlite/ as a minimal reference and
packages/cli/src/connectors/postgres/ as a full-featured one.
Code conventions
- TypeScript: strict types, no
any, noas unknown as. Usezodschemas for runtime validation at CLI and config boundaries. Follow thecamelCaseSchema/PascalCaseTypenaming convention for Zod schemas and inferred types. - Python: type hints on all new code,
pathliboveros.path, explicit exception types over broadexcept Exception,logger.exception()for caught exceptions. Usesqlglotfor SQL parsing - never regex. - Dependencies:
pnpmfor Node packages,uvfor Python. - Dead code: remove it. Don't leave commented-out code, unused wrappers, or empty directories.
PR guidelines
Before submitting a pull request:
- Run the relevant checks - at minimum,
pnpm run type-checkandpnpm run testfor TypeScript changes,uv run pytest -qanduv run pre-commit run --files [FILES]for Python changes. - Build if you changed exports - run
pnpm run buildto verify package exports anddist/expectations still align. - Keep changes focused - one logical change per PR. Don't bundle unrelated refactors.
- Follow existing patterns - match the style and conventions of surrounding code. The codebase favors explicit over clever.
- Update docs for user-visible changes - update
docs-site/content/docs/when setup, CLI, configuration, or integration behavior changes. - Don't commit artifacts -
node_modules/,.venv/,dist/, coverage output, and local databases should not be committed.
For larger features or architectural changes, open an issue first to discuss the approach.
Agent usage notes
Use this page when an agent is modifying the ktx repository itself rather than using ktx in an analytics project.
| Agent task | Command or section |
|---|---|
| Prepare the workspace | pnpm install, pnpm run setup:dev, uv sync --all-groups |
| Verify TypeScript changes | pnpm run type-check, pnpm run test, or package-filtered equivalents |
| Verify Python changes | uv run pytest -q and uv run pre-commit run --files <files> |
| Add a connector | Adding a connector |
| Check style expectations | Code conventions |
Common recovery path: if a check fails because generated files or local runtimes are missing, run the setup commands first. If a check fails because of a real type, lint, or test error, fix the source file and rerun the smallest failing check before broadening verification.