Community & Resources

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

GoalStart here
Prepare a local development checkoutDevelopment setup
Understand the workspace layoutRepository structure
Run verification before a pull requestRunning tests
Add a database connectorAdding a connector
Update docs for a user-visible CLI or setup changePR guidelines

Contribution areas

AreaGood first context
CLI and setuppackages/cli, especially setup steps, command definitions, status checks, and smoke tests
Context enginepackages/cli/src/context, including project config, ingest orchestration, and semantic search
Connectorspackages/cli/src/connectors/<driver>, plus connector-specific tests and integration docs
Python semantic layerpython/ktx-sl for planning and SQL compilation
ktx daemonpython/ktx-daemon for the portable runtime API
Documentationdocs-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 build

This builds the TypeScript package. You can also build the package directly:

pnpm --filter @kaelio/ktx run build
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/.

output
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:

output
packages/cli/src/connectors/<driver>/
  index.ts          # Internal connector exports
  connector.ts      # KtxScanConnector implementation
  dialect.ts        # SQL dialect handling

Add 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 - the KtxConnectionDriver value for your database
  • capabilities - a KtxConnectorCapabilities object declaring what your connector supports: tableSampling, columnSampling, columnStats, readOnlySql, nestedAnalysis, eventStreamDiscovery, formalForeignKeys, estimatedRowCounts
  • introspect() - discovers tables, columns, types, and constraints, returning a KtxSchemaSnapshot

Optional methods for richer scanning:

  • sampleColumn() - sample values from a specific column
  • sampleTable() - sample rows from a table
  • columnStats() - compute column statistics
  • executeReadOnly() - 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, no as unknown as. Use zod schemas for runtime validation at CLI and config boundaries. Follow the camelCaseSchema / PascalCaseType naming convention for Zod schemas and inferred types.
  • Python: type hints on all new code, pathlib over os.path, explicit exception types over broad except Exception, logger.exception() for caught exceptions. Use sqlglot for SQL parsing - never regex.
  • Dependencies: pnpm for Node packages, uv for Python.
  • Dead code: remove it. Don't leave commented-out code, unused wrappers, or empty directories.

PR guidelines

Before submitting a pull request:

  1. Run the relevant checks - at minimum, pnpm run type-check and pnpm run test for TypeScript changes, uv run pytest -q and uv run pre-commit run --files [FILES] for Python changes.
  2. Build if you changed exports - run pnpm run build to verify package exports and dist/ expectations still align.
  3. Keep changes focused - one logical change per PR. Don't bundle unrelated refactors.
  4. Follow existing patterns - match the style and conventions of surrounding code. The codebase favors explicit over clever.
  5. Update docs for user-visible changes - update docs-site/content/docs/ when setup, CLI, configuration, or integration behavior changes.
  6. 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 taskCommand or section
Prepare the workspacepnpm install, pnpm run setup:dev, uv sync --all-groups
Verify TypeScript changespnpm run type-check, pnpm run test, or package-filtered equivalents
Verify Python changesuv run pytest -q and uv run pre-commit run --files <files>
Add a connectorAdding a connector
Check style expectationsCode 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.